Translated using Weblate (Slovenian)
[phpmyadmin.git] / libraries / plugin_interface.lib.php
blob0376e87e1a1743ecd94bea4f94be3d4d9ac153dc
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Generic plugin interface.
6 * @package PhpMyAdmin
7 */
8 use PMA\libraries\properties\options\groups\OptionsPropertySubgroup;
9 use PMA\libraries\properties\options\OptionsPropertyItem;
10 use PMA\libraries\properties\plugins\ExportPluginProperties;
11 use PMA\libraries\properties\plugins\PluginPropertyItem;
12 use PMA\libraries\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 = 'PMA\\' . str_replace('/', '\\', $plugins_dir) . $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 = 'PMA\\' . str_replace('/', '\\', $plugins_dir);
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 ksort($plugin_list);
99 return $plugin_list;
103 * Returns locale string for $name or $name if no locale is found
105 * @param string $name for local string
107 * @return string locale string for $name
109 function PMA_getString($name)
111 return isset($GLOBALS[$name]) ? $GLOBALS[$name] : $name;
115 * Returns html input tag option 'checked' if plugin $opt
116 * should be set by config or request
118 * @param string $section name of config section in
119 * $GLOBALS['cfg'][$section] for plugin
120 * @param string $opt name of option
122 * @return string html input tag option 'checked'
124 function PMA_pluginCheckboxCheck($section, $opt)
126 // If the form is being repopulated using $_GET data, that is priority
127 if (isset($_GET[$opt])
128 || ! isset($_GET['repopulate'])
129 && ((! empty($GLOBALS['timeout_passed']) && isset($_REQUEST[$opt]))
130 || ! empty($GLOBALS['cfg'][$section][$opt]))
132 return ' checked="checked"';
134 return '';
138 * Returns default value for option $opt
140 * @param string $section name of config section in
141 * $GLOBALS['cfg'][$section] for plugin
142 * @param string $opt name of option
144 * @return string default value for option $opt
146 function PMA_pluginGetDefault($section, $opt)
148 if (isset($_GET[$opt])) {
149 // If the form is being repopulated using $_GET data, that is priority
150 return htmlspecialchars($_GET[$opt]);
153 if (isset($GLOBALS['timeout_passed'])
154 && $GLOBALS['timeout_passed']
155 && isset($_REQUEST[$opt])
157 return htmlspecialchars($_REQUEST[$opt]);
160 if (!isset($GLOBALS['cfg'][$section][$opt])) {
161 return '';
164 $matches = array();
165 /* Possibly replace localised texts */
166 if (!preg_match_all(
167 '/(str[A-Z][A-Za-z0-9]*)/',
168 $GLOBALS['cfg'][$section][$opt],
169 $matches
170 )) {
171 return htmlspecialchars($GLOBALS['cfg'][$section][$opt]);
174 $val = $GLOBALS['cfg'][$section][$opt];
175 foreach ($matches[0] as $match) {
176 if (isset($GLOBALS[$match])) {
177 $val = str_replace($match, $GLOBALS[$match], $val);
180 return htmlspecialchars($val);
184 * Returns html select form element for plugin choice
185 * and hidden fields denoting whether each plugin must be exported as a file
187 * @param string $section name of config section in
188 * $GLOBALS['cfg'][$section] for plugin
189 * @param string $name name of select element
190 * @param array &$list array with plugin instances
191 * @param string $cfgname name of config value, if none same as $name
193 * @return string html select tag
195 function PMA_pluginGetChoice($section, $name, &$list, $cfgname = null)
197 if (! isset($cfgname)) {
198 $cfgname = $name;
200 $ret = '<select id="plugins" name="' . $name . '">';
201 $default = PMA_pluginGetDefault($section, $cfgname);
202 $hidden = null;
203 foreach ($list as $plugin) {
204 $elem = explode('\\', get_class($plugin));
205 $plugin_name = array_pop($elem);
206 unset($elem);
207 $plugin_name = mb_strtolower(
208 mb_substr(
209 $plugin_name,
210 mb_strlen($section)
213 $ret .= '<option';
214 // If the form is being repopulated using $_GET data, that is priority
215 if (isset($_GET[$name])
216 && $plugin_name == $_GET[$name]
217 || ! isset($_GET[$name])
218 && $plugin_name == $default
220 $ret .= ' selected="selected"';
223 /** @var PluginPropertyItem $properties */
224 $properties = $plugin->getProperties();
225 $text = null;
226 if ($properties != null) {
227 $text = $properties->getText();
229 $ret .= ' value="' . $plugin_name . '">'
230 . PMA_getString($text)
231 . '</option>' . "\n";
233 // Whether each plugin has to be saved as a file
234 $hidden .= '<input type="hidden" id="force_file_' . $plugin_name
235 . '" value="';
236 /** @var ExportPluginProperties|SchemaPluginProperties $properties */
237 $properties = $plugin->getProperties();
238 if (! strcmp($section, 'Import')
239 || ($properties != null && $properties->getForceFile() != null)
241 $hidden .= 'true';
242 } else {
243 $hidden .= 'false';
245 $hidden .= '" />' . "\n";
247 $ret .= '</select>' . "\n" . $hidden;
249 return $ret;
253 * Returns single option in a list element
255 * @param string $section name of
256 * config
257 * section in
258 * $GLOBALS['cfg'][$section]
259 * for plugin
260 * @param string $plugin_name unique plugin
261 * name
262 * @param array|\PMA\libraries\properties\PropertyItem &$propertyGroup options
263 * property main
264 * group
265 * instance
266 * @param boolean $is_subgroup if this group
267 * is a subgroup
269 * @return string table row with option
271 function PMA_pluginGetOneOption(
272 $section,
273 $plugin_name,
274 &$propertyGroup,
275 $is_subgroup = false
277 $ret = "\n";
279 if (! $is_subgroup) {
280 // for subgroup headers
281 if (mb_strpos(get_class($propertyGroup), "PropertyItem")) {
282 $properties = array($propertyGroup);
283 } else {
284 // for main groups
285 $ret .= '<div class="export_sub_options" id="' . $plugin_name . '_'
286 . $propertyGroup->getName() . '">';
288 if (method_exists($propertyGroup, 'getText')) {
289 $text = $propertyGroup->getText();
292 if ($text != null) {
293 $ret .= '<h4>' . PMA_getString($text) . '</h4>';
295 $ret .= '<ul>';
299 if (! isset($properties)) {
300 $not_subgroup_header = true;
301 if (method_exists($propertyGroup, 'getProperties')) {
302 $properties = $propertyGroup->getProperties();
306 if (isset($properties)) {
307 /** @var OptionsPropertySubgroup $propertyItem */
308 foreach ($properties as $propertyItem) {
309 $property_class = get_class($propertyItem);
310 // if the property is a subgroup, we deal with it recursively
311 if (mb_strpos($property_class, "Subgroup")) {
312 // for subgroups
313 // each subgroup can have a header, which may also be a form element
314 /** @var OptionsPropertyItem $subgroup_header */
315 $subgroup_header = $propertyItem->getSubgroupHeader();
316 if (isset($subgroup_header)) {
317 $ret .= PMA_pluginGetOneOption(
318 $section,
319 $plugin_name,
320 $subgroup_header
324 $ret .= '<li class="subgroup"><ul';
325 if (isset($subgroup_header)) {
326 $ret .= ' id="ul_' . $subgroup_header->getName() . '">';
327 } else {
328 $ret .= '>';
331 $ret .= PMA_pluginGetOneOption(
332 $section,
333 $plugin_name,
334 $propertyItem,
335 true
337 continue;
340 // single property item
341 $ret .= PMA_getHtmlForProperty(
342 $section, $plugin_name, $propertyItem
347 if ($is_subgroup) {
348 // end subgroup
349 $ret .= '</ul></li>';
350 } else {
351 // end main group
352 if (! empty($not_subgroup_header)) {
353 $ret .= '</ul></div>';
357 if (method_exists($propertyGroup, "getDoc")) {
358 $doc = $propertyGroup->getDoc();
359 if ($doc != null) {
360 if (count($doc) == 3) {
361 $ret .= PMA\libraries\Util::showMySQLDocu(
362 $doc[1],
363 false,
364 $doc[2]
366 } elseif (count($doc) == 1) {
367 $ret .= PMA\libraries\Util::showDocu('faq', $doc[0]);
368 } else {
369 $ret .= PMA\libraries\Util::showMySQLDocu(
370 $doc[1]
376 // Close the list element after $doc link is displayed
377 if (isset($property_class)) {
378 if ($property_class == 'PMA\libraries\properties\options\items\BoolPropertyItem'
379 || $property_class == 'PMA\libraries\properties\options\items\MessageOnlyPropertyItem'
380 || $property_class == 'PMA\libraries\properties\options\items\SelectPropertyItem'
381 || $property_class == 'PMA\libraries\properties\options\items\TextPropertyItem'
383 $ret .= '</li>';
386 $ret .= "\n";
387 return $ret;
391 * Get HTML for properties items
393 * @param string $section name of config section in
394 * $GLOBALS['cfg'][$section] for plugin
395 * @param string $plugin_name unique plugin name
396 * @param OptionsPropertyItem $propertyItem Property item
398 * @return string
400 function PMA_getHtmlForProperty(
401 $section, $plugin_name, $propertyItem
403 $ret = null;
404 $property_class = get_class($propertyItem);
405 switch ($property_class) {
406 case 'PMA\libraries\properties\options\items\BoolPropertyItem':
407 $ret .= '<li>' . "\n";
408 $ret .= '<input type="checkbox" name="' . $plugin_name . '_'
409 . $propertyItem->getName() . '"'
410 . ' value="something" id="checkbox_' . $plugin_name . '_'
411 . $propertyItem->getName() . '"'
412 . ' '
413 . PMA_pluginCheckboxCheck(
414 $section,
415 $plugin_name . '_' . $propertyItem->getName()
418 if ($propertyItem->getForce() != null) {
419 // Same code is also few lines lower, update both if needed
420 $ret .= ' onclick="if (!this.checked &amp;&amp; '
421 . '(!document.getElementById(\'checkbox_' . $plugin_name
422 . '_' . $propertyItem->getForce() . '\') '
423 . '|| !document.getElementById(\'checkbox_'
424 . $plugin_name . '_' . $propertyItem->getForce()
425 . '\').checked)) '
426 . 'return false; else return true;"';
428 $ret .= ' />';
429 $ret .= '<label for="checkbox_' . $plugin_name . '_'
430 . $propertyItem->getName() . '">'
431 . PMA_getString($propertyItem->getText()) . '</label>';
432 break;
433 case 'PMA\libraries\properties\options\items\DocPropertyItem':
434 echo 'PMA\libraries\properties\options\items\DocPropertyItem';
435 break;
436 case 'PMA\libraries\properties\options\items\HiddenPropertyItem':
437 $ret .= '<li><input type="hidden" name="' . $plugin_name . '_'
438 . $propertyItem->getName() . '"'
439 . ' value="' . PMA_pluginGetDefault(
440 $section,
441 $plugin_name . '_' . $propertyItem->getName()
443 . '"' . ' /></li>';
444 break;
445 case 'PMA\libraries\properties\options\items\MessageOnlyPropertyItem':
446 $ret .= '<li>' . "\n";
447 $ret .= '<p>' . PMA_getString($propertyItem->getText()) . '</p>';
448 break;
449 case 'PMA\libraries\properties\options\items\RadioPropertyItem':
450 $default = PMA_pluginGetDefault(
451 $section,
452 $plugin_name . '_' . $propertyItem->getName()
454 foreach ($propertyItem->getValues() as $key => $val) {
455 $ret .= '<li><input type="radio" name="' . $plugin_name
456 . '_' . $propertyItem->getName() . '" value="' . $key
457 . '" id="radio_' . $plugin_name . '_'
458 . $propertyItem->getName() . '_' . $key . '"';
459 if ($key == $default) {
460 $ret .= ' checked="checked"';
462 $ret .= ' />' . '<label for="radio_' . $plugin_name . '_'
463 . $propertyItem->getName() . '_' . $key . '">'
464 . PMA_getString($val) . '</label></li>';
466 break;
467 case 'PMA\libraries\properties\options\items\SelectPropertyItem':
468 $ret .= '<li>' . "\n";
469 $ret .= '<label for="select_' . $plugin_name . '_'
470 . $propertyItem->getName() . '" class="desc">'
471 . PMA_getString($propertyItem->getText()) . '</label>';
472 $ret .= '<select name="' . $plugin_name . '_'
473 . $propertyItem->getName() . '"'
474 . ' id="select_' . $plugin_name . '_'
475 . $propertyItem->getName() . '">';
476 $default = PMA_pluginGetDefault(
477 $section,
478 $plugin_name . '_' . $propertyItem->getName()
480 foreach ($propertyItem->getValues() as $key => $val) {
481 $ret .= '<option value="' . $key . '"';
482 if ($key == $default) {
483 $ret .= ' selected="selected"';
485 $ret .= '>' . PMA_getString($val) . '</option>';
487 $ret .= '</select>';
488 break;
489 case 'PMA\libraries\properties\options\items\TextPropertyItem':
490 case 'PMA\libraries\properties\options\items\NumberPropertyItem':
491 $ret .= '<li>' . "\n";
492 $ret .= '<label for="text_' . $plugin_name . '_'
493 . $propertyItem->getName() . '" class="desc">'
494 . PMA_getString($propertyItem->getText()) . '</label>';
495 $ret .= '<input type="text" name="' . $plugin_name . '_'
496 . $propertyItem->getName() . '"'
497 . ' value="' . PMA_pluginGetDefault(
498 $section,
499 $plugin_name . '_' . $propertyItem->getName()
500 ) . '"'
501 . ' id="text_' . $plugin_name . '_'
502 . $propertyItem->getName() . '"'
503 . ($propertyItem->getSize() != null
504 ? ' size="' . $propertyItem->getSize() . '"'
505 : '')
506 . ($propertyItem->getLen() != null
507 ? ' maxlength="' . $propertyItem->getLen() . '"'
508 : '')
509 . ' />';
510 break;
511 default:
512 break;
514 return $ret;
518 * Returns html div with editable options for plugin
520 * @param string $section name of config section in $GLOBALS['cfg'][$section]
521 * @param array &$list array with plugin instances
523 * @return string html fieldset with plugin options
525 function PMA_pluginGetOptions($section, &$list)
527 $ret = '';
528 // Options for plugins that support them
529 foreach ($list as $plugin) {
530 $properties = $plugin->getProperties();
531 if ($properties != null) {
532 $text = $properties->getText();
533 $options = $properties->getOptions();
536 $elem = explode('\\', get_class($plugin));
537 $plugin_name = array_pop($elem);
538 unset($elem);
539 $plugin_name = mb_strtolower(
540 mb_substr(
541 $plugin_name,
542 mb_strlen($section)
546 $ret .= '<div id="' . $plugin_name
547 . '_options" class="format_specific_options">';
548 $ret .= '<h3>' . PMA_getString($text) . '</h3>';
550 $no_options = true;
551 if ($options != null && count($options) > 0) {
552 foreach ($options->getProperties()
553 as $propertyMainGroup
555 // check for hidden properties
556 $no_options = true;
557 foreach ($propertyMainGroup->getProperties() as $propertyItem) {
558 if (strcmp('PMA\libraries\properties\options\items\HiddenPropertyItem', get_class($propertyItem))) {
559 $no_options = false;
560 break;
564 $ret .= PMA_pluginGetOneOption(
565 $section,
566 $plugin_name,
567 $propertyMainGroup
572 if ($no_options) {
573 $ret .= '<p>' . __('This format has no options') . '</p>';
575 $ret .= '</div>';
577 return $ret;