123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- <?php
- /* vim: set expandtab sw=4 ts=4 sts=4: */
- /**
- * Generic plugin interface.
- *
- * @package PhpMyAdmin
- */
- namespace PhpMyAdmin;
- use PhpMyAdmin\Properties\Options\Groups\OptionsPropertySubgroup;
- use PhpMyAdmin\Properties\Options\OptionsPropertyItem;
- use PhpMyAdmin\Properties\Plugins\ExportPluginProperties;
- use PhpMyAdmin\Properties\Plugins\PluginPropertyItem;
- use PhpMyAdmin\Properties\Plugins\SchemaPluginProperties;
- /**
- * PhpMyAdmin\Plugins class
- *
- * @package PhpMyAdmin
- */
- class Plugins
- {
- /**
- * Includes and instantiates the specified plugin type for a certain format
- *
- * @param string $plugin_type the type of the plugin (import, export, etc)
- * @param string $plugin_format the format of the plugin (sql, xml, et )
- * @param string $plugins_dir directory with plugins
- * @param mixed $plugin_param parameter to plugin by which they can
- * decide whether they can work
- *
- * @return object|null new plugin instance
- */
- public static function getPlugin(
- $plugin_type,
- $plugin_format,
- $plugins_dir,
- $plugin_param = false
- ) {
- $GLOBALS['plugin_param'] = $plugin_param;
- $class_name = mb_strtoupper($plugin_type[0])
- . mb_strtolower(mb_substr($plugin_type, 1))
- . mb_strtoupper($plugin_format[0])
- . mb_strtolower(mb_substr($plugin_format, 1));
- $file = $class_name . ".php";
- if (is_file($plugins_dir . $file)) {
- //include_once $plugins_dir . $file;
- $fqnClass = 'PhpMyAdmin\\' . str_replace('/', '\\', mb_substr($plugins_dir, 18)) . $class_name;
- // check if class exists, could be caused by skip_import
- if (class_exists($fqnClass)) {
- return new $fqnClass;
- }
- }
- return null;
- }
- /**
- * Reads all plugin information from directory $plugins_dir
- *
- * @param string $plugin_type the type of the plugin (import, export, etc)
- * @param string $plugins_dir directory with plugins
- * @param mixed $plugin_param parameter to plugin by which they can
- * decide whether they can work
- *
- * @return array list of plugin instances
- */
- public static function getPlugins($plugin_type, $plugins_dir, $plugin_param)
- {
- $GLOBALS['plugin_param'] = $plugin_param;
- /* Scan for plugins */
- $plugin_list = array();
- if (!($handle = @opendir($plugins_dir))) {
- return $plugin_list;
- }
- $namespace = 'PhpMyAdmin\\' . str_replace('/', '\\', mb_substr($plugins_dir, 18));
- $class_type = mb_strtoupper($plugin_type[0], 'UTF-8')
- . mb_strtolower(mb_substr($plugin_type, 1), 'UTF-8');
- $prefix_class_name = $namespace . $class_type;
- while ($file = @readdir($handle)) {
- // In some situations, Mac OS creates a new file for each file
- // (for example ._csv.php) so the following regexp
- // matches a file which does not start with a dot but ends
- // with ".php"
- if (is_file($plugins_dir . $file)
- && preg_match(
- '@^' . $class_type . '([^\.]+)\.php$@i',
- $file,
- $matches
- )
- ) {
- $GLOBALS['skip_import'] = false;
- include_once $plugins_dir . $file;
- if (! $GLOBALS['skip_import']) {
- $class_name = $prefix_class_name . $matches[1];
- $plugin = new $class_name;
- if (null !== $plugin->getProperties()) {
- $plugin_list[] = $plugin;
- }
- }
- }
- }
- usort($plugin_list, function($cmp_name_1, $cmp_name_2) {
- return strcasecmp(
- $cmp_name_1->getProperties()->getText(),
- $cmp_name_2->getProperties()->getText()
- );
- });
- return $plugin_list;
- }
- /**
- * Returns locale string for $name or $name if no locale is found
- *
- * @param string $name for local string
- *
- * @return string locale string for $name
- */
- public static function getString($name)
- {
- return isset($GLOBALS[$name]) ? $GLOBALS[$name] : $name;
- }
- /**
- * Returns html input tag option 'checked' if plugin $opt
- * should be set by config or request
- *
- * @param string $section name of config section in
- * $GLOBALS['cfg'][$section] for plugin
- * @param string $opt name of option
- *
- * @return string html input tag option 'checked'
- */
- public static function checkboxCheck($section, $opt)
- {
- // If the form is being repopulated using $_GET data, that is priority
- if (isset($_GET[$opt])
- || ! isset($_GET['repopulate'])
- && ((! empty($GLOBALS['timeout_passed']) && isset($_REQUEST[$opt]))
- || ! empty($GLOBALS['cfg'][$section][$opt]))
- ) {
- return ' checked="checked"';
- }
- return '';
- }
- /**
- * Returns default value for option $opt
- *
- * @param string $section name of config section in
- * $GLOBALS['cfg'][$section] for plugin
- * @param string $opt name of option
- *
- * @return string default value for option $opt
- */
- public static function getDefault($section, $opt)
- {
- if (isset($_GET[$opt])) {
- // If the form is being repopulated using $_GET data, that is priority
- return htmlspecialchars($_GET[$opt]);
- }
- if (isset($GLOBALS['timeout_passed'])
- && $GLOBALS['timeout_passed']
- && isset($_REQUEST[$opt])
- ) {
- return htmlspecialchars($_REQUEST[$opt]);
- }
- if (!isset($GLOBALS['cfg'][$section][$opt])) {
- return '';
- }
- $matches = array();
- /* Possibly replace localised texts */
- if (!preg_match_all(
- '/(str[A-Z][A-Za-z0-9]*)/',
- $GLOBALS['cfg'][$section][$opt],
- $matches
- )) {
- return htmlspecialchars($GLOBALS['cfg'][$section][$opt]);
- }
- $val = $GLOBALS['cfg'][$section][$opt];
- foreach ($matches[0] as $match) {
- if (isset($GLOBALS[$match])) {
- $val = str_replace($match, $GLOBALS[$match], $val);
- }
- }
- return htmlspecialchars($val);
- }
- /**
- * Returns html select form element for plugin choice
- * and hidden fields denoting whether each plugin must be exported as a file
- *
- * @param string $section name of config section in
- * $GLOBALS['cfg'][$section] for plugin
- * @param string $name name of select element
- * @param array &$list array with plugin instances
- * @param string $cfgname name of config value, if none same as $name
- *
- * @return string html select tag
- */
- public static function getChoice($section, $name, array $list, $cfgname = null)
- {
- if (! isset($cfgname)) {
- $cfgname = $name;
- }
- $ret = '<select id="plugins" name="' . $name . '">';
- $default = self::getDefault($section, $cfgname);
- $hidden = null;
- foreach ($list as $plugin) {
- $elem = explode('\\', get_class($plugin));
- $plugin_name = array_pop($elem);
- unset($elem);
- $plugin_name = mb_strtolower(
- mb_substr(
- $plugin_name,
- mb_strlen($section)
- )
- );
- $ret .= '<option';
- // If the form is being repopulated using $_GET data, that is priority
- if (isset($_GET[$name])
- && $plugin_name == $_GET[$name]
- || ! isset($_GET[$name])
- && $plugin_name == $default
- ) {
- $ret .= ' selected="selected"';
- }
- /** @var PluginPropertyItem $properties */
- $properties = $plugin->getProperties();
- $text = null;
- if ($properties != null) {
- $text = $properties->getText();
- }
- $ret .= ' value="' . $plugin_name . '">'
- . self::getString($text)
- . '</option>' . "\n";
- // Whether each plugin has to be saved as a file
- $hidden .= '<input type="hidden" id="force_file_' . $plugin_name
- . '" value="';
- /** @var ExportPluginProperties|SchemaPluginProperties $properties */
- $properties = $plugin->getProperties();
- if (! strcmp($section, 'Import')
- || ($properties != null && $properties->getForceFile() != null)
- ) {
- $hidden .= 'true';
- } else {
- $hidden .= 'false';
- }
- $hidden .= '" />' . "\n";
- }
- $ret .= '</select>' . "\n" . $hidden;
- return $ret;
- }
- /**
- * Returns single option in a list element
- *
- * @param string $section name of config section in $GLOBALS['cfg'][$section] for plugin
- * @param string $plugin_name unique plugin name
- * @param array|\PhpMyAdmin\Properties\PropertyItem &$propertyGroup options property main group instance
- * @param boolean $is_subgroup if this group is a subgroup
- *
- * @return string table row with option
- */
- public static function getOneOption(
- $section,
- $plugin_name,
- &$propertyGroup,
- $is_subgroup = false
- ) {
- $ret = "\n";
- if (! $is_subgroup) {
- // for subgroup headers
- if (mb_strpos(get_class($propertyGroup), "PropertyItem")) {
- $properties = array($propertyGroup);
- } else {
- // for main groups
- $ret .= '<div class="export_sub_options" id="' . $plugin_name . '_'
- . $propertyGroup->getName() . '">';
- if (method_exists($propertyGroup, 'getText')) {
- $text = $propertyGroup->getText();
- }
- if ($text != null) {
- $ret .= '<h4>' . self::getString($text) . '</h4>';
- }
- $ret .= '<ul>';
- }
- }
- if (! isset($properties)) {
- $not_subgroup_header = true;
- if (method_exists($propertyGroup, 'getProperties')) {
- $properties = $propertyGroup->getProperties();
- }
- }
- if (isset($properties)) {
- /** @var OptionsPropertySubgroup $propertyItem */
- foreach ($properties as $propertyItem) {
- $property_class = get_class($propertyItem);
- // if the property is a subgroup, we deal with it recursively
- if (mb_strpos($property_class, "Subgroup")) {
- // for subgroups
- // each subgroup can have a header, which may also be a form element
- /** @var OptionsPropertyItem $subgroup_header */
- $subgroup_header = $propertyItem->getSubgroupHeader();
- if (isset($subgroup_header)) {
- $ret .= self::getOneOption(
- $section,
- $plugin_name,
- $subgroup_header
- );
- }
- $ret .= '<li class="subgroup"><ul';
- if (isset($subgroup_header)) {
- $ret .= ' id="ul_' . $subgroup_header->getName() . '">';
- } else {
- $ret .= '>';
- }
- $ret .= self::getOneOption(
- $section,
- $plugin_name,
- $propertyItem,
- true
- );
- continue;
- }
- // single property item
- $ret .= self::getHtmlForProperty(
- $section, $plugin_name, $propertyItem
- );
- }
- }
- if ($is_subgroup) {
- // end subgroup
- $ret .= '</ul></li>';
- } else {
- // end main group
- if (! empty($not_subgroup_header)) {
- $ret .= '</ul></div>';
- }
- }
- if (method_exists($propertyGroup, "getDoc")) {
- $doc = $propertyGroup->getDoc();
- if ($doc != null) {
- if (count($doc) == 3) {
- $ret .= PhpMyAdmin\Util::showMySQLDocu(
- $doc[1],
- false,
- $doc[2]
- );
- } elseif (count($doc) == 1) {
- $ret .= PhpMyAdmin\Util::showDocu('faq', $doc[0]);
- } else {
- $ret .= PhpMyAdmin\Util::showMySQLDocu(
- $doc[1]
- );
- }
- }
- }
- // Close the list element after $doc link is displayed
- if (isset($property_class)) {
- if ($property_class == 'PhpMyAdmin\Properties\Options\Items\BoolPropertyItem'
- || $property_class == 'PhpMyAdmin\Properties\Options\Items\MessageOnlyPropertyItem'
- || $property_class == 'PhpMyAdmin\Properties\Options\Items\SelectPropertyItem'
- || $property_class == 'PhpMyAdmin\Properties\Options\Items\TextPropertyItem'
- ) {
- $ret .= '</li>';
- }
- }
- $ret .= "\n";
- return $ret;
- }
- /**
- * Get HTML for properties items
- *
- * @param string $section name of config section in
- * $GLOBALS['cfg'][$section] for plugin
- * @param string $plugin_name unique plugin name
- * @param OptionsPropertyItem $propertyItem Property item
- *
- * @return string
- */
- public static function getHtmlForProperty(
- $section, $plugin_name, $propertyItem
- ) {
- $ret = null;
- $property_class = get_class($propertyItem);
- switch ($property_class) {
- case 'PhpMyAdmin\Properties\Options\Items\BoolPropertyItem':
- $ret .= '<li>' . "\n";
- $ret .= '<input type="checkbox" name="' . $plugin_name . '_'
- . $propertyItem->getName() . '"'
- . ' value="something" id="checkbox_' . $plugin_name . '_'
- . $propertyItem->getName() . '"'
- . ' '
- . self::checkboxCheck(
- $section,
- $plugin_name . '_' . $propertyItem->getName()
- );
- if ($propertyItem->getForce() != null) {
- // Same code is also few lines lower, update both if needed
- $ret .= ' onclick="if (!this.checked && '
- . '(!document.getElementById(\'checkbox_' . $plugin_name
- . '_' . $propertyItem->getForce() . '\') '
- . '|| !document.getElementById(\'checkbox_'
- . $plugin_name . '_' . $propertyItem->getForce()
- . '\').checked)) '
- . 'return false; else return true;"';
- }
- $ret .= ' />';
- $ret .= '<label for="checkbox_' . $plugin_name . '_'
- . $propertyItem->getName() . '">'
- . self::getString($propertyItem->getText()) . '</label>';
- break;
- case 'PhpMyAdmin\Properties\Options\Items\DocPropertyItem':
- echo 'PhpMyAdmin\Properties\Options\Items\DocPropertyItem';
- break;
- case 'PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem':
- $ret .= '<li><input type="hidden" name="' . $plugin_name . '_'
- . $propertyItem->getName() . '"'
- . ' value="' . self::getDefault(
- $section,
- $plugin_name . '_' . $propertyItem->getName()
- )
- . '"' . ' /></li>';
- break;
- case 'PhpMyAdmin\Properties\Options\Items\MessageOnlyPropertyItem':
- $ret .= '<li>' . "\n";
- $ret .= '<p>' . self::getString($propertyItem->getText()) . '</p>';
- break;
- case 'PhpMyAdmin\Properties\Options\Items\RadioPropertyItem':
- $default = self::getDefault(
- $section,
- $plugin_name . '_' . $propertyItem->getName()
- );
- foreach ($propertyItem->getValues() as $key => $val) {
- $ret .= '<li><input type="radio" name="' . $plugin_name
- . '_' . $propertyItem->getName() . '" value="' . $key
- . '" id="radio_' . $plugin_name . '_'
- . $propertyItem->getName() . '_' . $key . '"';
- if ($key == $default) {
- $ret .= ' checked="checked"';
- }
- $ret .= ' />' . '<label for="radio_' . $plugin_name . '_'
- . $propertyItem->getName() . '_' . $key . '">'
- . self::getString($val) . '</label></li>';
- }
- break;
- case 'PhpMyAdmin\Properties\Options\Items\SelectPropertyItem':
- $ret .= '<li>' . "\n";
- $ret .= '<label for="select_' . $plugin_name . '_'
- . $propertyItem->getName() . '" class="desc">'
- . self::getString($propertyItem->getText()) . '</label>';
- $ret .= '<select name="' . $plugin_name . '_'
- . $propertyItem->getName() . '"'
- . ' id="select_' . $plugin_name . '_'
- . $propertyItem->getName() . '">';
- $default = self::getDefault(
- $section,
- $plugin_name . '_' . $propertyItem->getName()
- );
- foreach ($propertyItem->getValues() as $key => $val) {
- $ret .= '<option value="' . $key . '"';
- if ($key == $default) {
- $ret .= ' selected="selected"';
- }
- $ret .= '>' . self::getString($val) . '</option>';
- }
- $ret .= '</select>';
- break;
- case 'PhpMyAdmin\Properties\Options\Items\TextPropertyItem':
- case 'PhpMyAdmin\Properties\Options\Items\NumberPropertyItem':
- $ret .= '<li>' . "\n";
- $ret .= '<label for="text_' . $plugin_name . '_'
- . $propertyItem->getName() . '" class="desc">'
- . self::getString($propertyItem->getText()) . '</label>';
- $ret .= '<input type="text" name="' . $plugin_name . '_'
- . $propertyItem->getName() . '"'
- . ' value="' . self::getDefault(
- $section,
- $plugin_name . '_' . $propertyItem->getName()
- ) . '"'
- . ' id="text_' . $plugin_name . '_'
- . $propertyItem->getName() . '"'
- . ($propertyItem->getSize() != null
- ? ' size="' . $propertyItem->getSize() . '"'
- : '')
- . ($propertyItem->getLen() != null
- ? ' maxlength="' . $propertyItem->getLen() . '"'
- : '')
- . ' />';
- break;
- default:
- break;
- }
- return $ret;
- }
- /**
- * Returns html div with editable options for plugin
- *
- * @param string $section name of config section in $GLOBALS['cfg'][$section]
- * @param array &$list array with plugin instances
- *
- * @return string html fieldset with plugin options
- */
- public static function getOptions($section, array $list)
- {
- $ret = '';
- // Options for plugins that support them
- foreach ($list as $plugin) {
- $properties = $plugin->getProperties();
- if ($properties != null) {
- $text = $properties->getText();
- $options = $properties->getOptions();
- }
- $elem = explode('\\', get_class($plugin));
- $plugin_name = array_pop($elem);
- unset($elem);
- $plugin_name = mb_strtolower(
- mb_substr(
- $plugin_name,
- mb_strlen($section)
- )
- );
- $ret .= '<div id="' . $plugin_name
- . '_options" class="format_specific_options">';
- $ret .= '<h3>' . self::getString($text) . '</h3>';
- $no_options = true;
- if (! is_null($options) && count($options) > 0) {
- foreach ($options->getProperties()
- as $propertyMainGroup
- ) {
- // check for hidden properties
- $no_options = true;
- foreach ($propertyMainGroup->getProperties() as $propertyItem) {
- if (strcmp('PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem', get_class($propertyItem))) {
- $no_options = false;
- break;
- }
- }
- $ret .= self::getOneOption(
- $section,
- $plugin_name,
- $propertyMainGroup
- );
- }
- }
- if ($no_options) {
- $ret .= '<p>' . __('This format has no options') . '</p>';
- }
- $ret .= '</div>';
- }
- return $ret;
- }
- }
|