Translated using Weblate (Estonian)
[phpmyadmin.git] / libraries / plugin_interface.lib.php
blobadd6671665ec26ad3e9bd63661ba138935f00b9b
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Generic plugin interface.
6 * @package PhpMyAdmin
7 */
8 use PhpMyAdmin\Properties\Options\Groups\OptionsPropertySubgroup;
9 use PhpMyAdmin\Properties\Options\OptionsPropertyItem;
10 use PhpMyAdmin\Properties\Plugins\ExportPluginProperties;
11 use PhpMyAdmin\Properties\Plugins\PluginPropertyItem;
12 use PhpMyAdmin\Properties\Plugins\SchemaPluginProperties;
14 /**
15 * Includes and instantiates the specified plugin type for a certain format
17 * @param string $plugin_type the type of the plugin (import, export, etc)
18 * @param string $plugin_format the format of the plugin (sql, xml, et )
19 * @param string $plugins_dir directory with plugins
20 * @param mixed $plugin_param parameter to plugin by which they can
21 * decide whether they can work
23 * @return object|null new plugin instance
25 function PMA_getPlugin(
26 $plugin_type,
27 $plugin_format,
28 $plugins_dir,
29 $plugin_param = false
30 ) {
31 $GLOBALS['plugin_param'] = $plugin_param;
32 $class_name = mb_strtoupper($plugin_type[0])
33 . mb_strtolower(mb_substr($plugin_type, 1))
34 . mb_strtoupper($plugin_format[0])
35 . mb_strtolower(mb_substr($plugin_format, 1));
36 $file = $class_name . ".php";
37 if (is_file($plugins_dir . $file)) {
38 //include_once $plugins_dir . $file;
39 $fqnClass = 'PhpMyAdmin\\' . str_replace('/', '\\', mb_substr($plugins_dir, 18)) . $class_name;
40 // check if class exists, could be caused by skip_import
41 if (class_exists($fqnClass)) {
42 return new $fqnClass;
46 return null;
49 /**
50 * Reads all plugin information from directory $plugins_dir
52 * @param string $plugin_type the type of the plugin (import, export, etc)
53 * @param string $plugins_dir directory with plugins
54 * @param mixed $plugin_param parameter to plugin by which they can
55 * decide whether they can work
57 * @return array list of plugin instances
59 function PMA_getPlugins($plugin_type, $plugins_dir, $plugin_param)
61 $GLOBALS['plugin_param'] = $plugin_param;
62 /* Scan for plugins */
63 $plugin_list = array();
64 if (!($handle = @opendir($plugins_dir))) {
65 return $plugin_list;
68 $namespace = 'PhpMyAdmin\\' . str_replace('/', '\\', mb_substr($plugins_dir, 18));
69 $class_type = mb_strtoupper($plugin_type[0], 'UTF-8')
70 . mb_strtolower(mb_substr($plugin_type, 1), 'UTF-8');
72 $prefix_class_name = $namespace . $class_type;
74 while ($file = @readdir($handle)) {
75 // In some situations, Mac OS creates a new file for each file
76 // (for example ._csv.php) so the following regexp
77 // matches a file which does not start with a dot but ends
78 // with ".php"
79 if (is_file($plugins_dir . $file)
80 && preg_match(
81 '@^' . $class_type . '([^\.]+)\.php$@i',
82 $file,
83 $matches
85 ) {
86 $GLOBALS['skip_import'] = false;
87 include_once $plugins_dir . $file;
88 if (! $GLOBALS['skip_import']) {
89 $class_name = $prefix_class_name . $matches[1];
90 $plugin = new $class_name;
91 if (null !== $plugin->getProperties()) {
92 $plugin_list[] = $plugin;
98 usort($plugin_list, function($cmp_name_1, $cmp_name_2) {
99 return strcasecmp(
100 $cmp_name_1->getProperties()->getText(),
101 $cmp_name_2->getProperties()->getText()
104 return $plugin_list;
108 * Returns locale string for $name or $name if no locale is found
110 * @param string $name for local string
112 * @return string locale string for $name
114 function PMA_getString($name)
116 return isset($GLOBALS[$name]) ? $GLOBALS[$name] : $name;
120 * Returns html input tag option 'checked' if plugin $opt
121 * should be set by config or request
123 * @param string $section name of config section in
124 * $GLOBALS['cfg'][$section] for plugin
125 * @param string $opt name of option
127 * @return string html input tag option 'checked'
129 function PMA_pluginCheckboxCheck($section, $opt)
131 // If the form is being repopulated using $_GET data, that is priority
132 if (isset($_GET[$opt])
133 || ! isset($_GET['repopulate'])
134 && ((! empty($GLOBALS['timeout_passed']) && isset($_REQUEST[$opt]))
135 || ! empty($GLOBALS['cfg'][$section][$opt]))
137 return ' checked="checked"';
139 return '';
143 * Returns default value for option $opt
145 * @param string $section name of config section in
146 * $GLOBALS['cfg'][$section] for plugin
147 * @param string $opt name of option
149 * @return string default value for option $opt
151 function PMA_pluginGetDefault($section, $opt)
153 if (isset($_GET[$opt])) {
154 // If the form is being repopulated using $_GET data, that is priority
155 return htmlspecialchars($_GET[$opt]);
158 if (isset($GLOBALS['timeout_passed'])
159 && $GLOBALS['timeout_passed']
160 && isset($_REQUEST[$opt])
162 return htmlspecialchars($_REQUEST[$opt]);
165 if (!isset($GLOBALS['cfg'][$section][$opt])) {
166 return '';
169 $matches = array();
170 /* Possibly replace localised texts */
171 if (!preg_match_all(
172 '/(str[A-Z][A-Za-z0-9]*)/',
173 $GLOBALS['cfg'][$section][$opt],
174 $matches
175 )) {
176 return htmlspecialchars($GLOBALS['cfg'][$section][$opt]);
179 $val = $GLOBALS['cfg'][$section][$opt];
180 foreach ($matches[0] as $match) {
181 if (isset($GLOBALS[$match])) {
182 $val = str_replace($match, $GLOBALS[$match], $val);
185 return htmlspecialchars($val);
189 * Returns html select form element for plugin choice
190 * and hidden fields denoting whether each plugin must be exported as a file
192 * @param string $section name of config section in
193 * $GLOBALS['cfg'][$section] for plugin
194 * @param string $name name of select element
195 * @param array &$list array with plugin instances
196 * @param string $cfgname name of config value, if none same as $name
198 * @return string html select tag
200 function PMA_pluginGetChoice($section, $name, &$list, $cfgname = null)
202 if (! isset($cfgname)) {
203 $cfgname = $name;
205 $ret = '<select id="plugins" name="' . $name . '">';
206 $default = PMA_pluginGetDefault($section, $cfgname);
207 $hidden = null;
208 foreach ($list as $plugin) {
209 $elem = explode('\\', get_class($plugin));
210 $plugin_name = array_pop($elem);
211 unset($elem);
212 $plugin_name = mb_strtolower(
213 mb_substr(
214 $plugin_name,
215 mb_strlen($section)
218 $ret .= '<option';
219 // If the form is being repopulated using $_GET data, that is priority
220 if (isset($_GET[$name])
221 && $plugin_name == $_GET[$name]
222 || ! isset($_GET[$name])
223 && $plugin_name == $default
225 $ret .= ' selected="selected"';
228 /** @var PluginPropertyItem $properties */
229 $properties = $plugin->getProperties();
230 $text = null;
231 if ($properties != null) {
232 $text = $properties->getText();
234 $ret .= ' value="' . $plugin_name . '">'
235 . PMA_getString($text)
236 . '</option>' . "\n";
238 // Whether each plugin has to be saved as a file
239 $hidden .= '<input type="hidden" id="force_file_' . $plugin_name
240 . '" value="';
241 /** @var ExportPluginProperties|SchemaPluginProperties $properties */
242 $properties = $plugin->getProperties();
243 if (! strcmp($section, 'Import')
244 || ($properties != null && $properties->getForceFile() != null)
246 $hidden .= 'true';
247 } else {
248 $hidden .= 'false';
250 $hidden .= '" />' . "\n";
252 $ret .= '</select>' . "\n" . $hidden;
254 return $ret;
258 * Returns single option in a list element
260 * @param string $section name of config section in $GLOBALS['cfg'][$section] for plugin
261 * config
262 * section in
263 * $GLOBALS['cfg'][$section]
264 * for plugin
265 * @param string $plugin_name unique plugin name
266 * name
267 * @param array|\PhpMyAdmin\Properties\PropertyItem &$propertyGroup options
268 * property main
269 * group
270 * instance
271 * @param boolean $is_subgroup if this group is a subgroup
272 * is a subgroup
274 * @return string table row with option
276 function PMA_pluginGetOneOption(
277 $section,
278 $plugin_name,
279 &$propertyGroup,
280 $is_subgroup = false
282 $ret = "\n";
284 if (! $is_subgroup) {
285 // for subgroup headers
286 if (mb_strpos(get_class($propertyGroup), "PropertyItem")) {
287 $properties = array($propertyGroup);
288 } else {
289 // for main groups
290 $ret .= '<div class="export_sub_options" id="' . $plugin_name . '_'
291 . $propertyGroup->getName() . '">';
293 if (method_exists($propertyGroup, 'getText')) {
294 $text = $propertyGroup->getText();
297 if ($text != null) {
298 $ret .= '<h4>' . PMA_getString($text) . '</h4>';
300 $ret .= '<ul>';
304 if (! isset($properties)) {
305 $not_subgroup_header = true;
306 if (method_exists($propertyGroup, 'getProperties')) {
307 $properties = $propertyGroup->getProperties();
311 if (isset($properties)) {
312 /** @var OptionsPropertySubgroup $propertyItem */
313 foreach ($properties as $propertyItem) {
314 $property_class = get_class($propertyItem);
315 // if the property is a subgroup, we deal with it recursively
316 if (mb_strpos($property_class, "Subgroup")) {
317 // for subgroups
318 // each subgroup can have a header, which may also be a form element
319 /** @var OptionsPropertyItem $subgroup_header */
320 $subgroup_header = $propertyItem->getSubgroupHeader();
321 if (isset($subgroup_header)) {
322 $ret .= PMA_pluginGetOneOption(
323 $section,
324 $plugin_name,
325 $subgroup_header
329 $ret .= '<li class="subgroup"><ul';
330 if (isset($subgroup_header)) {
331 $ret .= ' id="ul_' . $subgroup_header->getName() . '">';
332 } else {
333 $ret .= '>';
336 $ret .= PMA_pluginGetOneOption(
337 $section,
338 $plugin_name,
339 $propertyItem,
340 true
342 continue;
345 // single property item
346 $ret .= PMA_getHtmlForProperty(
347 $section, $plugin_name, $propertyItem
352 if ($is_subgroup) {
353 // end subgroup
354 $ret .= '</ul></li>';
355 } else {
356 // end main group
357 if (! empty($not_subgroup_header)) {
358 $ret .= '</ul></div>';
362 if (method_exists($propertyGroup, "getDoc")) {
363 $doc = $propertyGroup->getDoc();
364 if ($doc != null) {
365 if (count($doc) == 3) {
366 $ret .= PhpMyAdmin\Util::showMySQLDocu(
367 $doc[1],
368 false,
369 $doc[2]
371 } elseif (count($doc) == 1) {
372 $ret .= PhpMyAdmin\Util::showDocu('faq', $doc[0]);
373 } else {
374 $ret .= PhpMyAdmin\Util::showMySQLDocu(
375 $doc[1]
381 // Close the list element after $doc link is displayed
382 if (isset($property_class)) {
383 if ($property_class == 'PhpMyAdmin\Properties\Options\Items\BoolPropertyItem'
384 || $property_class == 'PhpMyAdmin\Properties\Options\Items\MessageOnlyPropertyItem'
385 || $property_class == 'PhpMyAdmin\Properties\Options\Items\SelectPropertyItem'
386 || $property_class == 'PhpMyAdmin\Properties\Options\Items\TextPropertyItem'
388 $ret .= '</li>';
391 $ret .= "\n";
392 return $ret;
396 * Get HTML for properties items
398 * @param string $section name of config section in
399 * $GLOBALS['cfg'][$section] for plugin
400 * @param string $plugin_name unique plugin name
401 * @param OptionsPropertyItem $propertyItem Property item
403 * @return string
405 function PMA_getHtmlForProperty(
406 $section, $plugin_name, $propertyItem
408 $ret = null;
409 $property_class = get_class($propertyItem);
410 switch ($property_class) {
411 case 'PhpMyAdmin\Properties\Options\Items\BoolPropertyItem':
412 $ret .= '<li>' . "\n";
413 $ret .= '<input type="checkbox" name="' . $plugin_name . '_'
414 . $propertyItem->getName() . '"'
415 . ' value="something" id="checkbox_' . $plugin_name . '_'
416 . $propertyItem->getName() . '"'
417 . ' '
418 . PMA_pluginCheckboxCheck(
419 $section,
420 $plugin_name . '_' . $propertyItem->getName()
423 if ($propertyItem->getForce() != null) {
424 // Same code is also few lines lower, update both if needed
425 $ret .= ' onclick="if (!this.checked &amp;&amp; '
426 . '(!document.getElementById(\'checkbox_' . $plugin_name
427 . '_' . $propertyItem->getForce() . '\') '
428 . '|| !document.getElementById(\'checkbox_'
429 . $plugin_name . '_' . $propertyItem->getForce()
430 . '\').checked)) '
431 . 'return false; else return true;"';
433 $ret .= ' />';
434 $ret .= '<label for="checkbox_' . $plugin_name . '_'
435 . $propertyItem->getName() . '">'
436 . PMA_getString($propertyItem->getText()) . '</label>';
437 break;
438 case 'PhpMyAdmin\Properties\Options\Items\DocPropertyItem':
439 echo 'PhpMyAdmin\Properties\Options\Items\DocPropertyItem';
440 break;
441 case 'PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem':
442 $ret .= '<li><input type="hidden" name="' . $plugin_name . '_'
443 . $propertyItem->getName() . '"'
444 . ' value="' . PMA_pluginGetDefault(
445 $section,
446 $plugin_name . '_' . $propertyItem->getName()
448 . '"' . ' /></li>';
449 break;
450 case 'PhpMyAdmin\Properties\Options\Items\MessageOnlyPropertyItem':
451 $ret .= '<li>' . "\n";
452 $ret .= '<p>' . PMA_getString($propertyItem->getText()) . '</p>';
453 break;
454 case 'PhpMyAdmin\Properties\Options\Items\RadioPropertyItem':
455 $default = PMA_pluginGetDefault(
456 $section,
457 $plugin_name . '_' . $propertyItem->getName()
459 foreach ($propertyItem->getValues() as $key => $val) {
460 $ret .= '<li><input type="radio" name="' . $plugin_name
461 . '_' . $propertyItem->getName() . '" value="' . $key
462 . '" id="radio_' . $plugin_name . '_'
463 . $propertyItem->getName() . '_' . $key . '"';
464 if ($key == $default) {
465 $ret .= ' checked="checked"';
467 $ret .= ' />' . '<label for="radio_' . $plugin_name . '_'
468 . $propertyItem->getName() . '_' . $key . '">'
469 . PMA_getString($val) . '</label></li>';
471 break;
472 case 'PhpMyAdmin\Properties\Options\Items\SelectPropertyItem':
473 $ret .= '<li>' . "\n";
474 $ret .= '<label for="select_' . $plugin_name . '_'
475 . $propertyItem->getName() . '" class="desc">'
476 . PMA_getString($propertyItem->getText()) . '</label>';
477 $ret .= '<select name="' . $plugin_name . '_'
478 . $propertyItem->getName() . '"'
479 . ' id="select_' . $plugin_name . '_'
480 . $propertyItem->getName() . '">';
481 $default = PMA_pluginGetDefault(
482 $section,
483 $plugin_name . '_' . $propertyItem->getName()
485 foreach ($propertyItem->getValues() as $key => $val) {
486 $ret .= '<option value="' . $key . '"';
487 if ($key == $default) {
488 $ret .= ' selected="selected"';
490 $ret .= '>' . PMA_getString($val) . '</option>';
492 $ret .= '</select>';
493 break;
494 case 'PhpMyAdmin\Properties\Options\Items\TextPropertyItem':
495 case 'PhpMyAdmin\Properties\Options\Items\NumberPropertyItem':
496 $ret .= '<li>' . "\n";
497 $ret .= '<label for="text_' . $plugin_name . '_'
498 . $propertyItem->getName() . '" class="desc">'
499 . PMA_getString($propertyItem->getText()) . '</label>';
500 $ret .= '<input type="text" name="' . $plugin_name . '_'
501 . $propertyItem->getName() . '"'
502 . ' value="' . PMA_pluginGetDefault(
503 $section,
504 $plugin_name . '_' . $propertyItem->getName()
505 ) . '"'
506 . ' id="text_' . $plugin_name . '_'
507 . $propertyItem->getName() . '"'
508 . ($propertyItem->getSize() != null
509 ? ' size="' . $propertyItem->getSize() . '"'
510 : '')
511 . ($propertyItem->getLen() != null
512 ? ' maxlength="' . $propertyItem->getLen() . '"'
513 : '')
514 . ' />';
515 break;
516 default:
517 break;
519 return $ret;
523 * Returns html div with editable options for plugin
525 * @param string $section name of config section in $GLOBALS['cfg'][$section]
526 * @param array &$list array with plugin instances
528 * @return string html fieldset with plugin options
530 function PMA_pluginGetOptions($section, &$list)
532 $ret = '';
533 // Options for plugins that support them
534 foreach ($list as $plugin) {
535 $properties = $plugin->getProperties();
536 if ($properties != null) {
537 $text = $properties->getText();
538 $options = $properties->getOptions();
541 $elem = explode('\\', get_class($plugin));
542 $plugin_name = array_pop($elem);
543 unset($elem);
544 $plugin_name = mb_strtolower(
545 mb_substr(
546 $plugin_name,
547 mb_strlen($section)
551 $ret .= '<div id="' . $plugin_name
552 . '_options" class="format_specific_options">';
553 $ret .= '<h3>' . PMA_getString($text) . '</h3>';
555 $no_options = true;
556 if (! is_null($options) && count($options) > 0) {
557 foreach ($options->getProperties()
558 as $propertyMainGroup
560 // check for hidden properties
561 $no_options = true;
562 foreach ($propertyMainGroup->getProperties() as $propertyItem) {
563 if (strcmp('PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem', get_class($propertyItem))) {
564 $no_options = false;
565 break;
569 $ret .= PMA_pluginGetOneOption(
570 $section,
571 $plugin_name,
572 $propertyMainGroup
577 if ($no_options) {
578 $ret .= '<p>' . __('This format has no options') . '</p>';
580 $ret .= '</div>';
582 return $ret;