FormDisplay.class.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Form management class, displays and processes forms
  5. *
  6. * Explanation of used terms:
  7. * o work_path - original field path, eg. Servers/4/verbose
  8. * o system_path - work_path modified so that it points to the first server,
  9. * eg. Servers/1/verbose
  10. * o translated_path - work_path modified for HTML field name, a path with
  11. * slashes changed to hyphens, eg. Servers-4-verbose
  12. *
  13. * @package PhpMyAdmin
  14. */
  15. /**
  16. * Core libraries.
  17. */
  18. require_once './libraries/config/FormDisplay.tpl.php';
  19. require_once './libraries/config/Validator.class.php';
  20. require_once './libraries/js_escape.lib.php';
  21. /**
  22. * Form management class, displays and processes forms
  23. *
  24. * @package PhpMyAdmin
  25. */
  26. class FormDisplay
  27. {
  28. /**
  29. * ConfigFile instance
  30. * @var ConfigFile
  31. */
  32. private $_configFile;
  33. /**
  34. * Form list
  35. * @var Form[]
  36. */
  37. private $_forms = array();
  38. /**
  39. * Stores validation errors, indexed by paths
  40. * [ Form_name ] is an array of form errors
  41. * [path] is a string storing error associated with single field
  42. * @var array
  43. */
  44. private $_errors = array();
  45. /**
  46. * Paths changed so that they can be used as HTML ids, indexed by paths
  47. * @var array
  48. */
  49. private $_translatedPaths = array();
  50. /**
  51. * Server paths change indexes so we define maps from current server
  52. * path to the first one, indexed by work path
  53. * @var array
  54. */
  55. private $_systemPaths = array();
  56. /**
  57. * Language strings which will be sent to PMA_messages JS variable
  58. * Will be looked up in $GLOBALS: str{value} or strSetup{value}
  59. * @var array
  60. */
  61. private $_jsLangStrings = array();
  62. /**
  63. * Tells whether forms have been validated
  64. * @var bool
  65. */
  66. private $_isValidated = true;
  67. /**
  68. * Dictionary with user preferences keys
  69. * @var array
  70. */
  71. private $_userprefsKeys;
  72. /**
  73. * Dictionary with disallowed user preferences keys
  74. * @var array
  75. */
  76. private $_userprefsDisallow;
  77. /**
  78. * Constructor
  79. *
  80. * @param ConfigFile $cf Config file instance
  81. */
  82. public function __construct(ConfigFile $cf)
  83. {
  84. $this->_jsLangStrings = array(
  85. 'error_nan_p' => __('Not a positive number!'),
  86. 'error_nan_nneg' => __('Not a non-negative number!'),
  87. 'error_incorrect_port' => __('Not a valid port number!'),
  88. 'error_invalid_value' => __('Incorrect value!'),
  89. 'error_value_lte' => __('Value must be equal or lower than %s!'));
  90. $this->_configFile = $cf;
  91. // initialize validators
  92. PMA_Validator::getValidators($this->_configFile);
  93. }
  94. /**
  95. * Returns {@link ConfigFile} associated with this instance
  96. *
  97. * @return ConfigFile
  98. */
  99. public function getConfigFile()
  100. {
  101. return $this->_configFile;
  102. }
  103. /**
  104. * Registers form in form manager
  105. *
  106. * @param string $form_name Form name
  107. * @param array $form Form data
  108. * @param int $server_id 0 if new server, validation; >= 1 if editing a server
  109. *
  110. * @return void
  111. */
  112. public function registerForm($form_name, array $form, $server_id = null)
  113. {
  114. $this->_forms[$form_name] = new Form(
  115. $form_name, $form, $this->_configFile, $server_id
  116. );
  117. $this->_isValidated = false;
  118. foreach ($this->_forms[$form_name]->fields as $path) {
  119. $work_path = $server_id === null
  120. ? $path
  121. : str_replace('Servers/1/', "Servers/$server_id/", $path);
  122. $this->_systemPaths[$work_path] = $path;
  123. $this->_translatedPaths[$work_path] = str_replace('/', '-', $work_path);
  124. }
  125. }
  126. /**
  127. * Processes forms, returns true on successful save
  128. *
  129. * @param bool $allow_partial_save allows for partial form saving
  130. * on failed validation
  131. * @param bool $check_form_submit whether check for $_POST['submit_save']
  132. *
  133. * @return boolean whether processing was successful
  134. */
  135. public function process($allow_partial_save = true, $check_form_submit = true)
  136. {
  137. if ($check_form_submit && !isset($_POST['submit_save'])) {
  138. return false;
  139. }
  140. // save forms
  141. if (count($this->_forms) > 0) {
  142. return $this->save(array_keys($this->_forms), $allow_partial_save);
  143. }
  144. return false;
  145. }
  146. /**
  147. * Runs validation for all registered forms
  148. *
  149. * @return void
  150. */
  151. private function _validate()
  152. {
  153. if ($this->_isValidated) {
  154. return;
  155. }
  156. $paths = array();
  157. $values = array();
  158. foreach ($this->_forms as $form) {
  159. /* @var $form Form */
  160. $paths[] = $form->name;
  161. // collect values and paths
  162. foreach ($form->fields as $path) {
  163. $work_path = array_search($path, $this->_systemPaths);
  164. $values[$path] = $this->_configFile->getValue($work_path);
  165. $paths[] = $path;
  166. }
  167. }
  168. // run validation
  169. $errors = PMA_Validator::validate(
  170. $this->_configFile, $paths, $values, false
  171. );
  172. // change error keys from canonical paths to work paths
  173. if (is_array($errors) && count($errors) > 0) {
  174. $this->_errors = array();
  175. foreach ($errors as $path => $error_list) {
  176. $work_path = array_search($path, $this->_systemPaths);
  177. // field error
  178. if (! $work_path) {
  179. // form error, fix path
  180. $work_path = $path;
  181. }
  182. $this->_errors[$work_path] = $error_list;
  183. }
  184. }
  185. $this->_isValidated = true;
  186. }
  187. /**
  188. * Outputs HTML for forms
  189. *
  190. * @param bool $tabbed_form if true, use a form with tabs
  191. * @param bool $show_restore_default whether show "restore default" button
  192. * besides the input field
  193. *
  194. * @return void
  195. */
  196. public function display($tabbed_form = false, $show_restore_default = false)
  197. {
  198. static $js_lang_sent = false;
  199. $js = array();
  200. $js_default = array();
  201. $tabbed_form = $tabbed_form && (count($this->_forms) > 1);
  202. $validators = PMA_Validator::getValidators($this->_configFile);
  203. PMA_displayFormTop();
  204. if ($tabbed_form) {
  205. $tabs = array();
  206. foreach ($this->_forms as $form) {
  207. $tabs[$form->name] = PMA_lang("Form_$form->name");
  208. }
  209. PMA_displayTabsTop($tabs);
  210. }
  211. // validate only when we aren't displaying a "new server" form
  212. $is_new_server = false;
  213. foreach ($this->_forms as $form) {
  214. /* @var $form Form */
  215. if ($form->index === 0) {
  216. $is_new_server = true;
  217. break;
  218. }
  219. }
  220. if (! $is_new_server) {
  221. $this->_validate();
  222. }
  223. // user preferences
  224. $this->_loadUserprefsInfo();
  225. // display forms
  226. foreach ($this->_forms as $form) {
  227. /* @var $form Form */
  228. $form_desc = isset($GLOBALS["strConfigForm_{$form->name}_desc"])
  229. ? PMA_lang("Form_{$form->name}_desc")
  230. : '';
  231. $form_errors = isset($this->_errors[$form->name])
  232. ? $this->_errors[$form->name] : null;
  233. PMA_displayFieldsetTop(
  234. PMA_lang("Form_$form->name"),
  235. $form_desc,
  236. $form_errors,
  237. array('id' => $form->name)
  238. );
  239. foreach ($form->fields as $field => $path) {
  240. $work_path = array_search($path, $this->_systemPaths);
  241. $translated_path = $this->_translatedPaths[$work_path];
  242. // always true/false for user preferences display
  243. // otherwise null
  244. $userprefs_allow = isset($this->_userprefsKeys[$path])
  245. ? !isset($this->_userprefsDisallow[$path])
  246. : null;
  247. // display input
  248. $this->_displayFieldInput(
  249. $form,
  250. $field,
  251. $path,
  252. $work_path,
  253. $translated_path,
  254. $show_restore_default,
  255. $userprefs_allow,
  256. $js_default
  257. );
  258. // register JS validators for this field
  259. if (isset($validators[$path])) {
  260. PMA_addJsValidate($translated_path, $validators[$path], $js);
  261. }
  262. }
  263. PMA_displayFieldsetBottom();
  264. }
  265. if ($tabbed_form) {
  266. PMA_displayTabsBottom();
  267. }
  268. PMA_displayFormBottom();
  269. // if not already done, send strings used for valdiation to JavaScript
  270. if (! $js_lang_sent) {
  271. $js_lang_sent = true;
  272. $js_lang = array();
  273. foreach ($this->_jsLangStrings as $strName => $strValue) {
  274. $js_lang[] = "'$strName': '" . PMA_jsFormat($strValue, false) . '\'';
  275. }
  276. $js[] = "$.extend(PMA_messages, {\n\t"
  277. . implode(",\n\t", $js_lang) . '})';
  278. }
  279. $js[] = "$.extend(defaultValues, {\n\t"
  280. . implode(",\n\t", $js_default) . '})';
  281. PMA_displayJavascript($js);
  282. }
  283. /**
  284. * Prepares data for input field display and outputs HTML code
  285. *
  286. * @param Form $form Form object
  287. * @param string $field field name as it appears in $form
  288. * @param string $system_path field path, eg. Servers/1/verbose
  289. * @param string $work_path work path, eg. Servers/4/verbose
  290. * @param string $translated_path work path changed so that it can be
  291. * used as XHTML id
  292. * @param bool $show_restore_default whether show "restore default" button
  293. * besides the input field
  294. * @param mixed $userprefs_allow whether user preferences are enabled
  295. * for this field (null - no support,
  296. * true/false - enabled/disabled)
  297. * @param array &$js_default array which stores JavaScript code
  298. * to be displayed
  299. *
  300. * @return void
  301. */
  302. private function _displayFieldInput(
  303. Form $form, $field, $system_path, $work_path,
  304. $translated_path, $show_restore_default, $userprefs_allow, array &$js_default
  305. ) {
  306. $name = PMA_langName($system_path);
  307. $description = PMA_langName($system_path, 'desc', '');
  308. $value = $this->_configFile->get($work_path);
  309. $value_default = $this->_configFile->getDefault($system_path);
  310. $value_is_default = false;
  311. if ($value === null || $value === $value_default) {
  312. $value = $value_default;
  313. $value_is_default = true;
  314. }
  315. $opts = array(
  316. 'doc' => $this->getDocLink($system_path),
  317. 'show_restore_default' => $show_restore_default,
  318. 'userprefs_allow' => $userprefs_allow,
  319. 'userprefs_comment' => PMA_langName($system_path, 'cmt', ''));
  320. if (isset($form->default[$system_path])) {
  321. $opts['setvalue'] = $form->default[$system_path];
  322. }
  323. if (isset($this->_errors[$work_path])) {
  324. $opts['errors'] = $this->_errors[$work_path];
  325. }
  326. switch ($form->getOptionType($field)) {
  327. case 'string':
  328. $type = 'text';
  329. break;
  330. case 'short_string':
  331. $type = 'short_text';
  332. break;
  333. case 'double':
  334. case 'integer':
  335. $type = 'number_text';
  336. break;
  337. case 'boolean':
  338. $type = 'checkbox';
  339. break;
  340. case 'select':
  341. $type = 'select';
  342. $opts['values'] = $form->getOptionValueList($form->fields[$field]);
  343. break;
  344. case 'array':
  345. $type = 'list';
  346. $value = (array) $value;
  347. $value_default = (array) $value_default;
  348. break;
  349. case 'group':
  350. // :group:end is changed to :group:end:{unique id} in Form class
  351. if (substr($field, 7, 4) != 'end:') {
  352. PMA_displayGroupHeader(substr($field, 7));
  353. } else {
  354. PMA_displayGroupFooter();
  355. }
  356. return;
  357. case 'NULL':
  358. trigger_error("Field $system_path has no type", E_USER_WARNING);
  359. return;
  360. }
  361. // detect password fields
  362. if ($type === 'text'
  363. && substr($translated_path, -9) === '-password'
  364. ) {
  365. $type = 'password';
  366. }
  367. // TrustedProxies requires changes before displaying
  368. if ($system_path == 'TrustedProxies') {
  369. foreach ($value as $ip => &$v) {
  370. if (!preg_match('/^-\d+$/', $ip)) {
  371. $v = $ip . ': ' . $v;
  372. }
  373. }
  374. }
  375. $this->_setComments($system_path, $opts);
  376. // send default value to form's JS
  377. $js_line = '\'' . $translated_path . '\': ';
  378. switch ($type) {
  379. case 'text':
  380. case 'short_text':
  381. case 'number_text':
  382. case 'password':
  383. $js_line .= '\'' . PMA_escapeJsString($value_default) . '\'';
  384. break;
  385. case 'checkbox':
  386. $js_line .= $value_default ? 'true' : 'false';
  387. break;
  388. case 'select':
  389. $value_default_js = is_bool($value_default)
  390. ? (int) $value_default
  391. : $value_default;
  392. $js_line .= '[\'' . PMA_escapeJsString($value_default_js) . '\']';
  393. break;
  394. case 'list':
  395. $js_line .= '\'' . PMA_escapeJsString(implode("\n", $value_default))
  396. . '\'';
  397. break;
  398. }
  399. $js_default[] = $js_line;
  400. PMA_displayInput(
  401. $translated_path, $name, $type, $value,
  402. $description, $value_is_default, $opts
  403. );
  404. }
  405. /**
  406. * Displays errors
  407. *
  408. * @return void
  409. */
  410. public function displayErrors()
  411. {
  412. $this->_validate();
  413. if (count($this->_errors) == 0) {
  414. return;
  415. }
  416. foreach ($this->_errors as $system_path => $error_list) {
  417. if (isset($this->_systemPaths[$system_path])) {
  418. $path = $this->_systemPaths[$system_path];
  419. $name = PMA_langName($path);
  420. } else {
  421. $name = $GLOBALS["strConfigForm_$system_path"];
  422. }
  423. PMA_displayErrors($name, $error_list);
  424. }
  425. }
  426. /**
  427. * Reverts erroneous fields to their default values
  428. *
  429. * @return void
  430. */
  431. public function fixErrors()
  432. {
  433. $this->_validate();
  434. if (count($this->_errors) == 0) {
  435. return;
  436. }
  437. $cf = $this->_configFile;
  438. foreach (array_keys($this->_errors) as $work_path) {
  439. if (!isset($this->_systemPaths[$work_path])) {
  440. continue;
  441. }
  442. $canonical_path = $this->_systemPaths[$work_path];
  443. $cf->set($work_path, $cf->getDefault($canonical_path));
  444. }
  445. }
  446. /**
  447. * Validates select field and casts $value to correct type
  448. *
  449. * @param string &$value Current value
  450. * @param array $allowed List of allowed values
  451. *
  452. * @return bool
  453. */
  454. private function _validateSelect(&$value, array $allowed)
  455. {
  456. $value_cmp = is_bool($value)
  457. ? (int) $value
  458. : $value;
  459. foreach ($allowed as $vk => $v) {
  460. // equality comparison only if both values are numeric or not numeric
  461. // (allows to skip 0 == 'string' equalling to true)
  462. // or identity (for string-string)
  463. if (($vk == $value && !(is_numeric($value_cmp) xor is_numeric($vk)))
  464. || $vk === $value
  465. ) {
  466. // keep boolean value as boolean
  467. if (!is_bool($value)) {
  468. settype($value, gettype($vk));
  469. }
  470. return true;
  471. }
  472. }
  473. return false;
  474. }
  475. /**
  476. * Validates and saves form data to session
  477. *
  478. * @param array|string $forms array of form names
  479. * @param bool $allow_partial_save allows for partial form saving on
  480. * failed validation
  481. *
  482. * @return boolean true on success (no errors and all saved)
  483. */
  484. public function save($forms, $allow_partial_save = true)
  485. {
  486. $result = true;
  487. $forms = (array) $forms;
  488. $values = array();
  489. $to_save = array();
  490. $is_setup_script = defined('PMA_SETUP');
  491. if ($is_setup_script) {
  492. $this->_loadUserprefsInfo();
  493. }
  494. $this->_errors = array();
  495. foreach ($forms as $form_name) {
  496. /* @var $form Form */
  497. if (isset($this->_forms[$form_name])) {
  498. $form = $this->_forms[$form_name];
  499. } else {
  500. continue;
  501. }
  502. // get current server id
  503. $change_index = $form->index === 0
  504. ? $this->_configFile->getServerCount() + 1
  505. : false;
  506. // grab POST values
  507. foreach ($form->fields as $field => $system_path) {
  508. $work_path = array_search($system_path, $this->_systemPaths);
  509. $key = $this->_translatedPaths[$work_path];
  510. $type = $form->getOptionType($field);
  511. // skip groups
  512. if ($type == 'group') {
  513. continue;
  514. }
  515. // ensure the value is set
  516. if (!isset($_POST[$key])) {
  517. // checkboxes aren't set by browsers if they're off
  518. if ($type == 'boolean') {
  519. $_POST[$key] = false;
  520. } else {
  521. $this->_errors[$form->name][] = sprintf(
  522. __('Missing data for %s'),
  523. '<i>' . PMA_langName($system_path) . '</i>'
  524. );
  525. $result = false;
  526. continue;
  527. }
  528. }
  529. // user preferences allow/disallow
  530. if ($is_setup_script
  531. && isset($this->_userprefsKeys[$system_path])
  532. ) {
  533. if (isset($this->_userprefsDisallow[$system_path])
  534. && isset($_POST[$key . '-userprefs-allow'])
  535. ) {
  536. unset($this->_userprefsDisallow[$system_path]);
  537. } else if (!isset($_POST[$key . '-userprefs-allow'])) {
  538. $this->_userprefsDisallow[$system_path] = true;
  539. }
  540. }
  541. // cast variables to correct type
  542. switch ($type) {
  543. case 'double':
  544. settype($_POST[$key], 'float');
  545. break;
  546. case 'boolean':
  547. case 'integer':
  548. if ($_POST[$key] !== '') {
  549. settype($_POST[$key], $type);
  550. }
  551. break;
  552. case 'select':
  553. $successfully_validated = $this->_validateSelect(
  554. $_POST[$key],
  555. $form->getOptionValueList($system_path)
  556. );
  557. if (! $successfully_validated) {
  558. $this->_errors[$work_path][] = __('Incorrect value!');
  559. $result = false;
  560. continue;
  561. }
  562. break;
  563. case 'string':
  564. case 'short_string':
  565. $_POST[$key] = trim($_POST[$key]);
  566. break;
  567. case 'array':
  568. // eliminate empty values and ensure we have an array
  569. $post_values = is_array($_POST[$key])
  570. ? $_POST[$key]
  571. : explode("\n", $_POST[$key]);
  572. $_POST[$key] = array();
  573. $this->_fillPostArrayParameters($post_values, $key);
  574. break;
  575. }
  576. // now we have value with proper type
  577. $values[$system_path] = $_POST[$key];
  578. if ($change_index !== false) {
  579. $work_path = str_replace(
  580. "Servers/$form->index/",
  581. "Servers/$change_index/", $work_path
  582. );
  583. }
  584. $to_save[$work_path] = $system_path;
  585. }
  586. }
  587. // save forms
  588. if (!$allow_partial_save && !empty($this->_errors)) {
  589. // don't look for non-critical errors
  590. $this->_validate();
  591. return $result;
  592. }
  593. foreach ($to_save as $work_path => $path) {
  594. // TrustedProxies requires changes before saving
  595. if ($path == 'TrustedProxies') {
  596. $proxies = array();
  597. $i = 0;
  598. foreach ($values[$path] as $value) {
  599. $matches = array();
  600. $match = preg_match(
  601. "/^(.+):(?:[ ]?)(\\w+)$/", $value, $matches
  602. );
  603. if ($match) {
  604. // correct 'IP: HTTP header' pair
  605. $ip = trim($matches[1]);
  606. $proxies[$ip] = trim($matches[2]);
  607. } else {
  608. // save also incorrect values
  609. $proxies["-$i"] = $value;
  610. $i++;
  611. }
  612. }
  613. $values[$path] = $proxies;
  614. }
  615. $this->_configFile->set($work_path, $values[$path], $path);
  616. }
  617. if ($is_setup_script) {
  618. $this->_configFile->set(
  619. 'UserprefsDisallow',
  620. array_keys($this->_userprefsDisallow)
  621. );
  622. }
  623. // don't look for non-critical errors
  624. $this->_validate();
  625. return $result;
  626. }
  627. /**
  628. * Tells whether form validation failed
  629. *
  630. * @return boolean
  631. */
  632. public function hasErrors()
  633. {
  634. return count($this->_errors) > 0;
  635. }
  636. /**
  637. * Returns link to documentation
  638. *
  639. * @param string $path Path to documentation
  640. *
  641. * @return string
  642. */
  643. public function getDocLink($path)
  644. {
  645. $test = substr($path, 0, 6);
  646. if ($test == 'Import' || $test == 'Export') {
  647. return '';
  648. }
  649. return PMA_Util::getDocuLink(
  650. 'config',
  651. 'cfg_' . $this->_getOptName($path)
  652. );
  653. }
  654. /**
  655. * Changes path so it can be used in URLs
  656. *
  657. * @param string $path Path
  658. *
  659. * @return string
  660. */
  661. private function _getOptName($path)
  662. {
  663. return str_replace(array('Servers/1/', '/'), array('Servers/', '_'), $path);
  664. }
  665. /**
  666. * Fills out {@link userprefs_keys} and {@link userprefs_disallow}
  667. *
  668. * @return void
  669. */
  670. private function _loadUserprefsInfo()
  671. {
  672. if ($this->_userprefsKeys !== null) {
  673. return;
  674. }
  675. $this->_userprefsKeys = array_flip(PMA_readUserprefsFieldNames());
  676. // read real config for user preferences display
  677. $userprefs_disallow = defined('PMA_SETUP')
  678. ? $this->_configFile->get('UserprefsDisallow', array())
  679. : $GLOBALS['cfg']['UserprefsDisallow'];
  680. $this->_userprefsDisallow = array_flip($userprefs_disallow);
  681. }
  682. /**
  683. * Sets field comments and warnings based on current environment
  684. *
  685. * @param string $system_path Path to settings
  686. * @param array &$opts Chosen options
  687. *
  688. * @return void
  689. */
  690. private function _setComments($system_path, array &$opts)
  691. {
  692. // RecodingEngine - mark unavailable types
  693. if ($system_path == 'RecodingEngine') {
  694. $comment = '';
  695. if (!function_exists('iconv')) {
  696. $opts['values']['iconv'] .= ' (' . __('unavailable') . ')';
  697. $comment = sprintf(
  698. __('"%s" requires %s extension'), 'iconv', 'iconv'
  699. );
  700. }
  701. if (!function_exists('recode_string')) {
  702. $opts['values']['recode'] .= ' (' . __('unavailable') . ')';
  703. $comment .= ($comment ? ", " : '') . sprintf(
  704. __('"%s" requires %s extension'),
  705. 'recode', 'recode'
  706. );
  707. }
  708. if (!function_exists('mb_convert_encoding')) {
  709. $opts['values']['mb'] .= ' (' . __('unavailable') . ')';
  710. $comment .= ($comment ? ", " : '') . sprintf(
  711. __('"%s" requires %s extension'),
  712. 'mb', 'mbstring'
  713. );
  714. }
  715. $opts['comment'] = $comment;
  716. $opts['comment_warning'] = true;
  717. }
  718. // ZipDump, GZipDump, BZipDump - check function availability
  719. if ($system_path == 'ZipDump'
  720. || $system_path == 'GZipDump'
  721. || $system_path == 'BZipDump'
  722. ) {
  723. $comment = '';
  724. $funcs = array(
  725. 'ZipDump' => array('zip_open', 'gzcompress'),
  726. 'GZipDump' => array('gzopen', 'gzencode'),
  727. 'BZipDump' => array('bzopen', 'bzcompress'));
  728. if (!function_exists($funcs[$system_path][0])) {
  729. $comment = sprintf(
  730. __('Compressed import will not work due to missing function %s.'),
  731. $funcs[$system_path][0]
  732. );
  733. }
  734. if (!function_exists($funcs[$system_path][1])) {
  735. $comment .= ($comment ? '; ' : '') . sprintf(
  736. __(
  737. 'Compressed export will not work due to missing function %s.'
  738. ),
  739. $funcs[$system_path][1]
  740. );
  741. }
  742. $opts['comment'] = $comment;
  743. $opts['comment_warning'] = true;
  744. }
  745. if (!defined('PMA_SETUP')) {
  746. if (($system_path == 'MaxDbList' || $system_path == 'MaxTableList'
  747. || $system_path == 'QueryHistoryMax')
  748. ) {
  749. $opts['comment'] = sprintf(
  750. __('maximum %s'), $GLOBALS['cfg'][$system_path]
  751. );
  752. }
  753. }
  754. }
  755. /**
  756. * Copy items of an array to $_POST variable
  757. *
  758. * @param array $post_values List of parameters
  759. * @param string $key Array key
  760. *
  761. * @return void
  762. */
  763. private function _fillPostArrayParameters($post_values, $key)
  764. {
  765. foreach ($post_values as $v) {
  766. $v = trim($v);
  767. if ($v !== '') {
  768. $_POST[$key][] = $v;
  769. }
  770. }
  771. }
  772. }
  773. ?>