Translated using Weblate (Armenian)
[phpmyadmin.git] / libraries / plugin_interface.lib.php
blobdd6f775f5b1d9e83ca577bc089929e622a55249f
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Generic plugin interface.
6 * @package PhpMyAdmin
7 */
9 /**
10 * Includes and instantiates the specified plugin type for a certain format
12 * @param string $plugin_type the type of the plugin (import, export, etc)
13 * @param string $plugin_format the format of the plugin (sql, xml, et )
14 * @param string $plugins_dir directory with plugins
15 * @param mixed $plugin_param parameter to plugin by which they can
16 * decide whether they can work
18 * @return object|null new plugin instance
20 function PMA_getPlugin(
21 $plugin_type,
22 $plugin_format,
23 $plugins_dir,
24 $plugin_param = false
25 ) {
26 $GLOBALS['plugin_param'] = $plugin_param;
27 $class_name = /*overload*/mb_strtoupper($plugin_type[0])
28 . /*overload*/mb_strtolower(/*overload*/mb_substr($plugin_type, 1))
29 . /*overload*/mb_strtoupper($plugin_format[0])
30 . /*overload*/mb_strtolower(/*overload*/mb_substr($plugin_format, 1));
31 $file = $class_name . ".class.php";
32 if (is_file($plugins_dir . $file)) {
33 include_once $plugins_dir . $file;
34 return new $class_name;
37 return null;
40 /**
41 * Reads all plugin information from directory $plugins_dir
43 * @param string $plugin_type the type of the plugin (import, export, etc)
44 * @param string $plugins_dir directory with plugins
45 * @param mixed $plugin_param parameter to plugin by which they can
46 * decide whether they can work
48 * @return array list of plugin instances
50 function PMA_getPlugins($plugin_type, $plugins_dir, $plugin_param)
52 $GLOBALS['plugin_param'] = $plugin_param;
53 /* Scan for plugins */
54 $plugin_list = array();
55 if (!($handle = @opendir($plugins_dir))) {
56 ksort($plugin_list);
57 return $plugin_list;
60 //@todo Find a way to use PMA_StringMB with UTF-8 instead of mb_*.
61 while ($file = @readdir($handle)) {
62 // In some situations, Mac OS creates a new file for each file
63 // (for example ._csv.php) so the following regexp
64 // matches a file which does not start with a dot but ends
65 // with ".php"
66 $class_type = mb_strtoupper($plugin_type[0], 'UTF-8')
67 . mb_strtolower(/*overload*/mb_substr($plugin_type, 1), 'UTF-8');
68 if (is_file($plugins_dir . $file)
69 && preg_match(
70 '@^' . $class_type . '(.+)\.class\.php$@i',
71 $file,
72 $matches
74 ) {
75 $GLOBALS['skip_import'] = false;
76 include_once $plugins_dir . $file;
77 if (! $GLOBALS['skip_import']) {
78 $class_name = $class_type . $matches[1];
79 $plugin = new $class_name;
80 if (null !== $plugin->getProperties()) {
81 $plugin_list[] = $plugin;
87 ksort($plugin_list);
88 return $plugin_list;
91 /**
92 * Returns locale string for $name or $name if no locale is found
94 * @param string $name for local string
96 * @return string locale string for $name
98 function PMA_getString($name)
100 return isset($GLOBALS[$name]) ? $GLOBALS[$name] : $name;
104 * Returns html input tag option 'checked' if plugin $opt
105 * should be set by config or request
107 * @param string $section name of config section in
108 * $GLOBALS['cfg'][$section] for plugin
109 * @param string $opt name of option
111 * @return string html input tag option 'checked'
113 function PMA_pluginCheckboxCheck($section, $opt)
115 // If the form is being repopulated using $_GET data, that is priority
116 if (isset($_GET[$opt])
117 || ! isset($_GET['repopulate'])
118 && ((! empty($GLOBALS['timeout_passed']) && isset($_REQUEST[$opt]))
119 || ! empty($GLOBALS['cfg'][$section][$opt]))
121 return ' checked="checked"';
123 return '';
127 * Returns default value for option $opt
129 * @param string $section name of config section in
130 * $GLOBALS['cfg'][$section] for plugin
131 * @param string $opt name of option
133 * @return string default value for option $opt
135 function PMA_pluginGetDefault($section, $opt)
137 if (isset($_GET[$opt])) {
138 // If the form is being repopulated using $_GET data, that is priority
139 return htmlspecialchars($_GET[$opt]);
142 if (isset($GLOBALS['timeout_passed'])
143 && $GLOBALS['timeout_passed']
144 && isset($_REQUEST[$opt])
146 return htmlspecialchars($_REQUEST[$opt]);
149 if (!isset($GLOBALS['cfg'][$section][$opt])) {
150 return '';
153 $matches = array();
154 /* Possibly replace localised texts */
155 if (!preg_match_all(
156 '/(str[A-Z][A-Za-z0-9]*)/',
157 $GLOBALS['cfg'][$section][$opt],
158 $matches
159 )) {
160 return htmlspecialchars($GLOBALS['cfg'][$section][$opt]);
163 $val = $GLOBALS['cfg'][$section][$opt];
164 foreach ($matches[0] as $match) {
165 if (isset($GLOBALS[$match])) {
166 $val = str_replace($match, $GLOBALS[$match], $val);
169 return htmlspecialchars($val);
173 * Returns html select form element for plugin choice
174 * and hidden fields denoting whether each plugin must be exported as a file
176 * @param string $section name of config section in
177 * $GLOBALS['cfg'][$section] for plugin
178 * @param string $name name of select element
179 * @param array &$list array with plugin instances
180 * @param string $cfgname name of config value, if none same as $name
182 * @return string html select tag
184 function PMA_pluginGetChoice($section, $name, &$list, $cfgname = null)
186 if (! isset($cfgname)) {
187 $cfgname = $name;
189 $ret = '<select id="plugins" name="' . $name . '">';
190 $default = PMA_pluginGetDefault($section, $cfgname);
191 foreach ($list as $plugin) {
192 $plugin_name = /*overload*/mb_strtolower(
193 /*overload*/mb_substr(
194 get_class($plugin),
195 /*overload*/mb_strlen($section)
198 $ret .= '<option';
199 // If the form is being repopulated using $_GET data, that is priority
200 if (isset($_GET[$name])
201 && $plugin_name == $_GET[$name]
202 || ! isset($_GET[$name])
203 && $plugin_name == $default
205 $ret .= ' selected="selected"';
208 $properties = $plugin->getProperties();
209 $text = null;
210 if ($properties != null) {
211 $text = $properties->getText();
213 $ret .= ' value="' . $plugin_name . '">'
214 . PMA_getString($text)
215 . '</option>' . "\n";
217 $ret .= '</select>' . "\n";
219 // Whether each plugin has to be saved as a file
220 foreach ($list as $plugin) {
221 $plugin_name = /*overload*/mb_strtolower(
222 /*overload*/mb_substr(
223 get_class($plugin),
224 /*overload*/mb_strlen($section)
227 $ret .= '<input type="hidden" id="force_file_' . $plugin_name
228 . '" value="';
229 $properties = $plugin->getProperties();
230 if (! strcmp($section, 'Import')
231 || ($properties != null && $properties->getForceFile() != null)
233 $ret .= 'true';
234 } else {
235 $ret .= 'false';
237 $ret .= '" />' . "\n";
240 return $ret;
244 * Returns single option in a list element
246 * @param string $section name of config section in
247 * $GLOBALS['cfg'][$section] for plugin
248 * @param string $plugin_name unique plugin name
249 * @param array &$propertyGroup options property main group instance
250 * @param boolean $is_subgroup if this group is a subgroup
252 * @return string table row with option
254 function PMA_pluginGetOneOption(
255 $section,
256 $plugin_name,
257 &$propertyGroup,
258 $is_subgroup = false
260 $ret = "\n";
262 if (! $is_subgroup) {
263 // for subgroup headers
264 if (/*overload*/mb_strpos(get_class($propertyGroup), "PropertyItem")) {
265 $properties = array($propertyGroup);
266 } else {
267 // for main groups
268 $ret .= '<div class="export_sub_options" id="' . $plugin_name . '_'
269 . $propertyGroup->getName() . '">';
271 if (method_exists($propertyGroup, 'getText')) {
272 $text = $propertyGroup->getText();
275 if ($text != null) {
276 $ret .= '<h4>' . PMA_getString($text) . '</h4>';
278 $ret .= '<ul>';
282 if (! isset($properties)) {
283 $not_subgroup_header = true;
284 if (method_exists($propertyGroup, 'getProperties')) {
285 $properties = $propertyGroup->getProperties();
289 if (isset($properties)) {
290 /** @var OptionsPropertySubgroup $propertyItem */
291 foreach ($properties as $propertyItem) {
292 $property_class = get_class($propertyItem);
293 // if the property is a subgroup, we deal with it recursively
294 if (/*overload*/mb_strpos($property_class, "Subgroup")) {
295 // for subgroups
296 // each subgroup can have a header, which may also be a form element
297 /** @var OptionsPropertyItem $subgroup_header */
298 $subgroup_header = $propertyItem->getSubgroupHeader();
299 if (isset($subgroup_header)) {
300 $ret .= PMA_pluginGetOneOption(
301 $section,
302 $plugin_name,
303 $subgroup_header
307 $ret .= '<li class="subgroup"><ul';
308 if (isset($subgroup_header)) {
309 $ret .= ' id="ul_' . $subgroup_header->getName() . '">';
310 } else {
311 $ret .= '>';
314 $ret .= PMA_pluginGetOneOption(
315 $section,
316 $plugin_name,
317 $propertyItem,
318 true
320 continue;
323 // single property item
324 $ret .= PMA_getHtmlForProperty(
325 $section, $plugin_name, $propertyItem
330 if ($is_subgroup) {
331 // end subgroup
332 $ret .= '</ul></li>';
333 } else {
334 // end main group
335 if (! empty($not_subgroup_header)) {
336 $ret .= '</ul></div>';
340 if (method_exists($propertyGroup, "getDoc")) {
341 $doc = $propertyGroup->getDoc();
342 if ($doc != null) {
343 if (count($doc) == 3) {
344 $ret .= PMA_Util::showMySQLDocu(
345 $doc[1],
346 false,
347 $doc[2]
349 } elseif (count($doc) == 1) {
350 $ret .= PMA_Util::showDocu('faq', $doc[0]);
351 } else {
352 $ret .= PMA_Util::showMySQLDocu(
353 $doc[1]
359 // Close the list element after $doc link is displayed
360 if (isset($property_class)) {
361 if ($property_class == 'BoolPropertyItem'
362 || $property_class == 'MessageOnlyPropertyItem'
363 || $property_class == 'SelectPropertyItem'
364 || $property_class == 'TextPropertyItem'
366 $ret .= '</li>';
369 $ret .= "\n";
370 return $ret;
374 * Get HTML for properties items
376 * @param string $section name of config section in
377 * $GLOBALS['cfg'][$section] for plugin
378 * @param string $plugin_name unique plugin name
379 * @param OptionsPropertyItem $propertyItem Property item
381 * @return string
383 function PMA_getHtmlForProperty(
384 $section, $plugin_name, $propertyItem
386 $ret = null;
387 $property_class = get_class($propertyItem);
388 switch ($property_class) {
389 case "BoolPropertyItem":
390 $ret .= '<li>' . "\n";
391 $ret .= '<input type="checkbox" name="' . $plugin_name . '_'
392 . $propertyItem->getName() . '"'
393 . ' value="something" id="checkbox_' . $plugin_name . '_'
394 . $propertyItem->getName() . '"'
395 . ' '
396 . PMA_pluginCheckboxCheck(
397 $section,
398 $plugin_name . '_' . $propertyItem->getName()
401 if ($propertyItem->getForce() != null) {
402 // Same code is also few lines lower, update both if needed
403 $ret .= ' onclick="if (!this.checked &amp;&amp; '
404 . '(!document.getElementById(\'checkbox_' . $plugin_name
405 . '_' . $propertyItem->getForce() . '\') '
406 . '|| !document.getElementById(\'checkbox_'
407 . $plugin_name . '_' . $propertyItem->getForce()
408 . '\').checked)) '
409 . 'return false; else return true;"';
411 $ret .= ' />';
412 $ret .= '<label for="checkbox_' . $plugin_name . '_'
413 . $propertyItem->getName() . '">'
414 . PMA_getString($propertyItem->getText()) . '</label>';
415 break;
416 case "DocPropertyItem":
417 echo "DocPropertyItem";
418 break;
419 case "HiddenPropertyItem":
420 $ret .= '<li><input type="hidden" name="' . $plugin_name . '_'
421 . $propertyItem->getName() . '"'
422 . ' value="' . PMA_pluginGetDefault(
423 $section,
424 $plugin_name . '_' . $propertyItem->getName()
426 . '"' . ' /></li>';
427 break;
428 case "MessageOnlyPropertyItem":
429 $ret .= '<li>' . "\n";
430 $ret .= '<p>' . PMA_getString($propertyItem->getText()) . '</p>';
431 break;
432 case "RadioPropertyItem":
433 $default = PMA_pluginGetDefault(
434 $section,
435 $plugin_name . '_' . $propertyItem->getName()
437 foreach ($propertyItem->getValues() as $key => $val) {
438 $ret .= '<li><input type="radio" name="' . $plugin_name
439 . '_' . $propertyItem->getName() . '" value="' . $key
440 . '" id="radio_' . $plugin_name . '_'
441 . $propertyItem->getName() . '_' . $key . '"';
442 if ($key == $default) {
443 $ret .= ' checked="checked"';
445 $ret .= ' />' . '<label for="radio_' . $plugin_name . '_'
446 . $propertyItem->getName() . '_' . $key . '">'
447 . PMA_getString($val) . '</label></li>';
449 break;
450 case "SelectPropertyItem":
451 $ret .= '<li>' . "\n";
452 $ret .= '<label for="select_' . $plugin_name . '_'
453 . $propertyItem->getName() . '" class="desc">'
454 . PMA_getString($propertyItem->getText()) . '</label>';
455 $ret .= '<select name="' . $plugin_name . '_'
456 . $propertyItem->getName() . '"'
457 . ' id="select_' . $plugin_name . '_'
458 . $propertyItem->getName() . '">';
459 $default = PMA_pluginGetDefault(
460 $section,
461 $plugin_name . '_' . $propertyItem->getName()
463 foreach ($propertyItem->getValues() as $key => $val) {
464 $ret .= '<option value="' . $key . '"';
465 if ($key == $default) {
466 $ret .= ' selected="selected"';
468 $ret .= '>' . PMA_getString($val) . '</option>';
470 $ret .= '</select>';
471 break;
472 case "TextPropertyItem":
473 case "NumberPropertyItem":
474 $ret .= '<li>' . "\n";
475 $ret .= '<label for="text_' . $plugin_name . '_'
476 . $propertyItem->getName() . '" class="desc">'
477 . PMA_getString($propertyItem->getText()) . '</label>';
478 $ret .= '<input type="text" name="' . $plugin_name . '_'
479 . $propertyItem->getName() . '"'
480 . ' value="' . PMA_pluginGetDefault(
481 $section,
482 $plugin_name . '_' . $propertyItem->getName()
483 ) . '"'
484 . ' id="text_' . $plugin_name . '_'
485 . $propertyItem->getName() . '"'
486 . ($propertyItem->getSize() != null
487 ? ' size="' . $propertyItem->getSize() . '"'
488 : '')
489 . ($propertyItem->getLen() != null
490 ? ' maxlength="' . $propertyItem->getLen() . '"'
491 : '')
492 . ' />';
493 break;
494 default:
495 break;
497 return $ret;
501 * Returns html div with editable options for plugin
503 * @param string $section name of config section in $GLOBALS['cfg'][$section]
504 * @param array &$list array with plugin instances
506 * @return string html fieldset with plugin options
508 function PMA_pluginGetOptions($section, &$list)
510 $ret = '';
511 // Options for plugins that support them
512 foreach ($list as $plugin) {
513 $properties = $plugin->getProperties();
514 if ($properties != null) {
515 $text = $properties->getText();
516 $options = $properties->getOptions();
519 $plugin_name = /*overload*/mb_strtolower(
520 /*overload*/mb_substr(
521 get_class($plugin),
522 /*overload*/mb_strlen($section)
525 $ret .= '<div id="' . $plugin_name
526 . '_options" class="format_specific_options">';
527 $ret .= '<h3>' . PMA_getString($text) . '</h3>';
529 $no_options = true;
530 if ($options != null && count($options) > 0) {
531 foreach ($options->getProperties()
532 as $propertyMainGroup
534 // check for hidden properties
535 $no_options = true;
536 foreach ($propertyMainGroup->getProperties() as $propertyItem) {
537 if (strcmp("HiddenPropertyItem", get_class($propertyItem))) {
538 $no_options = false;
539 break;
543 $ret .= PMA_pluginGetOneOption(
544 $section,
545 $plugin_name,
546 $propertyMainGroup
551 if ($no_options) {
552 $ret .= '<p>' . __('This format has no options') . '</p>';
554 $ret .= '</div>';
556 return $ret;