diff options
Diffstat (limited to 'hugo/libraries/config')
| -rw-r--r-- | hugo/libraries/config/ConfigFile.class.php | 549 | ||||
| -rw-r--r-- | hugo/libraries/config/Form.class.php | 210 | ||||
| -rw-r--r-- | hugo/libraries/config/FormDisplay.class.php | 823 | ||||
| -rw-r--r-- | hugo/libraries/config/FormDisplay.tpl.php | 489 | ||||
| -rw-r--r-- | hugo/libraries/config/config_functions.lib.php | 55 | ||||
| -rw-r--r-- | hugo/libraries/config/messages.inc.php | 526 | ||||
| -rw-r--r-- | hugo/libraries/config/setup.forms.php | 369 | ||||
| -rw-r--r-- | hugo/libraries/config/user_preferences.forms.php | 272 | ||||
| -rw-r--r-- | hugo/libraries/config/validate.lib.php | 584 |
9 files changed, 3877 insertions, 0 deletions
diff --git a/hugo/libraries/config/ConfigFile.class.php b/hugo/libraries/config/ConfigFile.class.php new file mode 100644 index 0000000..238f0b0 --- /dev/null +++ b/hugo/libraries/config/ConfigFile.class.php @@ -0,0 +1,549 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Config file management + * + * @package PhpMyAdmin + */ + +/** + * Config file management class. + * Stores its data in $_SESSION + * + * @package PhpMyAdmin + */ +class ConfigFile +{ + /** + * Stores default PMA config from config.default.php + * @var array + */ + private $_cfg; + + /** + * Stores original PMA_Config object, not modified by user preferences + * @var PMA_Config + */ + private $_orgCfgObject; + + /** + * Stores allowed values for non-standard fields + * @var array + */ + private $_cfgDb; + + /** + * Keys which will be always written to config file + * @var array + */ + private $_persistKeys = array(); + + /** + * Changes keys while updating config in {@link updateWithGlobalConfig()} + * or reading by {@link getConfig()} or {@link getConfigArray()} + * @var array + */ + private $_cfgUpdateReadMapping = array(); + + /** + * Key filter for {@link set()} + * @var array|null + */ + private $_setFilter; + + /** + * Instance id (key in $_SESSION array, separate for each server - + * ConfigFile{server id}) + * @var string + */ + private $_id; + + /** + * Result for {@link _flattenArray()} + * @var array + */ + private $_flattenArrayResult; + + /** + * ConfigFile instance + * @var ConfigFile + */ + private static $_instance; + + /** + * Private constructor, use {@link getInstance()} + * + */ + private function __construct() + { + // load default config values + $cfg = &$this->_cfg; + include './libraries/config.default.php'; + $cfg['fontsize'] = '82%'; + + // create PMA_Config to read config.inc.php values + $this->_orgCfgObject = new PMA_Config(CONFIG_FILE); + + // load additional config information + $cfg_db = &$this->_cfgDb; + include './libraries/config.values.php'; + + // apply default values overrides + if (count($cfg_db['_overrides'])) { + foreach ($cfg_db['_overrides'] as $path => $value) { + PMA_arrayWrite($path, $cfg, $value); + } + } + + $this->_id = 'ConfigFile' . $GLOBALS['server']; + if (!isset($_SESSION[$this->_id])) { + $_SESSION[$this->_id] = array(); + } + } + + /** + * Returns class instance + * + * @return ConfigFile + */ + public static function getInstance() + { + if (is_null(self::$_instance)) { + self::$_instance = new ConfigFile(); + } + return self::$_instance; + } + + /** + * Returns PMA_Config without user preferences applied + * + * @return PMA_Config + */ + public function getOrgConfigObj() + { + return $this->_orgCfgObject; + } + + /** + * Sets names of config options which will be placed in config file even if + * they are set to their default values (use only full paths) + * + * @param array $keys + * + * @return void + */ + public function setPersistKeys($keys) + { + // checking key presence is much faster than searching so move values + // to keys + $this->_persistKeys = array_flip($keys); + } + + /** + * Returns flipped array set by {@link setPersistKeys()} + * + * @return array + */ + public function getPersistKeysMap() + { + return $this->_persistKeys; + } + + /** + * By default ConfigFile allows setting of all configuration keys, use + * this method to set up a filter on {@link set()} method + * + * @param array|null $keys array of allowed keys or null to remove filter + * + * @return void + */ + public function setAllowedKeys($keys) + { + if ($keys === null) { + $this->_setFilter = null; + return; + } + // checking key presence is much faster than searching so move values + // to keys + $this->_setFilter = array_flip($keys); + } + + /** + * Sets path mapping for updating config in + * {@link updateWithGlobalConfig()} or reading + * by {@link getConfig()} or {@link getConfigArray()} + * + * @param array $mapping + * + * @return void + */ + public function setCfgUpdateReadMapping(array $mapping) + { + $this->_cfgUpdateReadMapping = $mapping; + } + + /** + * Resets configuration data + * + * @return void + */ + public function resetConfigData() + { + $_SESSION[$this->_id] = array(); + } + + /** + * Sets configuration data (overrides old data) + * + * @param array $cfg + * + * @return void + */ + public function setConfigData(array $cfg) + { + $_SESSION[$this->_id] = $cfg; + } + + /** + * Sets config value + * + * @param string $path + * @param mixed $value + * @param string $canonical_path + * + * @return void + */ + public function set($path, $value, $canonical_path = null) + { + if ($canonical_path === null) { + $canonical_path = $this->getCanonicalPath($path); + } + // apply key whitelist + if ($this->_setFilter !== null + && ! isset($this->_setFilter[$canonical_path]) + ) { + return; + } + // remove if the path isn't protected and it's empty or has a default + // value + if (!isset($this->_persistKeys[$canonical_path])) { + $default_value = $this->getDefault($canonical_path); + // we need original config values not overwritten by user + // preferences to allow for overwriting options set in + // config.inc.php with default values + $instance_default_value = PMA_arrayRead( + $canonical_path, + $this->_orgCfgObject->settings + ); + if (($value === $default_value && (defined('PMA_SETUP') + || $instance_default_value === $default_value)) + || (empty($value) && empty($default_value) && (defined('PMA_SETUP'))) + ) { + PMA_arrayRemove($path, $_SESSION[$this->_id]); + return; + } + } + PMA_arrayWrite($path, $_SESSION[$this->_id], $value); + } + + /** + * Flattens multidimensional array, changes indices to paths + * (eg. 'key/subkey'). + * Used as array_walk() callback. + * + * @param mixed $value + * @param mixed $key + * @param mixed $prefix + * + * @return void + */ + private function _flattenArray($value, $key, $prefix) + { + // no recursion for numeric arrays + if (is_array($value) && !isset($value[0])) { + $prefix .= $key . '/'; + array_walk($value, array($this, '_flattenArray'), $prefix); + } else { + $this->_flattenArrayResult[$prefix . $key] = $value; + } + } + + /** + * Returns default config in a flattened array + * + * @return array + */ + public function getFlatDefaultConfig() + { + $this->_flattenArrayResult = array(); + array_walk($this->_cfg, array($this, '_flattenArray'), ''); + $flat_cfg = $this->_flattenArrayResult; + $this->_flattenArrayResult = null; + return $flat_cfg; + } + + /** + * Updates config with values read from given array + * (config will contain differences to defaults from config.defaults.php). + * + * @param array $cfg + * + * @return void + */ + public function updateWithGlobalConfig(array $cfg) + { + // load config array and flatten it + $this->_flattenArrayResult = array(); + array_walk($cfg, array($this, '_flattenArray'), ''); + $flat_cfg = $this->_flattenArrayResult; + $this->_flattenArrayResult = null; + + // save values map for translating a few user preferences paths, + // should be complemented by code reading from generated config + // to perform inverse mapping + foreach ($flat_cfg as $path => $value) { + if (isset($this->_cfgUpdateReadMapping[$path])) { + $path = $this->_cfgUpdateReadMapping[$path]; + } + $this->set($path, $value, $path); + } + } + + /** + * Returns config value or $default if it's not set + * + * @param string $path + * @param mixed $default + * + * @return mixed + */ + public function get($path, $default = null) + { + return PMA_arrayRead($path, $_SESSION[$this->_id], $default); + } + + /** + * Returns default config value or $default it it's not set ie. it doesn't + * exist in config.default.php ($cfg) and config.values.php + * ($_cfg_db['_overrides']) + * + * @param string $canonical_path + * @param mixed $default + * + * @return mixed + */ + public function getDefault($canonical_path, $default = null) + { + return PMA_arrayRead($canonical_path, $this->_cfg, $default); + } + + /** + * Returns config value, if it's not set uses the default one; returns + * $default if the path isn't set and doesn't contain a default value + * + * @param string $path + * @param mixed $default + * + * @return mixed + */ + public function getValue($path, $default = null) + { + $v = PMA_arrayRead($path, $_SESSION[$this->_id], null); + if ($v !== null) { + return $v; + } + $path = $this->getCanonicalPath($path); + return $this->getDefault($path, $default); + } + + /** + * Returns canonical path + * + * @param string $path + * + * @return string + */ + public function getCanonicalPath($path) + { + return preg_replace('#^Servers/([\d]+)/#', 'Servers/1/', $path); + } + + /** + * Returns config database entry for $path ($cfg_db in config_info.php) + * + * @param string $path + * @param mixed $default + * + * @return mixed + */ + public function getDbEntry($path, $default = null) + { + return PMA_arrayRead($path, $this->_cfgDb, $default); + } + + /** + * Returns server count + * + * @return int + */ + public function getServerCount() + { + return isset($_SESSION[$this->_id]['Servers']) + ? count($_SESSION[$this->_id]['Servers']) + : 0; + } + + /** + * Returns server list + * + * @return array|null + */ + public function getServers() + { + return isset($_SESSION[$this->_id]['Servers']) + ? $_SESSION[$this->_id]['Servers'] + : null; + } + + /** + * Returns DSN of given server + * + * @param integer $server + * + * @return string + */ + function getServerDSN($server) + { + if (!isset($_SESSION[$this->_id]['Servers'][$server])) { + return ''; + } + + $path = 'Servers/' . $server; + $dsn = $this->getValue("$path/extension") . '://'; + if ($this->getValue("$path/auth_type") == 'config') { + $dsn .= $this->getValue("$path/user"); + if (!$this->getValue("$path/nopassword")) { + $dsn .= ':***'; + } + $dsn .= '@'; + } + if ($this->getValue("$path/connect_type") == 'tcp') { + $dsn .= $this->getValue("$path/host"); + $port = $this->getValue("$path/port"); + if ($port) { + $dsn .= ':' . $port; + } + } else { + $dsn .= $this->getValue("$path/socket"); + } + return $dsn; + } + + /** + * Returns server name + * + * @param int $id + * + * @return string + */ + public function getServerName($id) + { + if (!isset($_SESSION[$this->_id]['Servers'][$id])) { + return ''; + } + $verbose = $this->get("Servers/$id/verbose"); + if (!empty($verbose)) { + return $verbose; + } + $host = $this->get("Servers/$id/host"); + return empty($host) ? 'localhost' : $host; + } + + /** + * Removes server + * + * @param int $server + * + * @return void + */ + public function removeServer($server) + { + if (!isset($_SESSION[$this->_id]['Servers'][$server])) { + return; + } + $last_server = $this->getServerCount(); + + for ($i = $server; $i < $last_server; $i++) { + $_SESSION[$this->_id]['Servers'][$i] + = $_SESSION[$this->_id]['Servers'][$i + 1]; + } + unset($_SESSION[$this->_id]['Servers'][$last_server]); + + if (isset($_SESSION[$this->_id]['ServerDefault']) + && $_SESSION[$this->_id]['ServerDefault'] >= 0 + ) { + unset($_SESSION[$this->_id]['ServerDefault']); + } + } + + /** + * Returns config file path, relative to phpMyAdmin's root path + * + * @return string + */ + public function getFilePath() + { + // Load paths + if (!defined('SETUP_CONFIG_FILE')) { + include_once './libraries/vendor_config.php'; + } + + return SETUP_CONFIG_FILE; + } + + /** + * Returns configuration array (full, multidimensional format) + * + * @return array + */ + public function getConfig() + { + $c = $_SESSION[$this->_id]; + foreach ($this->_cfgUpdateReadMapping as $map_to => $map_from) { + PMA_arrayWrite($map_to, $c, PMA_arrayRead($map_from, $c)); + PMA_arrayRemove($map_from, $c); + } + return $c; + } + + /** + * Returns configuration array (flat format) + * + * @return array + */ + public function getConfigArray() + { + $this->_flattenArrayResult = array(); + array_walk($_SESSION[$this->_id], array($this, '_flattenArray'), ''); + $c = $this->_flattenArrayResult; + $this->_flattenArrayResult = null; + + $persistKeys = array_diff( + array_keys($this->_persistKeys), + array_keys($c) + ); + foreach ($persistKeys as $k) { + $c[$k] = $this->getDefault($k); + } + + foreach ($this->_cfgUpdateReadMapping as $map_to => $map_from) { + if (!isset($c[$map_from])) { + continue; + } + $c[$map_to] = $c[$map_from]; + unset($c[$map_from]); + } + return $c; + } +} +?> diff --git a/hugo/libraries/config/Form.class.php b/hugo/libraries/config/Form.class.php new file mode 100644 index 0000000..d82e66b --- /dev/null +++ b/hugo/libraries/config/Form.class.php @@ -0,0 +1,210 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Form handling code. + * + * @package PhpMyAdmin + */ + +/** + * Base class for forms, loads default configuration options, checks allowed + * values etc. + * + * @package PhpMyAdmin + */ +class Form +{ + /** + * Form name + * @var string + */ + public $name; + + /** + * Arbitrary index, doesn't affect class' behavior + * @var int + */ + public $index; + + /** + * Form fields (paths), filled by {@link readFormPaths()}, indexed by field name + * @var array + */ + public $fields; + + /** + * Stores default values for some fields (eg. pmadb tables) + * @var array + */ + public $default; + + /** + * Caches field types, indexed by field names + * @var array + */ + private $_fieldsTypes; + + /** + * Constructor, reads default config values + * + * @param string $form_name + * @param array $form + * @param int $index arbitrary index, stored in Form::$index + */ + public function __construct($form_name, array $form, $index = null) + { + $this->index = $index; + $this->loadForm($form_name, $form); + } + + /** + * Returns type of given option + * + * @param string $option_name path or field name + * + * @return string|null one of: boolean, integer, double, string, select, array + */ + public function getOptionType($option_name) + { + $key = ltrim(substr($option_name, strrpos($option_name, '/')), '/'); + return isset($this->_fieldsTypes[$key]) + ? $this->_fieldsTypes[$key] + : null; + } + + /** + * Returns allowed values for select fields + * + * @param string $option_path + * + * @return array + */ + public function getOptionValueList($option_path) + { + $value = ConfigFile::getInstance()->getDbEntry($option_path); + if ($value === null) { + trigger_error("$option_path - select options not defined", E_USER_ERROR); + return array(); + } + if (!is_array($value)) { + trigger_error("$option_path - not a static value list", E_USER_ERROR); + return array(); + } + // convert array('#', 'a', 'b') to array('a', 'b') + if (isset($value[0]) && $value[0] === '#') { + // remove first element ('#') + array_shift($value); + } else { + // convert value list array('a', 'b') to array('a' => 'a', 'b' => 'b') + $has_string_keys = false; + $keys = array(); + for ($i = 0; $i < count($value); $i++) { + if (!isset($value[$i])) { + $has_string_keys = true; + break; + } + $keys[] = is_bool($value[$i]) ? (int)$value[$i] : $value[$i]; + } + if (!$has_string_keys) { + $value = array_combine($keys, $value); + } + } + + // $value has keys and value names, return it + return $value; + } + + /** + * array_walk callback function, reads path of form fields from + * array (see file comment in setup.forms.php or user_preferences.forms.inc) + * + * @param mixed $value + * @param mixed $key + * @param mixed $prefix + * + * @return void + */ + private function _readFormPathsCallback($value, $key, $prefix) + { + static $group_counter = 0; + + if (is_array($value)) { + $prefix .= $key . '/'; + array_walk($value, array($this, '_readFormPathsCallback'), $prefix); + } else { + if (!is_int($key)) { + $this->default[$prefix . $key] = $value; + $value = $key; + } + // add unique id to group ends + if ($value == ':group:end') { + $value .= ':' . $group_counter++; + } + $this->fields[] = $prefix . $value; + } + } + + /** + * Reads form paths to {@link $fields} + * + * @param array $form + * + * @return void + */ + protected function readFormPaths($form) + { + // flatten form fields' paths and save them to $fields + $this->fields = array(); + array_walk($form, array($this, '_readFormPathsCallback'), ''); + + // $this->fields is an array of the form: [0..n] => 'field path' + // change numeric indexes to contain field names (last part of the path) + $paths = $this->fields; + $this->fields = array(); + foreach ($paths as $path) { + $key = ltrim(substr($path, strrpos($path, '/')), '/'); + $this->fields[$key] = $path; + } + // now $this->fields is an array of the form: 'field name' => 'field path' + } + + /** + * Reads fields' types to $this->_fieldsTypes + * + * @return void + */ + protected function readTypes() + { + $cf = ConfigFile::getInstance(); + foreach ($this->fields as $name => $path) { + if (strpos($name, ':group:') === 0) { + $this->_fieldsTypes[$name] = 'group'; + continue; + } + $v = $cf->getDbEntry($path); + if ($v !== null) { + $type = is_array($v) ? 'select' : $v; + } else { + $type = gettype($cf->getDefault($path)); + } + $this->_fieldsTypes[$name] = $type; + } + } + + /** + * Reads form settings and prepares class to work with given subset of + * config file + * + * @param string $form_name + * @param array $form + * + * @return void + */ + public function loadForm($form_name, $form) + { + $this->name = $form_name; + $this->readFormPaths($form); + $this->readTypes(); + } +} +?> diff --git a/hugo/libraries/config/FormDisplay.class.php b/hugo/libraries/config/FormDisplay.class.php new file mode 100644 index 0000000..447a34b --- /dev/null +++ b/hugo/libraries/config/FormDisplay.class.php @@ -0,0 +1,823 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Form management class, displays and processes forms + * + * Explanation of used terms: + * o work_path - original field path, eg. Servers/4/verbose + * o system_path - work_path modified so that it points to the first server, + * eg. Servers/1/verbose + * o translated_path - work_path modified for HTML field name, a path with + * slashes changed to hyphens, eg. Servers-4-verbose + * + * @package PhpMyAdmin + */ + +/** + * Core libraries. + */ +require_once './libraries/config/FormDisplay.tpl.php'; +require_once './libraries/config/validate.lib.php'; +require_once './libraries/js_escape.lib.php'; + +/** + * Form management class, displays and processes forms + * + * @package PhpMyAdmin + */ +class FormDisplay +{ + /** + * Form list + * @var Form[] + */ + private $_forms = array(); + + /** + * Stores validation errors, indexed by paths + * [ Form_name ] is an array of form errors + * [path] is a string storing error associated with single field + * @var array + */ + private $_errors = array(); + + /** + * Paths changed so that they can be used as HTML ids, indexed by paths + * @var array + */ + private $_translatedPaths = array(); + + /** + * Server paths change indexes so we define maps from current server + * path to the first one, indexed by work path + * @var array + */ + private $_systemPaths = array(); + + /** + * Language strings which will be sent to PMA_messages JS variable + * Will be looked up in $GLOBALS: str{value} or strSetup{value} + * @var array + */ + private $_jsLangStrings = array(); + + /** + * Tells whether forms have been validated + * @var bool + */ + private $_isValidated = true; + + /** + * Dictionary with user preferences keys + * @var array + */ + private $_userprefsKeys; + + /** + * Dictionary with disallowed user preferences keys + * @var array + */ + private $_userprefsDisallow; + + /** + * Constructor + */ + public function __construct() + { + $this->_jsLangStrings = array( + 'error_nan_p' => __('Not a positive number'), + 'error_nan_nneg' => __('Not a non-negative number'), + 'error_incorrect_port' => __('Not a valid port number'), + 'error_invalid_value' => __('Incorrect value'), + 'error_value_lte' => __('Value must be equal or lower than %s')); + // initialize validators + PMA_config_get_validators(); + } + + /** + * Registers form in form manager + * + * @param string $form_name + * @param array $form + * @param int $server_id 0 if new server, validation; >= 1 if editing a server + * + * @return void + */ + public function registerForm($form_name, array $form, $server_id = null) + { + $this->_forms[$form_name] = new Form($form_name, $form, $server_id); + $this->_isValidated = false; + foreach ($this->_forms[$form_name]->fields as $path) { + $work_path = $server_id === null + ? $path + : str_replace('Servers/1/', "Servers/$server_id/", $path); + $this->_systemPaths[$work_path] = $path; + $this->_translatedPaths[$work_path] = str_replace('/', '-', $work_path); + } + } + + /** + * Processes forms, returns true on successful save + * + * @param bool $allow_partial_save allows for partial form saving + * on failed validation + * @param bool $check_form_submit whether check for $_POST['submit_save'] + * + * @return boolean whether processing was successful + */ + public function process($allow_partial_save = true, $check_form_submit = true) + { + if ($check_form_submit && !isset($_POST['submit_save'])) { + return false; + } + + // save forms + if (count($this->_forms) > 0) { + return $this->save(array_keys($this->_forms), $allow_partial_save); + } + return false; + } + + /** + * Runs validation for all registered forms + * + * @return void + */ + private function _validate() + { + if ($this->_isValidated) { + return; + } + + $cf = ConfigFile::getInstance(); + $paths = array(); + $values = array(); + foreach ($this->_forms as $form) { + /* @var $form Form */ + $paths[] = $form->name; + // collect values and paths + foreach ($form->fields as $path) { + $work_path = array_search($path, $this->_systemPaths); + $values[$path] = $cf->getValue($work_path); + $paths[] = $path; + } + } + + // run validation + $errors = PMA_config_validate($paths, $values, false); + + // change error keys from canonical paths to work paths + if (is_array($errors) && count($errors) > 0) { + $this->_errors = array(); + foreach ($errors as $path => $error_list) { + $work_path = array_search($path, $this->_systemPaths); + // field error + if (!$work_path) { + // form error, fix path + $work_path = $path; + } + $this->_errors[$work_path] = $error_list; + } + } + $this->_isValidated = true; + } + + /** + * Outputs HTML for forms + * + * @param bool $tabbed_form + * @param bool $show_restore_default whether show "restore default" button + * besides the input field + * + * @return void + */ + public function display($tabbed_form = false, $show_restore_default = false) + { + static $js_lang_sent = false; + + $js = array(); + $js_default = array(); + $tabbed_form = $tabbed_form && (count($this->_forms) > 1); + $validators = PMA_config_get_validators(); + + PMA_displayFormTop(); + + if ($tabbed_form) { + $tabs = array(); + foreach ($this->_forms as $form) { + $tabs[$form->name] = PMA_lang("Form_$form->name"); + } + PMA_displayTabsTop($tabs); + } + + // valdiate only when we aren't displaying a "new server" form + $is_new_server = false; + foreach ($this->_forms as $form) { + /* @var $form Form */ + if ($form->index === 0) { + $is_new_server = true; + break; + } + } + if (!$is_new_server) { + $this->_validate(); + } + + // user preferences + $this->_loadUserprefsInfo(); + + // display forms + foreach ($this->_forms as $form) { + /* @var $form Form */ + $form_desc = isset($GLOBALS["strConfigForm_{$form->name}_desc"]) + ? PMA_lang("Form_{$form->name}_desc") + : ''; + $form_errors = isset($this->_errors[$form->name]) + ? $this->_errors[$form->name] : null; + PMA_displayFieldsetTop( + PMA_lang("Form_$form->name"), + $form_desc, + $form_errors, + array('id' => $form->name) + ); + + foreach ($form->fields as $field => $path) { + $work_path = array_search($path, $this->_systemPaths); + $translated_path = $this->_translatedPaths[$work_path]; + // always true/false for user preferences display + // otherwise null + $userprefs_allow = isset($this->_userprefsKeys[$path]) + ? !isset($this->_userprefsDisallow[$path]) + : null; + // display input + $this->_displayFieldInput( + $form, + $field, + $path, + $work_path, + $translated_path, + $show_restore_default, + $userprefs_allow, + $js_default + ); + // register JS validators for this field + if (isset($validators[$path])) { + PMA_addJsValidate($translated_path, $validators[$path], $js); + } + } + PMA_displayFieldsetBottom(); + } + + if ($tabbed_form) { + PMA_displayTabsBottom(); + } + PMA_displayFormBottom(); + + // if not already done, send strings used for valdiation to JavaScript + if (!$js_lang_sent) { + $js_lang_sent = true; + $js_lang = array(); + foreach ($this->_jsLangStrings as $strName => $strValue) { + $js_lang[] = "'$strName': '" . PMA_jsFormat($strValue, false) . '\''; + } + $js[] = "$.extend(PMA_messages, {\n\t" . implode(",\n\t", $js_lang) . '})'; + } + + $js[] = "$.extend(defaultValues, {\n\t" . implode(",\n\t", $js_default) . '})'; + PMA_displayJavascript($js); + } + + /** + * Prepares data for input field display and outputs HTML code + * + * @param Form $form + * @param string $field field name as it appears in $form + * @param string $system_path field path, eg. Servers/1/verbose + * @param string $work_path work path, eg. Servers/4/verbose + * @param string $translated_path work path changed so that it can be + * used as XHTML id + * @param bool $show_restore_default whether show "restore default" button + * besides the input field + * @param mixed $userprefs_allow whether user preferences are enabled + * for this field (null - no support, + * true/false - enabled/disabled) + * @param array &$js_default array which stores JavaScript code + * to be displayed + * + * @return void + */ + private function _displayFieldInput( + Form $form, $field, $system_path, $work_path, + $translated_path, $show_restore_default, $userprefs_allow, array &$js_default + ) { + $name = PMA_lang_name($system_path); + $description = PMA_lang_name($system_path, 'desc', ''); + + $cf = ConfigFile::getInstance(); + $value = $cf->get($work_path); + $value_default = $cf->getDefault($system_path); + $value_is_default = false; + if ($value === null || $value === $value_default) { + $value = $value_default; + $value_is_default = true; + } + + $opts = array( + 'doc' => $this->getDocLink($system_path), + 'wiki' => $this->getWikiLink($system_path), + 'show_restore_default' => $show_restore_default, + 'userprefs_allow' => $userprefs_allow, + 'userprefs_comment' => PMA_lang_name($system_path, 'cmt', '')); + if (isset($form->default[$system_path])) { + $opts['setvalue'] = $form->default[$system_path]; + } + + if (isset($this->_errors[$work_path])) { + $opts['errors'] = $this->_errors[$work_path]; + } + switch ($form->getOptionType($field)) { + case 'string': + $type = 'text'; + break; + case 'short_string': + $type = 'short_text'; + break; + case 'double': + case 'integer': + $type = 'number_text'; + break; + case 'boolean': + $type = 'checkbox'; + break; + case 'select': + $type = 'select'; + $opts['values'] = $form->getOptionValueList($form->fields[$field]); + break; + case 'array': + $type = 'list'; + $value = (array) $value; + $value_default = (array) $value_default; + break; + case 'group': + // :group:end is changed to :group:end:{unique id} in Form class + if (substr($field, 7, 4) != 'end:') { + PMA_displayGroupHeader(substr($field, 7)); + } else { + PMA_displayGroupFooter(); + } + return; + case 'NULL': + trigger_error("Field $system_path has no type", E_USER_WARNING); + return; + } + + // TrustedProxies requires changes before displaying + if ($system_path == 'TrustedProxies') { + foreach ($value as $ip => &$v) { + if (!preg_match('/^-\d+$/', $ip)) { + $v = $ip . ': ' . $v; + } + } + } + $this->_setComments($system_path, $opts); + + // send default value to form's JS + $js_line = '\'' . $translated_path . '\': '; + switch ($type) { + case 'text': + case 'short_text': + case 'number_text': + $js_line .= '\'' . PMA_escapeJsString($value_default) . '\''; + break; + case 'checkbox': + $js_line .= $value_default ? 'true' : 'false'; + break; + case 'select': + $value_default_js = is_bool($value_default) + ? (int) $value_default + : $value_default; + $js_line .= '[\'' . PMA_escapeJsString($value_default_js) . '\']'; + break; + case 'list': + $js_line .= '\'' . PMA_escapeJsString(implode("\n", $value_default)) + . '\''; + break; + } + $js_default[] = $js_line; + + PMA_displayInput( + $translated_path, $name, $type, $value, + $description, $value_is_default, $opts + ); + } + + /** + * Displays errors + * + * @return void + */ + public function displayErrors() + { + $this->_validate(); + if (count($this->_errors) == 0) { + return; + } + + foreach ($this->_errors as $system_path => $error_list) { + if (isset($this->_systemPaths[$system_path])) { + $path = $this->_systemPaths[$system_path]; + $name = PMA_lang_name($path); + } else { + $name = $GLOBALS["strConfigForm_$system_path"]; + } + PMA_displayErrors($name, $error_list); + } + } + + /** + * Reverts erroneous fields to their default values + * + * @return void + */ + public function fixErrors() + { + $this->_validate(); + if (count($this->_errors) == 0) { + return; + } + + $cf = ConfigFile::getInstance(); + foreach (array_keys($this->_errors) as $work_path) { + if (!isset($this->_systemPaths[$work_path])) { + continue; + } + $canonical_path = $this->_systemPaths[$work_path]; + $cf->set($work_path, $cf->getDefault($canonical_path)); + } + } + + /** + * Validates select field and casts $value to correct type + * + * @param string $value + * @param array $allowed + * + * @return bool + */ + private function _validateSelect(&$value, array $allowed) + { + $value_cmp = is_bool($value) + ? (int) $value + : $value; + foreach ($allowed as $vk => $v) { + // equality comparison only if both values are numeric or not numeric + // (allows to skip 0 == 'string' equalling to true) + // or identity (for string-string) + if (($vk == $value && !(is_numeric($value_cmp) xor is_numeric($vk))) + || $vk === $value + ) { + // keep boolean value as boolean + if (!is_bool($value)) { + settype($value, gettype($vk)); + } + return true; + } + } + return false; + } + + /** + * Validates and saves form data to session + * + * @param array|string $forms array of form names + * @param bool $allow_partial_save allows for partial form saving on + * failed validation + * + * @return boolean true on success (no errors and all saved) + */ + public function save($forms, $allow_partial_save = true) + { + $result = true; + $cf = ConfigFile::getInstance(); + $forms = (array) $forms; + + $values = array(); + $to_save = array(); + $is_setup_script = defined('PMA_SETUP'); + if ($is_setup_script) { + $this->_loadUserprefsInfo(); + } + + $this->_errors = array(); + foreach ($forms as $form_name) { + /* @var $form Form */ + if (isset($this->_forms[$form_name])) { + $form = $this->_forms[$form_name]; + } else { + continue; + } + // get current server id + $change_index = $form->index === 0 + ? $cf->getServerCount() + 1 + : false; + // grab POST values + foreach ($form->fields as $field => $system_path) { + $work_path = array_search($system_path, $this->_systemPaths); + $key = $this->_translatedPaths[$work_path]; + $type = $form->getOptionType($field); + + // skip groups + if ($type == 'group') { + continue; + } + + // ensure the value is set + if (!isset($_POST[$key])) { + // checkboxes aren't set by browsers if they're off + if ($type == 'boolean') { + $_POST[$key] = false; + } else { + $this->_errors[$form->name][] = sprintf( + __('Missing data for %s'), + '<i>' . PMA_lang_name($system_path) . '</i>' + ); + $result = false; + continue; + } + } + + // user preferences allow/disallow + if ($is_setup_script + && isset($this->_userprefsKeys[$system_path]) + ) { + if (isset($this->_userprefsDisallow[$system_path]) + && isset($_POST[$key . '-userprefs-allow']) + ) { + unset($this->_userprefsDisallow[$system_path]); + } else if (!isset($_POST[$key . '-userprefs-allow'])) { + $this->_userprefsDisallow[$system_path] = true; + } + } + + // cast variables to correct type + switch ($type) { + case 'double': + settype($_POST[$key], 'float'); + break; + case 'boolean': + case 'integer': + if ($_POST[$key] !== '') { + settype($_POST[$key], $type); + } + break; + case 'select': + $successfully_validated = $this->_validateSelect( + $_POST[$key], + $form->getOptionValueList($system_path) + ); + if (! $successfully_validated) { + $this->_errors[$work_path][] = __('Incorrect value'); + $result = false; + continue; + } + break; + case 'string': + case 'short_string': + $_POST[$key] = trim($_POST[$key]); + break; + case 'array': + // eliminate empty values and ensure we have an array + $post_values = is_array($_POST[$key]) + ? $_POST[$key] + : explode("\n", $_POST[$key]); + $_POST[$key] = array(); + foreach ($post_values as $v) { + $v = trim($v); + if ($v !== '') { + $_POST[$key][] = $v; + } + } + break; + } + + // now we have value with proper type + $values[$system_path] = $_POST[$key]; + if ($change_index !== false) { + $work_path = str_replace( + "Servers/$form->index/", + "Servers/$change_index/", $work_path + ); + } + $to_save[$work_path] = $system_path; + } + } + + // save forms + if ($allow_partial_save || empty($this->_errors)) { + foreach ($to_save as $work_path => $path) { + // TrustedProxies requires changes before saving + if ($path == 'TrustedProxies') { + $proxies = array(); + $i = 0; + foreach ($values[$path] as $value) { + $matches = array(); + $match = preg_match( + "/^(.+):(?:[ ]?)(\\w+)$/", $value, $matches + ); + if ($match) { + // correct 'IP: HTTP header' pair + $ip = trim($matches[1]); + $proxies[$ip] = trim($matches[2]); + } else { + // save also incorrect values + $proxies["-$i"] = $value; + $i++; + } + } + $values[$path] = $proxies; + } + $cf->set($work_path, $values[$path], $path); + } + if ($is_setup_script) { + $cf->set( + 'UserprefsDisallow', + array_keys($this->_userprefsDisallow) + ); + } + } + + // don't look for non-critical errors + $this->_validate(); + + return $result; + } + + /** + * Tells whether form validation failed + * + * @return boolean + */ + public function hasErrors() + { + return count($this->_errors) > 0; + } + + + /** + * Returns link to documentation + * + * @param string $path + * + * @return string + */ + public function getDocLink($path) + { + $test = substr($path, 0, 6); + if ($test == 'Import' || $test == 'Export') { + return ''; + } + return PMA_Util::getDocuLink( + 'config', + 'cfg_' . $this->_getOptName($path) + ); + } + + /** + * Returns link to wiki + * + * @param string $path + * + * @return string + */ + public function getWikiLink($path) + { + $opt_name = $this->_getOptName($path); + if (substr($opt_name, 0, 7) == 'Servers') { + $opt_name = substr($opt_name, 8); + if (strpos($opt_name, 'AllowDeny') === 0) { + $opt_name = str_replace('_', '_.28', $opt_name) . '.29'; + } + } + $test = substr($path, 0, 6); + if ($test == 'Import') { + $opt_name = substr($opt_name, 7); + if ($opt_name == 'format') { + $opt_name = 'format_2'; + } + } + if ($test == 'Export') { + $opt_name = substr($opt_name, 7); + } + return PMA_linkURL('http://wiki.phpmyadmin.net/pma/Config#' . $opt_name); + } + + /** + * Changes path so it can be used in URLs + * + * @param string $path + * + * @return string + */ + private function _getOptName($path) + { + return str_replace(array('Servers/1/', '/'), array('Servers/', '_'), $path); + } + + /** + * Fills out {@link userprefs_keys} and {@link userprefs_disallow} + * + * @return void + */ + private function _loadUserprefsInfo() + { + if ($this->_userprefsKeys === null) { + $this->_userprefsKeys = array_flip(PMA_readUserprefsFieldNames()); + // read real config for user preferences display + $userprefs_disallow = defined('PMA_SETUP') + ? ConfigFile::getInstance()->get('UserprefsDisallow', array()) + : $GLOBALS['cfg']['UserprefsDisallow']; + $this->_userprefsDisallow = array_flip($userprefs_disallow); + } + } + + /** + * Sets field comments and warnings based on current environment + * + * @param string $system_path + * @param array $opts + * + * @return void + */ + private function _setComments($system_path, array &$opts) + { + // RecodingEngine - mark unavailable types + if ($system_path == 'RecodingEngine') { + $comment = ''; + if (!function_exists('iconv')) { + $opts['values']['iconv'] .= ' (' . __('unavailable') . ')'; + $comment = sprintf( + __('"%s" requires %s extension'), 'iconv', 'iconv' + ); + } + if (!function_exists('recode_string')) { + $opts['values']['recode'] .= ' (' . __('unavailable') . ')'; + $comment .= ($comment ? ", " : '') . sprintf( + __('"%s" requires %s extension'), + 'recode', 'recode' + ); + } + $opts['comment'] = $comment; + $opts['comment_warning'] = true; + } + // ZipDump, GZipDump, BZipDump - check function availability + if ($system_path == 'ZipDump' + || $system_path == 'GZipDump' + || $system_path == 'BZipDump' + ) { + $comment = ''; + $funcs = array( + 'ZipDump' => array('zip_open', 'gzcompress'), + 'GZipDump' => array('gzopen', 'gzencode'), + 'BZipDump' => array('bzopen', 'bzcompress')); + if (!function_exists($funcs[$system_path][0])) { + $comment = sprintf( + __('import will not work, missing function (%s)'), + $funcs[$system_path][0] + ); + } + if (!function_exists($funcs[$system_path][1])) { + $comment .= ($comment ? '; ' : '') . sprintf( + __('export will not work, missing function (%s)'), + $funcs[$system_path][1] + ); + } + $opts['comment'] = $comment; + $opts['comment_warning'] = true; + } + if ($system_path == 'SQLQuery/Validate' + && ! $GLOBALS['cfg']['SQLValidator']['use'] + ) { + $opts['comment'] = __('SQL Validator is disabled'); + $opts['comment_warning'] = true; + } + if ($system_path == 'SQLValidator/use') { + if (!class_exists('SOAPClient')) { + @include_once 'SOAP/Client.php'; + if (!class_exists('SOAP_Client')) { + $opts['comment'] = __('SOAP extension not found'); + $opts['comment_warning'] = true; + } + } + } + if (!defined('PMA_SETUP')) { + if (($system_path == 'MaxDbList' || $system_path == 'MaxTableList' + || $system_path == 'QueryHistoryMax') + ) { + $opts['comment'] = sprintf( + __('maximum %s'), $GLOBALS['cfg'][$system_path] + ); + } + } + } +} +?> diff --git a/hugo/libraries/config/FormDisplay.tpl.php b/hugo/libraries/config/FormDisplay.tpl.php new file mode 100644 index 0000000..677e3f4 --- /dev/null +++ b/hugo/libraries/config/FormDisplay.tpl.php @@ -0,0 +1,489 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Form templates + * + * @package PhpMyAdmin + */ + +/** + * Displays top part of the form + * + * @param string $action default: $_SERVER['REQUEST_URI'] + * @param string $method 'post' or 'get' + * @param array $hidden_fields array of form hidden fields (key: field name) + * + * @return void + */ +function PMA_displayFormTop($action = null, $method = 'post', $hidden_fields = null) +{ + static $has_check_page_refresh = false; + + if ($action === null) { + $action = $_SERVER['REQUEST_URI']; + } + if ($method != 'post') { + $method = 'get'; + } + echo '<form method="' . $method . '" action="' + . htmlspecialchars($action) . '" class="config-form disableAjax">'; + echo '<input type="hidden" name="tab_hash" value="" />'; + // we do validation on page refresh when browser remembers field values, + // add a field with known value which will be used for checks + if (!$has_check_page_refresh) { + $has_check_page_refresh = true; + echo '<input type="hidden" name="check_page_refresh" ' + . ' id="check_page_refresh" value="" />' . "\n"; + } + echo PMA_generate_common_hidden_inputs('', '', 0, 'server') . "\n"; + echo PMA_getHiddenFields((array)$hidden_fields); +} + +/** + * Displays form tabs which are given by an array indexed by fieldset id + * ({@link PMA_displayFieldsetTop}), with values being tab titles. + * + * @param array $tabs tab names + * + * @return void + */ +function PMA_displayTabsTop($tabs) +{ + echo '<ul class="tabs">'; + foreach ($tabs as $tab_id => $tab_name) { + echo '<li><a href="#' . $tab_id . '">' + . htmlspecialchars($tab_name) . '</a></li>'; + } + echo '</ul>'; + echo '<br clear="right" />'; + echo '<div class="tabs_contents">'; +} + + +/** + * Displays top part of a fieldset + * + * @param string $title title of fieldset + * @param string $description description shown on top of fieldset + * @param array $errors error messages to display + * @param array $attributes optional extra attributes of fieldset + * + * @return void + */ +function PMA_displayFieldsetTop($title = '', $description = '', $errors = null, + $attributes = array() +) { + global $_FormDisplayGroup; + + $_FormDisplayGroup = 0; + + $attributes = array_merge(array('class' => 'optbox'), $attributes); + foreach ($attributes as $k => &$attr) { + $attr = $k . '="' . htmlspecialchars($attr) . '"'; + } + + echo '<fieldset ' . implode(' ', $attributes) . '>'; + echo '<legend>' . $title . '</legend>'; + if (!empty($description)) { + echo '<p>' . $description . '</p>'; + } + // this must match with displayErrors() in scripts.js + if (is_array($errors) && count($errors) > 0) { + echo '<dl class="errors">'; + foreach ($errors as $error) { + echo '<dd>' . $error . '</dd>'; + } + echo '</dl>'; + } + echo '<table width="100%" cellspacing="0">'; +} + +/** + * Displays input field + * + * $opts keys: + * o doc - (string) documentation link + * o errors - error array + * o setvalue - (string) shows button allowing to set poredefined value + * o show_restore_default - (boolean) whether show "restore default" button + * o userprefs_allow - whether user preferences are enabled for this field + * (null - no support, true/false - enabled/disabled) + * o userprefs_comment - (string) field comment + * o values - key - value paris for <select> fields + * o values_escaped - (boolean) tells whether values array is already escaped + * (defaults to false) + * o values_disabled - (array)list of disabled values (keys from values) + * o comment - (string) tooltip comment + * o comment_warning - (bool) whether this comments warns about something + * o wiki - (string) wiki link + * + * @param string $path config option path + * @param string $name config option name + * @param string $type type of config option + * @param mixed $value current value + * @param string $description verbose description + * @param bool $value_is_default whether value is default + * @param array $opts see above description + * + * @return void + */ +function PMA_displayInput($path, $name, $type, $value, $description = '', + $value_is_default = true, $opts = null +) { + global $_FormDisplayGroup; + static $icons; // An array of IMG tags used further below in the function + + $is_setup_script = defined('PMA_SETUP'); + if ($icons === null) { // if the static variables have not been initialised + $icons = array(); + // Icon definitions: + // The same indexes will be used in the $icons array. + // The first element contains the filename and the second + // element is used for the "alt" and "title" attributes. + $icon_init = array( + 'edit' => array('b_edit.png', ''), + 'help' => array('b_help.png', __('Documentation')), + 'info' => array('b_info.png', __('Wiki')), + 'reload' => array('s_reload.png', ''), + 'tblops' => array('b_tblops.png', '') + ); + if ($is_setup_script) { + // When called from the setup script, we don't have access to the + // sprite-aware getImage() function because the PMA_theme class + // has not been loaded, so we generate the img tags manually. + foreach ($icon_init as $k => $v) { + $title = ''; + if (! empty($v[1])) { + $title = ' title="' . $v[1] . '"'; + } + $icons[$k] = sprintf( + '<img alt="%s" src="%s"%s />', + $v[1], + ".{$GLOBALS['cfg']['ThemePath']}/original/img/{$v[0]}", + $title + ); + } + } else { + // In this case we just use getImage() because it's available + foreach ($icon_init as $k => $v) { + $icons[$k] = PMA_Util::getImage( + $v[0], $v[1] + ); + } + } + } + $has_errors = isset($opts['errors']) && !empty($opts['errors']); + $option_is_disabled = ! $is_setup_script && isset($opts['userprefs_allow']) + && ! $opts['userprefs_allow']; + $name_id = 'name="' . htmlspecialchars($path) . '" id="' + . htmlspecialchars($path) . '"'; + $field_class = $type == 'checkbox' ? 'checkbox' : ''; + if (! $value_is_default) { + $field_class .= ($field_class == '' ? '' : ' ') + . ($has_errors ? 'custom field-error' : 'custom'); + } + $field_class = $field_class ? ' class="' . $field_class . '"' : ''; + $tr_class = $_FormDisplayGroup > 0 + ? 'group-field group-field-' . $_FormDisplayGroup + : ''; + if (isset($opts['setvalue']) && $opts['setvalue'] == ':group') { + unset($opts['setvalue']); + $_FormDisplayGroup++; + $tr_class = 'group-header-field group-header-' . $_FormDisplayGroup; + } + if ($option_is_disabled) { + $tr_class .= ($tr_class ? ' ' : '') . 'disabled-field'; + } + $tr_class = $tr_class ? ' class="' . $tr_class . '"' : ''; + + echo '<tr' . $tr_class . '>'; + echo '<th>'; + echo '<label for="' . htmlspecialchars($path) . '">' . $name . '</label>'; + + if (! empty($opts['doc']) || ! empty($opts['wiki'])) { + echo '<span class="doc">'; + if (! empty($opts['doc'])) { + echo '<a href="' . $opts['doc'] + . '" target="documentation">' . $icons['help'] . '</a>'; + echo "\n"; + } + if (! empty($opts['wiki'])) { + echo '<a href="' . $opts['wiki'] + . '" target="wiki">' . $icons['info'] . '</a>'; + echo "\n"; + } + echo '</span>'; + } + + if ($option_is_disabled) { + echo '<span class="disabled-notice" title="'; + echo __( + 'This setting is disabled, it will not be applied to your configuration' + ); + echo '">' . __('Disabled') . "</span>"; + } + + if (!empty($description)) { + echo '<small>' . $description . '</small>'; + } + + echo '</th>'; + echo '<td>'; + + switch ($type) { + case 'text': + echo '<input type="text" size="60" ' . $name_id . $field_class + . ' value="' . htmlspecialchars($value) . '" />'; + break; + case 'short_text': + echo '<input type="text" size="25" ' . $name_id . $field_class + . ' value="' . htmlspecialchars($value) . '" />'; + break; + case 'number_text': + echo '<input type="text" size="15" ' . $name_id . $field_class + . ' value="' . htmlspecialchars($value) . '" />'; + break; + case 'checkbox': + echo '<span' . $field_class . '><input type="checkbox" ' . $name_id + . ($value ? ' checked="checked"' : '') . ' /></span>'; + break; + case 'select': + echo '<select ' . $name_id . $field_class . '>'; + $escape = !(isset($opts['values_escaped']) && $opts['values_escaped']); + $values_disabled = isset($opts['values_disabled']) + ? array_flip($opts['values_disabled']) : array(); + foreach ($opts['values'] as $opt_value_key => $opt_value) { + // set names for boolean values + if (is_bool($opt_value)) { + $opt_value = strtolower($opt_value ? __('Yes') : __('No')); + } + // escape if necessary + if ($escape) { + $display = htmlspecialchars($opt_value); + $display_value = htmlspecialchars($opt_value_key); + } else { + $display = $opt_value; + $display_value = $opt_value_key; + } + // compare with selected value + // boolean values are cast to integers when used as array keys + $selected = is_bool($value) + ? (int) $value === $opt_value_key + : $opt_value_key === $value; + echo '<option value="' . $display_value . '"'; + if ($selected) { + echo ' selected="selected"'; + } + if (isset($values_disabled[$opt_value_key])) { + echo ' disabled="disabled"'; + } + echo '>' . $display . '</option>'; + } + echo '</select>'; + break; + case 'list': + echo '<textarea cols="40" rows="5" ' . $name_id . $field_class . '>' + . htmlspecialchars(implode("\n", $value)) + . '</textarea>'; + break; + } + if (isset($opts['comment']) && $opts['comment']) { + $class = 'field-comment-mark'; + if (isset($opts['comment_warning']) && $opts['comment_warning']) { + $class .= ' field-comment-warning'; + } + echo '<span class="' . $class . '" title="' + . htmlspecialchars($opts['comment']) . '">i</span>'; + } + if ($is_setup_script + && isset($opts['userprefs_comment']) + && $opts['userprefs_comment'] + ) { + echo '<a class="userprefs-comment" title="' + . htmlspecialchars($opts['userprefs_comment']) . '">' + . $icons['tblops'] . '</a>'; + } + if (isset($opts['setvalue']) && $opts['setvalue']) { + echo '<a class="set-value" href="#' + . htmlspecialchars("$path={$opts['setvalue']}") . '" title="' + . sprintf(__('Set value: %s'), htmlspecialchars($opts['setvalue'])) + . '" style="display:none">' . $icons['edit'] . '</a>'; + } + if (isset($opts['show_restore_default']) && $opts['show_restore_default']) { + echo '<a class="restore-default" href="#' . $path . '" title="' + . __('Restore default value') . '" style="display:none">' + . $icons['reload'] . '</a>'; + } + // this must match with displayErrors() in scripts/config.js + if ($has_errors) { + echo "\n <dl class=\"inline_errors\">"; + foreach ($opts['errors'] as $error) { + echo '<dd>' . htmlspecialchars($error) . '</dd>'; + } + echo '</dl>'; + } + echo '</td>'; + if ($is_setup_script && isset($opts['userprefs_allow'])) { + echo '<td class="userprefs-allow" title="' . + __('Allow users to customize this value') . '">'; + echo '<input type="checkbox" name="' . $path . '-userprefs-allow" '; + if ($opts['userprefs_allow']) { + echo 'checked="checked"'; + }; + echo '/>'; + echo '</td>'; + } else if ($is_setup_script) { + echo '<td> </td>'; + } + echo '</tr>'; +} + +/** + * Display group header + * + * @param string $header_text Text of header + * + * @return void + */ +function PMA_displayGroupHeader($header_text) +{ + global $_FormDisplayGroup; + + $_FormDisplayGroup++; + if (!$header_text) { + return; + } + $colspan = defined('PMA_SETUP') + ? 3 + : 2; + echo '<tr class="group-header group-header-' . $_FormDisplayGroup . '">'; + echo '<th colspan="' . $colspan . '">'; + echo $header_text; + echo '</th>'; + echo '</tr>'; +} + +/** + * Display group footer + * + * @return void + */ +function PMA_displayGroupFooter() +{ + global $_FormDisplayGroup; + + $_FormDisplayGroup--; +} + +/** + * Displays bottom part of a fieldset + * + * @return void + */ +function PMA_displayFieldsetBottom() +{ + $colspan = 2; + if (defined('PMA_SETUP')) { + $colspan++; + } + echo '<tr>'; + echo '<td colspan="' . $colspan . '" class="lastrow">'; + echo '<input type="submit" name="submit_save" value="' + . __('Save') . '" class="green" />'; + echo '<input type="button" name="submit_reset" value="' + . __('Reset') . '" />'; + echo '</td>'; + echo '</tr>'; + echo '</table>'; + echo '</fieldset>'; +} + +/** + * Displays simple bottom part of a fieldset (without submit buttons) + * + * @return void + */ +function PMA_displayFieldsetBottomSimple() +{ + echo '</table>'; + echo '</fieldset>'; +} + +/** + * Closes form tabs + * + * @return void + */ +function PMA_displayTabsBottom() +{ + echo "</div>\n"; +} + +/** + * Displays bottom part of the form + * + * @return void + */ +function PMA_displayFormBottom() +{ + echo "</form>\n"; +} + +/** + * Appends JS validation code to $js_array + * + * @param string $field_id ID of field to validate + * @param string|array $validators validators callback + * @param array &$js_array will be updated with javascript code + * + * @return void + */ +function PMA_addJsValidate($field_id, $validators, &$js_array) +{ + foreach ((array)$validators as $validator) { + $validator = (array)$validator; + $v_name = array_shift($validator); + $v_args = array(); + foreach ($validator as $arg) { + $v_args[] = PMA_escapeJsString($arg); + } + $v_args = $v_args ? ", ['" . implode("', '", $v_args) . "']" : ''; + $js_array[] = "validateField('$field_id', '$v_name', true$v_args)"; + } +} + +/** + * Displays JavaScript code + * + * @param array $js_array lines of javascript code + * + * @return void + */ +function PMA_displayJavascript($js_array) +{ + if (empty($js_array)) { + return; + } + echo '<script type="text/javascript">' . "\n"; + echo implode(";\n", $js_array) . ";\n"; + echo '</script>' . "\n"; +} + +/** + * Displays error list + * + * @param string $name name of item with errors + * @param array $error_list list of errors to show + * + * @return void + */ +function PMA_displayErrors($name, $error_list) +{ + echo '<dl>'; + echo '<dt>' . htmlspecialchars($name) . '</dt>'; + foreach ($error_list as $error) { + echo '<dd>' . htmlspecialchars($error) . '</dd>'; + } + echo '</dl>'; +} +?> diff --git a/hugo/libraries/config/config_functions.lib.php b/hugo/libraries/config/config_functions.lib.php new file mode 100644 index 0000000..44a2624 --- /dev/null +++ b/hugo/libraries/config/config_functions.lib.php @@ -0,0 +1,55 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Common config manipulation functions + * + * @package PhpMyAdmin + */ + +/** + * Returns sanitized language string, taking into account our special codes + * for formatting. Takes variable number of arguments. + * Based on PMA_sanitize from sanitize.lib.php. + * + * @param string $lang_key key in $GLOBALS WITHOUT 'strSetup' prefix + * @param mixed $args,... arguments for sprintf + * + * @return string + */ +function PMA_lang($lang_key, $args = null) +{ + $message = isset($GLOBALS["strConfig$lang_key"]) + ? $GLOBALS["strConfig$lang_key"] : $lang_key; + + $message = PMA_sanitize($message); + + if (func_num_args() == 1) { + return $message; + } else { + $args = func_get_args(); + array_shift($args); + return vsprintf($message, $args); + } +} + +/** + * Returns translated field name/description or comment + * + * @param string $canonical_path + * @param string $type 'name', 'desc' or 'cmt' + * @param mixed $default + * + * @return string + */ +function PMA_lang_name($canonical_path, $type = 'name', $default = 'key') +{ + $lang_key = str_replace( + array('Servers/1/', '/'), + array('Servers/', '_'), + $canonical_path + ) . '_' . $type; + return isset($GLOBALS["strConfig$lang_key"]) + ? ($type == 'desc' ? PMA_lang($lang_key) : $GLOBALS["strConfig$lang_key"]) + : ($default == 'key' ? $lang_key : $default); +} +?> diff --git a/hugo/libraries/config/messages.inc.php b/hugo/libraries/config/messages.inc.php new file mode 100644 index 0000000..a2036fc --- /dev/null +++ b/hugo/libraries/config/messages.inc.php @@ -0,0 +1,526 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Messages for phpMyAdmin. + * + * This file defines variables in a special format suited for the + * configuration subsystem, with $strConfig as a prefix, _desc or _name + * as a suffix, and the directive name in between. + * + * @package PhpMyAdmin + */ + +if (!function_exists('__')) { + PMA_fatalError('Bad invocation!'); +} + +$strConfigAllowArbitraryServer_desc = __('If enabled user can enter any MySQL server in login form for cookie auth'); +$strConfigAllowArbitraryServer_name = __('Allow login to any MySQL server'); +$strConfigAllowThirdPartyFraming_desc = __('Enabling this allows a page located on a different domain to call phpMyAdmin inside a frame, and is a potential [strong]security hole[/strong] allowing cross-frame scripting attacks'); +$strConfigAllowThirdPartyFraming_name = __('Allow third party framing'); +$strConfigAllowUserDropDatabase_name = __('Show "Drop database" link to normal users'); +$strConfigblowfish_secret_desc = __('Secret passphrase used for encrypting cookies in [kbd]cookie[/kbd] authentication'); +$strConfigblowfish_secret_name = __('Blowfish secret'); +$strConfigBrowseMarkerEnable_desc = __('Highlight selected rows'); +$strConfigBrowseMarkerEnable_name = __('Row marker'); +$strConfigBrowsePointerEnable_desc = __('Highlight row pointed by the mouse cursor'); +$strConfigBrowsePointerEnable_name = __('Highlight pointer'); +$strConfigBZipDump_desc = __('Enable [a@http://en.wikipedia.org/wiki/Bzip2]bzip2[/a] compression for import and export operations'); +$strConfigBZipDump_name = __('Bzip2'); +$strConfigCharEditing_desc = __('Defines which type of editing controls should be used for CHAR and VARCHAR columns; [kbd]input[/kbd] - allows limiting of input length, [kbd]textarea[/kbd] - allows newlines in columns'); +$strConfigCharEditing_name = __('CHAR columns editing'); +$strConfigCodemirrorEnable_desc = __('Use user-friendly editor for editing SQL queries ([a@http://codemirror.net/]CodeMirror[/a]) with syntax highlighting and line numbers'); +$strConfigCodemirrorEnable_name = __('Enable CodeMirror'); +$strConfigMinSizeForInputField_desc = __('Defines the minimum size for input fields generated for CHAR and VARCHAR columns'); +$strConfigMinSizeForInputField_name = __('Minimum size for input field'); +$strConfigMaxSizeForInputField_desc = __('Defines the maximum size for input fields generated for CHAR and VARCHAR columns'); +$strConfigMaxSizeForInputField_name = __('Maximum size for input field'); +$strConfigCharTextareaCols_desc = __('Number of columns for CHAR/VARCHAR textareas'); +$strConfigCharTextareaCols_name = __('CHAR textarea columns'); +$strConfigCharTextareaRows_desc = __('Number of rows for CHAR/VARCHAR textareas'); +$strConfigCharTextareaRows_name = __('CHAR textarea rows'); +$strConfigCheckConfigurationPermissions_name = __('Check config file permissions'); +$strConfigCompressOnFly_desc = __('Compress gzip/bzip2 exports on the fly without the need for much memory; if you encounter problems with created gzip/bzip2 files disable this feature'); +$strConfigCompressOnFly_name = __('Compress on the fly'); +$strConfigConfigurationFile = __('Configuration file'); +$strConfigConfirm_desc = __('Whether a warning ("Are your really sure…") should be displayed when you\'re about to lose data'); +$strConfigConfirm_name = __('Confirm DROP queries'); +$strConfigDBG_sql_name = __('Debug SQL'); +$strConfigDefaultDisplay_name = __('Default display direction'); +$strConfigDefaultTabDatabase_desc = __('Tab that is displayed when entering a database'); +$strConfigDefaultTabDatabase_name = __('Default database tab'); +$strConfigDefaultTabServer_desc = __('Tab that is displayed when entering a server'); +$strConfigDefaultTabServer_name = __('Default server tab'); +$strConfigDefaultTabTable_desc = __('Tab that is displayed when entering a table'); +$strConfigDefaultTabTable_name = __('Default table tab'); +$strConfigHideStructureActions_desc = __('Whether the table structure actions should be hidden'); +$strConfigHideStructureActions_name = __('Hide table structure actions'); +$strConfigDisplayBinaryAsHex_desc = __('Show binary contents as HEX by default'); +$strConfigDisplayBinaryAsHex_name = __('Show binary contents as HEX'); +$strConfigDisplayServersList_desc = __('Show server listing as a list instead of a drop down'); +$strConfigDisplayServersList_name = __('Display servers as a list'); +$strConfigDisableMultiTableMaintenance_desc = __('Disable the table maintenance mass operations, like optimizing or repairing the selected tables of a database.'); +$strConfigDisableMultiTableMaintenance_name = __('Disable multi table maintenance'); +$strConfigEditInWindow_desc = __('Edit SQL queries in popup window'); +$strConfigEditInWindow_name = __('Edit in window'); +$strConfigError_Handler_display_name = __('Display errors'); +$strConfigError_Handler_gather_name = __('Gather errors'); +$strConfigExecTimeLimit_desc = __('Set the number of seconds a script is allowed to run ([kbd]0[/kbd] for no limit)'); +$strConfigExecTimeLimit_name = __('Maximum execution time'); +$strConfigExport_asfile_name = __('Save as file'); +$strConfigExport_charset_name = __('Character set of the file'); +$strConfigExport_codegen_format_name = __('Format'); +$strConfigExport_compression_name = __('Compression'); +$strConfigExport_csv_columns_name = __('Put columns names in the first row'); +$strConfigExport_csv_enclosed_name = __('Columns enclosed by'); +$strConfigExport_csv_escaped_name = __('Columns escaped by'); +$strConfigExport_csv_null_name = __('Replace NULL by'); +$strConfigExport_csv_removeCRLF_name = __('Remove CRLF characters within columns'); +$strConfigExport_csv_separator_name = __('Columns terminated by'); +$strConfigExport_csv_terminated_name = __('Lines terminated by'); +$strConfigExport_excel_columns_name = __('Put columns names in the first row'); +$strConfigExport_excel_edition_name = __('Excel edition'); +$strConfigExport_excel_null_name = __('Replace NULL by'); +$strConfigExport_excel_removeCRLF_name = __('Remove CRLF characters within columns'); +$strConfigExport_file_template_database_name = __('Database name template'); +$strConfigExport_file_template_server_name = __('Server name template'); +$strConfigExport_file_template_table_name = __('Table name template'); +$strConfigExport_format_name = __('Format'); +$strConfigExport_htmlword_columns_name = __('Put columns names in the first row'); +$strConfigExport_htmlword_null_name = __('Replace NULL by'); +$strConfigExport_htmlword_structure_or_data_name = __('Dump table'); +$strConfigExport_latex_caption_name = __('Include table caption'); +$strConfigExport_latex_columns_name = __('Put columns names in the first row'); +$strConfigExport_latex_comments_name = __('Comments'); +$strConfigExport_latex_data_caption_name = __('Table caption'); +$strConfigExport_latex_data_continued_caption_name = __('Continued table caption'); +$strConfigExport_latex_data_label_name = __('Label key'); +$strConfigExport_latex_mime_name = __('MIME type'); +$strConfigExport_latex_null_name = __('Replace NULL by'); +$strConfigExport_latex_relation_name = __('Relations'); +$strConfigExport_latex_structure_caption_name = __('Table caption'); +$strConfigExport_latex_structure_continued_caption_name = __('Continued table caption'); +$strConfigExport_latex_structure_label_name = __('Label key'); +$strConfigExport_latex_structure_or_data_name = __('Dump table'); +$strConfigExport_method_name = __('Export method'); +$strConfigExport_ods_columns_name = __('Put columns names in the first row'); +$strConfigExport_ods_null_name = __('Replace NULL by'); +$strConfigExport_odt_columns_name = __('Put columns names in the first row'); +$strConfigExport_odt_comments_name = __('Comments'); +$strConfigExport_odt_mime_name = __('MIME type'); +$strConfigExport_odt_null_name = __('Replace NULL by'); +$strConfigExport_odt_relation_name = __('Relations'); +$strConfigExport_odt_structure_or_data_name = __('Dump table'); +$strConfigExport_onserver_name = __('Save on server'); +$strConfigExport_onserver_overwrite_name = __('Overwrite existing file(s)'); +$strConfigExport_quick_export_onserver_name = __('Save on server'); +$strConfigExport_quick_export_onserver_overwrite_name = __('Overwrite existing file(s)'); +$strConfigExport_remember_file_template_name = __('Remember file name template'); +$strConfigExport_sql_auto_increment_name = __('Add AUTO_INCREMENT value'); +$strConfigExport_sql_backquotes_name = __('Enclose table and column names with backquotes'); +$strConfigExport_sql_compatibility_name = __('SQL compatibility mode'); +$strConfigExport_sql_create_table_statements_name = __('<code>CREATE TABLE</code> options:'); +$strConfigExport_sql_dates_name = __('Creation/Update/Check dates'); +$strConfigExport_sql_delayed_name = __('Use delayed inserts'); +$strConfigExport_sql_disable_fk_name = __('Disable foreign key checks'); +$strConfigExport_sql_drop_database_name = sprintf(__('Add %s'), 'DROP DATABASE'); +$strConfigExport_sql_drop_table_name = sprintf(__('Add %s'), 'DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT'); +$strConfigExport_sql_hex_for_blob_name = __('Use hexadecimal for BLOB'); +$strConfigExport_sql_if_not_exists_name = sprintf(__('Add %s'), 'IF NOT EXISTS'); +$strConfigExport_sql_ignore_name = __('Use ignore inserts'); +$strConfigExport_sql_include_comments_name = __('Comments'); +$strConfigExport_sql_insert_syntax_name = __('Syntax to use when inserting data'); +$strConfigExport_sql_max_query_size_name = __('Maximal length of created query'); +$strConfigExport_sql_mime_name = __('MIME type'); +$strConfigExport_sql_procedure_function_name = sprintf(__('Add %s'), 'CREATE PROCEDURE / FUNCTION / EVENT'); +$strConfigExport_sql_relation_name = __('Relations'); +$strConfigExport_sql_structure_or_data_name = __('Dump table'); +$strConfigExport_sql_type_name = __('Export type'); +$strConfigExport_sql_use_transaction_name = __('Enclose export in a transaction'); +$strConfigExport_sql_utc_time_name = __('Export time in UTC'); +$strConfigExport_texytext_columns_name = __('Put columns names in the first row'); +$strConfigExport_texytext_null_name = __('Replace NULL by'); +$strConfigExport_texytext_structure_or_data_name = __('Dump table'); +$strConfigExport_xls_columns_name = __('Put columns names in the first row'); +$strConfigExport_xls_null_name = __('Replace NULL by'); +$strConfigExport_xlsx_columns_name = __('Put columns names in the first row'); +$strConfigExport_xlsx_null_name = __('Replace NULL by'); +$strConfigForceSSL_desc = __('Force secured connection while using phpMyAdmin'); +$strConfigForceSSL_name = __('Force SSL connection'); +$strConfigForeignKeyDropdownOrder_desc = __('Sort order for items in a foreign-key dropdown box; [kbd]content[/kbd] is the referenced data, [kbd]id[/kbd] is the key value'); +$strConfigForeignKeyDropdownOrder_name = __('Foreign key dropdown order'); +$strConfigForeignKeyMaxLimit_desc = __('A dropdown will be used if fewer items are present'); +$strConfigForeignKeyMaxLimit_name = __('Foreign key limit'); +$strConfigForm_Browse = __('Browse mode'); +$strConfigForm_Browse_desc = __('Customize browse mode'); +$strConfigForm_CodeGen = 'CodeGen'; +$strConfigForm_CodeGen_desc = __('Customize default options'); +$strConfigForm_Csv = __('CSV'); +$strConfigForm_Csv_desc = __('Customize default options'); +$strConfigForm_Developer = __('Developer'); +$strConfigForm_Developer_desc = __('Settings for phpMyAdmin developers'); +$strConfigForm_Edit = __('Edit mode'); +$strConfigForm_Edit_desc = __('Customize edit mode'); +$strConfigForm_Export = __('Export'); +$strConfigForm_Export_defaults = __('Export defaults'); +$strConfigForm_Export_defaults_desc = __('Customize default export options'); +$strConfigForm_Features = __('Features'); +$strConfigForm_General = __('General'); +$strConfigForm_General_desc = __('Set some commonly used options'); +$strConfigForm_Import = __('Import'); +$strConfigForm_Import_defaults = __('Import defaults'); +$strConfigForm_Import_defaults_desc = __('Customize default common import options'); +$strConfigForm_Import_export = __('Import / export'); +$strConfigForm_Import_export_desc = __('Set import and export directories and compression options'); +$strConfigForm_Latex = __('LaTeX'); +$strConfigForm_Latex_desc = __('Customize default options'); +$strConfigForm_Navi_databases = __('Databases'); +$strConfigForm_Navi_databases_desc = __('Databases display options'); +$strConfigForm_Navi_panel = __('Navigation panel'); +$strConfigForm_Navi_panel_desc = __('Customize appearance of the navigation panel'); +$strConfigForm_Navi_servers = __('Servers'); +$strConfigForm_Navi_servers_desc = __('Servers display options'); +$strConfigForm_Navi_tables = __('Tables'); +$strConfigForm_Navi_tables_desc = __('Tables display options'); +$strConfigForm_Main_panel = __('Main panel'); +$strConfigForm_Microsoft_Office = __('Microsoft Office'); +$strConfigForm_Microsoft_Office_desc = __('Customize default options'); +$strConfigForm_Open_Document = 'OpenDocument'; +$strConfigForm_Open_Document_desc = __('Customize default options'); +$strConfigForm_Other_core_settings = __('Other core settings'); +$strConfigForm_Other_core_settings_desc = __('Settings that didn\'t fit anywhere else'); +$strConfigForm_Page_titles = __('Page titles'); +$strConfigForm_Page_titles_desc = __('Specify browser\'s title bar text. Refer to [doc@cfg_TitleTable]documentation[/doc] for magic strings that can be used to get special values.'); +$strConfigForm_Query_window = __('Query window'); +$strConfigForm_Query_window_desc = __('Customize query window options'); +$strConfigForm_Security = __('Security'); +$strConfigForm_Security_desc = __('Please note that phpMyAdmin is just a user interface and its features do not limit MySQL'); +$strConfigForm_Server = __('Basic settings'); +$strConfigForm_Server_auth = __('Authentication'); +$strConfigForm_Server_auth_desc = __('Authentication settings'); +$strConfigForm_Server_config = __('Server configuration'); +$strConfigForm_Server_config_desc = __('Advanced server configuration, do not change these options unless you know what they are for'); +$strConfigForm_Server_desc = __('Enter server connection parameters'); +$strConfigForm_Server_pmadb = __('Configuration storage'); +$strConfigForm_Server_pmadb_desc = __('Configure phpMyAdmin configuration storage to gain access to additional features, see [doc@linked-tables]phpMyAdmin configuration storage[/doc] in documentation'); +$strConfigForm_Server_tracking = __('Changes tracking'); +$strConfigForm_Server_tracking_desc = __('Tracking of changes made in database. Requires the phpMyAdmin configuration storage.'); +$strConfigFormset_Export = __('Customize export options'); +$strConfigFormset_Features = __('Features'); +$strConfigFormset_Import = __('Customize import defaults'); +$strConfigFormset_Navi_panel = __('Customize navigation panel'); +$strConfigFormset_Main_panel = __('Customize main panel'); +$strConfigFormset_Sql_queries = __('SQL queries'); +$strConfigForm_Sql = __('SQL'); +$strConfigForm_Sql_box = __('SQL Query box'); +$strConfigForm_Sql_box_desc = __('Customize links shown in SQL Query boxes'); +$strConfigForm_Sql_desc = __('Customize default options'); +$strConfigForm_Sql_queries = __('SQL queries'); +$strConfigForm_Sql_queries_desc = __('SQL queries settings'); +$strConfigForm_Sql_validator = __('SQL Validator'); +$strConfigForm_Sql_validator_desc = __('If you wish to use the SQL Validator service, you should be aware that [strong]all SQL statements are stored anonymously for statistical purposes[/strong].[br][em][a@http://sqlvalidator.mimer.com/]Mimer SQL Validator[/a], Copyright 2002 Upright Database Technology. All rights reserved.[/em]'); +$strConfigForm_Startup = __('Startup'); +$strConfigForm_Startup_desc = __('Customize startup page'); +$strConfigForm_DbStructure = __('Database structure'); +$strConfigForm_DbStructure_desc = __('Choose which details to show in the database structure (list of tables)'); +$strConfigForm_TableStructure = __('Table structure'); +$strConfigForm_TableStructure_desc = __('Settings for the table structure (list of columns)'); +$strConfigForm_Tabs = __('Tabs'); +$strConfigForm_Tabs_desc = __('Choose how you want tabs to work'); +$strConfigForm_Text_fields = __('Text fields'); +$strConfigForm_Text_fields_desc = __('Customize text input fields'); +$strConfigForm_Texy = __('Texy! text'); +$strConfigForm_Texy_desc = __('Customize default options'); +$strConfigForm_Warnings = __('Warnings'); +$strConfigForm_Warnings_desc = __('Disable some of the warnings shown by phpMyAdmin'); +$strConfigGZipDump_desc = __('Enable [a@http://en.wikipedia.org/wiki/Gzip]gzip[/a] compression for import and export operations'); +$strConfigGZipDump_name = __('GZip'); +$strConfigIconvExtraParams_name = __('Extra parameters for iconv'); +$strConfigIgnoreMultiSubmitErrors_desc = __('If enabled, phpMyAdmin continues computing multiple-statement queries even if one of the queries failed'); +$strConfigIgnoreMultiSubmitErrors_name = __('Ignore multiple statement errors'); +$strConfigImport_allow_interrupt_desc = __('Allow interrupt of import in case script detects it is close to time limit. This might be a good way to import large files, however it can break transactions.'); +$strConfigImport_allow_interrupt_name = __('Partial import: allow interrupt'); +$strConfigImport_charset_name = __('Character set of the file'); +$strConfigImport_csv_col_names_name = __('Lines terminated by'); +$strConfigImport_csv_enclosed_name = __('Columns enclosed by'); +$strConfigImport_csv_escaped_name = __('Columns escaped by'); +$strConfigImport_csv_ignore_name = __('Do not abort on INSERT error'); +$strConfigImport_csv_replace_name = __('Replace table data with file'); +$strConfigImport_csv_terminated_name = __('Columns terminated by'); +$strConfigImport_format_desc = __('Default format; be aware that this list depends on location (database, table) and only SQL is always available'); +$strConfigImport_format_name = __('Format of imported file'); +$strConfigImport_ldi_enclosed_name = __('Columns enclosed by'); +$strConfigImport_ldi_escaped_name = __('Columns escaped by'); +$strConfigImport_ldi_ignore_name = __('Do not abort on INSERT error'); +$strConfigImport_ldi_local_option_name = __('Use LOCAL keyword'); +$strConfigImport_ldi_replace_name = __('Replace table data with file'); +$strConfigImport_ldi_terminated_name = __('Columns terminated by'); +$strConfigImport_ods_col_names_name = __('Column names in first row'); +$strConfigImport_ods_empty_rows_name = __('Do not import empty rows'); +$strConfigImport_ods_recognize_currency_name = __('Import currencies ($5.00 to 5.00)'); +$strConfigImport_ods_recognize_percentages_name = __('Import percentages as proper decimals (12.00% to .12)'); +$strConfigImport_skip_queries_desc = __('Number of queries to skip from start'); +$strConfigImport_skip_queries_name = __('Partial import: skip queries'); +$strConfigImport_sql_compatibility_name = __('SQL compatibility mode'); +$strConfigImport_sql_no_auto_value_on_zero_name = __('Do not use AUTO_INCREMENT for zero values'); +$strConfigImport_xls_col_names_name = __('Column names in first row'); +$strConfigImport_xlsx_col_names_name = __('Column names in first row'); +$strConfigInitialSlidersState_name = __('Initial state for sliders'); +$strConfigInsertRows_desc = __('How many rows can be inserted at one time'); +$strConfigInsertRows_name = __('Number of inserted rows'); +$strConfigLimitChars_desc = __('Maximum number of characters shown in any non-numeric column on browse view'); +$strConfigLimitChars_name = __('Limit column characters'); +$strConfigLoginCookieDeleteAll_desc = __('If TRUE, logout deletes cookies for all servers; when set to FALSE, logout only occurs for the current server. Setting this to FALSE makes it easy to forget to log out from other servers when connected to multiple servers.'); +$strConfigLoginCookieDeleteAll_name = __('Delete all cookies on logout'); +$strConfigLoginCookieRecall_desc = __('Define whether the previous login should be recalled or not in cookie authentication mode'); +$strConfigLoginCookieRecall_name = __('Recall user name'); +$strConfigLoginCookieStore_desc = __('Defines how long (in seconds) a login cookie should be stored in browser. The default of 0 means that it will be kept for the existing session only, and will be deleted as soon as you close the browser window. This is recommended for non-trusted environments.'); +$strConfigLoginCookieStore_name = __('Login cookie store'); +$strConfigLoginCookieValidity_desc = __('Define how long (in seconds) a login cookie is valid'); +$strConfigLoginCookieValidity_name = __('Login cookie validity'); +$strConfigLongtextDoubleTextarea_desc = __('Double size of textarea for LONGTEXT columns'); +$strConfigLongtextDoubleTextarea_name = __('Bigger textarea for LONGTEXT'); +$strConfigMaxCharactersInDisplayedSQL_desc = __('Maximum number of characters used when a SQL query is displayed'); +$strConfigMaxCharactersInDisplayedSQL_name = __('Maximum displayed SQL length'); +$strConfigMaxDbList_cmt = __('Users cannot set a higher value'); +$strConfigMaxDbList_desc = __('Maximum number of databases displayed in database list'); +$strConfigMaxDbList_name = __('Maximum databases'); +$strConfigMaxNavigationItems_desc = __('The number of items that can be displayed on each page of the navigation tree'); +$strConfigMaxNavigationItems_name = __('Maximum items in branch'); +$strConfigMaxRows_desc = __('Number of rows displayed when browsing a result set. If the result set contains more rows, "Previous" and "Next" links will be shown.'); +$strConfigMaxRows_name = __('Maximum number of rows to display'); +$strConfigMaxTableList_cmt = __('Users cannot set a higher value'); +$strConfigMaxTableList_desc = __('Maximum number of tables displayed in table list'); +$strConfigMaxTableList_name = __('Maximum tables'); +$strConfigMcryptDisableWarning_desc = __('Disable the default warning that is displayed if mcrypt is missing for cookie authentication'); +$strConfigMcryptDisableWarning_name = __('mcrypt warning'); +$strConfigMemoryLimit_desc = __('The number of bytes a script is allowed to allocate, eg. [kbd]32M[/kbd] ([kbd]0[/kbd] for no limit)'); +$strConfigMemoryLimit_name = __('Memory limit'); +$strConfigNavigationDisplayLogo_desc = __('Show logo in navigation panel'); +$strConfigNavigationDisplayLogo_name = __('Display logo'); +$strConfigNavigationLogoLink_desc = __('URL where logo in the navigation panel will point to'); +$strConfigNavigationLogoLink_name = __('Logo link URL'); +$strConfigNavigationLogoLinkWindow_desc = __('Open the linked page in the main window ([kbd]main[/kbd]) or in a new one ([kbd]new[/kbd])'); +$strConfigNavigationLogoLinkWindow_name = __('Logo link target'); +$strConfigNavigationDisplayServers_desc = __('Display server choice at the top of the navigation panel'); +$strConfigNavigationDisplayServers_name = __('Display servers selection'); +$strConfigNavigationTreeDefaultTabTable_name = __('Target for quick access icon'); +$strConfigNavigationTreeDisplayItemFilterMinimum_desc = __('Defines the minimum number of items (tables, views, routines and events) to display a filter box.'); +$strConfigNavigationTreeDisplayItemFilterMinimum_name = __('Minimum number of items to display the filter box'); +$strConfigNavigationTreeDisplayDbFilterMinimum_name = __('Minimum number of databases to display the database filter box'); +$strConfigNavigationTreeEnableGrouping_desc = __('Group items in the navigation tree (determined by the separator defined below)'); +$strConfigNavigationTreeEnableGrouping_name = __('Group items in the tree'); +$strConfigNavigationTreeDbSeparator_desc = __('String that separates databases into different tree levels'); +$strConfigNavigationTreeDbSeparator_name = __('Database tree separator'); +$strConfigNavigationTreeTableSeparator_desc = __('String that separates tables into different tree levels'); +$strConfigNavigationTreeTableSeparator_name = __('Table tree separator'); +$strConfigNavigationTreeTableLevel_name = __('Maximum table tree depth'); +$strConfigNavigationTreePointerEnable_desc = __('Highlight server under the mouse cursor'); +$strConfigNavigationTreePointerEnable_name = __('Enable highlighting'); +$strConfigNumRecentTables_desc = __('Maximum number of recently used tables; set 0 to disable'); +$strConfigNumRecentTables_name = __('Recently used tables'); +$strConfigRowActionLinks_desc = __('These are Edit, Copy and Delete links'); +$strConfigRowActionLinks_name = __('Where to show the table row links'); +$strConfigNaturalOrder_desc = __('Use natural order for sorting table and database names'); +$strConfigNaturalOrder_name = __('Natural order'); +$strConfigTableNavigationLinksMode_desc = __('Use only icons, only text or both'); +$strConfigTableNavigationLinksMode_name = __('Table navigation bar'); +$strConfigOBGzip_desc = __('use GZip output buffering for increased speed in HTTP transfers'); +$strConfigOBGzip_name = __('GZip output buffering'); +$strConfigOrder_desc = __('[kbd]SMART[/kbd] - i.e. descending order for columns of type TIME, DATE, DATETIME and TIMESTAMP, ascending order otherwise'); +$strConfigOrder_name = __('Default sorting order'); +$strConfigPersistentConnections_desc = __('Use persistent connections to MySQL databases'); +$strConfigPersistentConnections_name = __('Persistent connections'); +$strConfigPmaNoRelation_DisableWarning_desc = __('Disable the default warning that is displayed on the database details Structure page if any of the required tables for the phpMyAdmin configuration storage could not be found'); +$strConfigPmaNoRelation_DisableWarning_name = __('Missing phpMyAdmin configuration storage tables'); +$strConfigServerLibraryDifference_DisableWarning_desc = __('Disable the default warning that is displayed if a difference between the MySQL library and server is detected'); +$strConfigServerLibraryDifference_DisableWarning_name = __('Server/library difference warning'); +$strConfigReservedWordDisableWarning_desc = __('Disable the default warning that is displayed on the Structure page if column names in a table are reserved MySQL words'); +$strConfigReservedWordDisableWarning_name = __('MySQL reserved word warning'); +$strConfigTabsMode_desc = __('Use only icons, only text or both'); +$strConfigTabsMode_name = __('How to display the menu tabs'); +$strConfigActionLinksMode_desc = __('Use only icons, only text or both'); +$strConfigActionLinksMode_name = __('How to display various action links'); +$strConfigProtectBinary_desc = __('Disallow BLOB and BINARY columns from editing'); +$strConfigProtectBinary_name = __('Protect binary columns'); +$strConfigQueryHistoryDB_desc = __('Enable if you want DB-based query history (requires phpMyAdmin configuration storage). If disabled, this utilizes JS-routines to display query history (lost by window close).'); +$strConfigQueryHistoryDB_name = __('Permanent query history'); +$strConfigQueryHistoryMax_cmt = __('Users cannot set a higher value'); +$strConfigQueryHistoryMax_desc = __('How many queries are kept in history'); +$strConfigQueryHistoryMax_name = __('Query history length'); +$strConfigQueryWindowDefTab_desc = __('Tab displayed when opening a new query window'); +$strConfigQueryWindowDefTab_name = __('Default query window tab'); +$strConfigQueryWindowHeight_desc = __('Query window height (in pixels)'); +$strConfigQueryWindowHeight_name = __('Query window height'); +$strConfigQueryWindowWidth_desc = __('Query window width (in pixels)'); +$strConfigQueryWindowWidth_name = __('Query window width'); +$strConfigRecodingEngine_desc = __('Select which functions will be used for character set conversion'); +$strConfigRecodingEngine_name = __('Recoding engine'); +$strConfigRememberSorting_desc = __('When browsing tables, the sorting of each table is remembered'); +$strConfigRememberSorting_name = __('Remember table\'s sorting'); +$strConfigRepeatCells_desc = __('Repeat the headers every X cells, [kbd]0[/kbd] deactivates this feature'); +$strConfigRepeatCells_name = __('Repeat headers'); +$strConfigRestoreDefaultValue = __('Restore default value'); +$strConfigGridEditing_name = __('Grid editing: trigger action'); +$strConfigSaveCellsAtOnce_name = __('Grid editing: save all edited cells at once'); +$strConfigSaveDir_desc = __('Directory where exports can be saved on server'); +$strConfigSaveDir_name = __('Save directory'); +$strConfigServers_AllowDeny_order_desc = __('Leave blank if not used'); +$strConfigServers_AllowDeny_order_name = __('Host authorization order'); +$strConfigServers_AllowDeny_rules_desc = __('Leave blank for defaults'); +$strConfigServers_AllowDeny_rules_name = __('Host authorization rules'); +$strConfigServers_AllowNoPassword_name = __('Allow logins without a password'); +$strConfigServers_AllowRoot_name = __('Allow root login'); +$strConfigServers_auth_http_realm_desc = __('HTTP Basic Auth Realm name to display when doing HTTP Auth'); +$strConfigServers_auth_http_realm_name = __('HTTP Realm'); +$strConfigServers_auth_swekey_config_desc = __('The path for the config file for [a@http://swekey.com]SweKey hardware authentication[/a] (not located in your document root; suggested: /etc/swekey.conf)'); +$strConfigServers_auth_swekey_config_name = __('SweKey config file'); +$strConfigServers_auth_type_desc = __('Authentication method to use'); +$strConfigServers_auth_type_name = __('Authentication type'); +$strConfigServers_bookmarktable_desc = __('Leave blank for no [a@http://wiki.phpmyadmin.net/pma/bookmark]bookmark[/a] support, suggested: [kbd]pma__bookmark[/kbd]'); +$strConfigServers_bookmarktable_name = __('Bookmark table'); +$strConfigServers_column_info_desc = __('Leave blank for no column comments/mime types, suggested: [kbd]pma__column_info[/kbd]'); +$strConfigServers_column_info_name = __('Column information table'); +$strConfigServers_compress_desc = __('Compress connection to MySQL server'); +$strConfigServers_compress_name = __('Compress connection'); +$strConfigServers_connect_type_desc = __('How to connect to server, keep [kbd]tcp[/kbd] if unsure'); +$strConfigServers_connect_type_name = __('Connection type'); +$strConfigServers_controlpass_name = __('Control user password'); +$strConfigServers_controluser_desc = __('A special MySQL user configured with limited permissions, more information available on [a@http://wiki.phpmyadmin.net/pma/controluser]wiki[/a]'); +$strConfigServers_controluser_name = __('Control user'); +$strConfigServers_controlhost_desc = __('An alternate host to hold the configuration storage; leave blank to use the already defined host'); +$strConfigServers_controlhost_name = __('Control host'); +$strConfigServers_designer_coords_desc = __('Leave blank for no Designer support, suggested: [kbd]pma__designer_coords[/kbd]'); +$strConfigServers_designer_coords_name = __('Designer table'); +$strConfigServers_DisableIS_desc = __('More information on [a@https://sourceforge.net/p/phpmyadmin/bugs/2606/]PMA bug tracker[/a] and [a@http://bugs.mysql.com/19588]MySQL Bugs[/a]'); +$strConfigServers_DisableIS_name = __('Disable use of INFORMATION_SCHEMA'); +$strConfigServers_extension_desc = __('What PHP extension to use; you should use mysqli if supported'); +$strConfigServers_extension_name = __('PHP extension to use'); +$strConfigServers_hide_db_desc = __('Hide databases matching regular expression (PCRE)'); +$strConfigServers_hide_db_name = __('Hide databases'); +$strConfigServers_history_desc = __('Leave blank for no SQL query history support, suggested: [kbd]pma__history[/kbd]'); +$strConfigServers_history_name = __('SQL query history table'); +$strConfigServers_host_desc = __('Hostname where MySQL server is running'); +$strConfigServers_host_name = __('Server hostname'); +$strConfigServers_LogoutURL_name = __('Logout URL'); +$strConfigServers_MaxTableUiprefs_desc = __('Limits number of table preferences which are stored in database, the oldest records are automatically removed'); +$strConfigServers_MaxTableUiprefs_name = __('Maximal number of table preferences to store'); +$strConfigServers_nopassword_desc = __('Try to connect without password'); +$strConfigServers_nopassword_name = __('Connect without password'); +$strConfigServers_only_db_desc = __('You can use MySQL wildcard characters (% and _), escape them if you want to use their literal instances, i.e. use [kbd]\'my\_db\'[/kbd] and not [kbd]\'my_db\'[/kbd].'); +$strConfigServers_only_db_name = __('Show only listed databases'); +$strConfigServers_password_desc = __('Leave empty if not using config auth'); +$strConfigServers_password_name = __('Password for config auth'); +$strConfigServers_pdf_pages_desc = __('Leave blank for no PDF schema support, suggested: [kbd]pma__pdf_pages[/kbd]'); +$strConfigServers_pdf_pages_name = __('PDF schema: pages table'); +$strConfigServers_pmadb_desc = __('Database used for relations, bookmarks, and PDF features. See [a@http://wiki.phpmyadmin.net/pma/pmadb]pmadb[/a] for complete information. Leave blank for no support. Suggested: [kbd]phpmyadmin[/kbd]'); +$strConfigServers_pmadb_name = __('Database name'); +$strConfigServers_port_desc = __('Port on which MySQL server is listening, leave empty for default'); +$strConfigServers_port_name = __('Server port'); +$strConfigServers_recent_desc = __('Leave blank for no "persistent" recently used tables across sessions, suggested: [kbd]pma__recent[/kbd]'); +$strConfigServers_recent_name = __('Recently used table'); +$strConfigServers_relation_desc = __('Leave blank for no [a@http://wiki.phpmyadmin.net/pma/relation]relation-links[/a] support, suggested: [kbd]pma__relation[/kbd]'); +$strConfigServers_relation_name = __('Relation table'); +$strConfigServers_ShowDatabasesCommand_desc = __('SQL command to fetch available databases'); +$strConfigServers_ShowDatabasesCommand_name = __('SHOW DATABASES command'); +$strConfigServers_SignonSession_desc = __('See [a@http://wiki.phpmyadmin.net/pma/auth_types#signon]authentication types[/a] for an example'); +$strConfigServers_SignonSession_name = __('Signon session name'); +$strConfigServers_SignonURL_name = __('Signon URL'); +$strConfigServers_socket_desc = __('Socket on which MySQL server is listening, leave empty for default'); +$strConfigServers_socket_name = __('Server socket'); +$strConfigServers_ssl_desc = __('Enable SSL for connection to MySQL server'); +$strConfigServers_ssl_name = __('Use SSL'); +$strConfigServers_table_coords_desc = __('Leave blank for no PDF schema support, suggested: [kbd]pma__table_coords[/kbd]'); +$strConfigServers_table_coords_name = __('PDF schema: table coordinates'); +$strConfigServers_table_info_desc = __('Table to describe the display columns, leave blank for no support; suggested: [kbd]pma__table_info[/kbd]'); +$strConfigServers_table_info_name = __('Display columns table'); +$strConfigServers_table_uiprefs_desc = __('Leave blank for no "persistent" tables\'UI preferences across sessions, suggested: [kbd]pma__table_uiprefs[/kbd]'); +$strConfigServers_table_uiprefs_name = __('UI preferences table'); +$strConfigServers_tracking_add_drop_database_desc = __('Whether a DROP DATABASE IF EXISTS statement will be added as first line to the log when creating a database.'); +$strConfigServers_tracking_add_drop_database_name = __('Add DROP DATABASE'); +$strConfigServers_tracking_add_drop_table_desc = __('Whether a DROP TABLE IF EXISTS statement will be added as first line to the log when creating a table.'); +$strConfigServers_tracking_add_drop_table_name = __('Add DROP TABLE'); +$strConfigServers_tracking_add_drop_view_desc = __('Whether a DROP VIEW IF EXISTS statement will be added as first line to the log when creating a view.'); +$strConfigServers_tracking_add_drop_view_name = __('Add DROP VIEW'); +$strConfigServers_tracking_default_statements_desc = __('Defines the list of statements the auto-creation uses for new versions.'); +$strConfigServers_tracking_default_statements_name = __('Statements to track'); +$strConfigServers_tracking_desc = __('Leave blank for no SQL query tracking support, suggested: [kbd]pma__tracking[/kbd]'); +$strConfigServers_tracking_name = __('SQL query tracking table'); +$strConfigServers_tracking_version_auto_create_desc = __('Whether the tracking mechanism creates versions for tables and views automatically.'); +$strConfigServers_tracking_version_auto_create_name = __('Automatically create versions'); +$strConfigServers_userconfig_desc = __('Leave blank for no user preferences storage in database, suggested: [kbd]pma__userconfig[/kbd]'); +$strConfigServers_userconfig_name = __('User preferences storage table'); +$strConfigServers_user_desc = __('Leave empty if not using config auth'); +$strConfigServers_user_name = __('User for config auth'); +$strConfigServers_verbose_desc = __('A user-friendly description of this server. Leave blank to display the hostname instead.'); +$strConfigServers_verbose_name = __('Verbose name of this server'); +$strConfigShowAll_desc = __('Whether a user should be displayed a "show all (rows)" button'); +$strConfigShowAll_name = __('Allow to display all the rows'); +$strConfigShowChgPassword_desc = __('Please note that enabling this has no effect with [kbd]config[/kbd] authentication mode because the password is hard coded in the configuration file; this does not limit the ability to execute the same command directly'); +$strConfigShowChgPassword_name = __('Show password change form'); +$strConfigShowCreateDb_name = __('Show create database form'); +$strConfigShowDbStructureCreation_desc = __('Show or hide a column displaying the Creation timestamp for all tables'); +$strConfigShowDbStructureCreation_name = __('Show Creation timestamp'); +$strConfigShowDbStructureLastUpdate_desc = __('Show or hide a column displaying the Last update timestamp for all tables'); +$strConfigShowDbStructureLastUpdate_name = __('Show Last update timestamp'); +$strConfigShowDbStructureLastCheck_desc = __('Show or hide a column displaying the Last check timestamp for all tables'); +$strConfigShowDbStructureLastCheck_name = __('Show Last check timestamp'); +$strConfigShowDisplayDirection_desc = __('Defines whether or not type display direction option is shown when browsing a table'); +$strConfigShowDisplayDirection_name = __('Show display direction'); +$strConfigShowFieldTypesInDataEditView_desc = __('Defines whether or not type fields should be initially displayed in edit/insert mode'); +$strConfigShowFieldTypesInDataEditView_name = __('Show field types'); +$strConfigShowFunctionFields_desc = __('Display the function fields in edit/insert mode'); +$strConfigShowFunctionFields_name = __('Show function fields'); +$strConfigShowHint_desc = __('Whether to show hint or not'); +$strConfigShowHint_name = __('Show hint'); +$strConfigShowPhpInfo_desc = __('Shows link to [a@http://php.net/manual/function.phpinfo.php]phpinfo()[/a] output'); +$strConfigShowPhpInfo_name = __('Show phpinfo() link'); +$strConfigShowServerInfo_name = __('Show detailed MySQL server information'); +$strConfigShowSQL_desc = __('Defines whether SQL queries generated by phpMyAdmin should be displayed'); +$strConfigShowSQL_name = __('Show SQL queries'); +$strConfigRetainQueryBox_desc = __('Defines whether the query box should stay on-screen after its submission'); +$strConfigRetainQueryBox_name = __('Retain query box'); +$strConfigShowStats_desc = __('Allow to display database and table statistics (eg. space usage)'); +$strConfigShowStats_name = __('Show statistics'); +$strConfigSkipLockedTables_desc = __('Mark used tables and make it possible to show databases with locked tables'); +$strConfigSkipLockedTables_name = __('Skip locked tables'); +$strConfigSQLQuery_Edit_name = __('Edit'); +$strConfigSQLQuery_Explain_name = __('Explain SQL'); +$strConfigSQLQuery_Refresh_name = __('Refresh'); +$strConfigSQLQuery_ShowAsPHP_name = __('Create PHP Code'); +$strConfigSQLQuery_Validate_desc = __('Requires SQL Validator to be enabled'); +$strConfigSQLQuery_Validate_name = __('Validate SQL'); +$strConfigSQLValidator_password_name = __('Password'); +$strConfigSQLValidator_use_desc = __('[strong]Warning:[/strong] requires PHP SOAP extension or PEAR SOAP to be installed'); +$strConfigSQLValidator_use_name = __('Enable SQL Validator'); +$strConfigSQLValidator_username_desc = __('If you have a custom username, specify it here (defaults to [kbd]anonymous[/kbd])'); +$strConfigSQLValidator_username_name = __('Username'); +$strConfigSuhosinDisableWarning_desc = __('A warning is displayed on the main page if Suhosin is detected'); +$strConfigSuhosinDisableWarning_name = __('Suhosin warning'); +$strConfigTextareaCols_desc = __('Textarea size (columns) in edit mode, this value will be emphasized for SQL query textareas (*2) and for query window (*1.25)'); +$strConfigTextareaCols_name = __('Textarea columns'); +$strConfigTextareaRows_desc = __('Textarea size (rows) in edit mode, this value will be emphasized for SQL query textareas (*2) and for query window (*1.25)'); +$strConfigTextareaRows_name = __('Textarea rows'); +$strConfigTitleDatabase_desc = __('Title of browser window when a database is selected'); +$strConfigTitleDatabase_name = __('Database'); +$strConfigTitleDefault_desc = __('Title of browser window when nothing is selected'); +$strConfigTitleDefault_name = __('Default title'); +$strConfigTitleServer_desc = __('Title of browser window when a server is selected'); +$strConfigTitleServer_name = __('Server'); +$strConfigTitleTable_desc = __('Title of browser window when a table is selected'); +$strConfigTitleTable_name = __('Table'); +$strConfigTrustedProxies_desc = __('Input proxies as [kbd]IP: trusted HTTP header[/kbd]. The following example specifies that phpMyAdmin should trust a HTTP_X_FORWARDED_FOR (X-Forwarded-For) header coming from the proxy 1.2.3.4:[br][kbd]1.2.3.4: HTTP_X_FORWARDED_FOR[/kbd]'); +$strConfigTrustedProxies_name = __('List of trusted proxies for IP allow/deny'); +$strConfigUploadDir_desc = __('Directory on server where you can upload files for import'); +$strConfigUploadDir_name = __('Upload directory'); +$strConfigUseDbSearch_desc = __('Allow for searching inside the entire database'); +$strConfigUseDbSearch_name = __('Use database search'); +$strConfigUserprefsDeveloperTab_desc = __('When disabled, users cannot set any of the options below, regardless of the checkbox on the right'); +$strConfigUserprefsDeveloperTab_name = __('Enable the Developer tab in settings'); +$strConfigVersionCheckLink = __('Check for latest version'); +$strConfigVersionCheck_desc = __('Enables check for latest version on main phpMyAdmin page'); +$strConfigVersionCheck_name = __('Version check'); +$strConfigZipDump_desc = __('Enable [a@http://en.wikipedia.org/wiki/ZIP_(file_format)]ZIP[/a] compression for import and export operations'); +$strConfigZipDump_name = __('ZIP'); + +?> diff --git a/hugo/libraries/config/setup.forms.php b/hugo/libraries/config/setup.forms.php new file mode 100644 index 0000000..1d40e0f --- /dev/null +++ b/hugo/libraries/config/setup.forms.php @@ -0,0 +1,369 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * List of avaible forms, each form is described as an array of fields to display. + * Fields MUST have their counterparts in the $cfg array. + * + * There are two possible notations: + * $forms['Form group']['Form name'] = array('Servers' => array(1 => array('host'))); + * can be written as + * $forms['Form group']['Form name'] = array('Servers/1/host'); + * + * You can assign default values set by special button ("set value: ..."), eg.: + * 'Servers/1/pmadb' => 'phpmyadmin' + * + * To group options, use: + * ':group:' . __('group name') // just define a group + * or + * 'option' => ':group' // group starting from this option + * End group blocks with: + * ':group:end' + * + * @package PhpMyAdmin-Setup + */ + +$forms = array(); +$forms['_config.php'] = array( + 'DefaultLang', + 'ServerDefault'); +$forms['Servers']['Server'] = array('Servers' => array(1 => array( + 'verbose', + 'host', + 'port', + 'socket', + 'ssl', + 'connect_type', + 'extension', + 'compress', + 'nopassword'))); +$forms['Servers']['Server_auth'] = array('Servers' => array(1 => array( + 'auth_type', + ':group:' . __('Config authentication'), + 'user', + 'password', + ':group:end', + ':group:' . __('Cookie authentication'), + 'auth_swekey_config' => './swekey.conf', + ':group:end', + ':group:' . __('HTTP authentication'), + 'auth_http_realm', + ':group:end', + ':group:' . __('Signon authentication'), + 'SignonSession', + 'SignonURL', + 'LogoutURL'))); +$forms['Servers']['Server_config'] = array('Servers' => array(1 => array( + 'only_db', + 'hide_db', + 'AllowRoot', + 'AllowNoPassword', + 'DisableIS', + 'AllowDeny/order', + 'AllowDeny/rules', + 'ShowDatabasesCommand'))); +$forms['Servers']['Server_pmadb'] = array('Servers' => array(1 => array( + 'pmadb' => 'phpmyadmin', + 'controlhost', + 'controluser', + 'controlpass', + 'bookmarktable' => 'pma__bookmark', + 'relation' => 'pma__relation', + 'userconfig' => 'pma__userconfig', + 'table_info' => 'pma__table_info', + 'column_info' => 'pma__column_info', + 'history' => 'pma__history', + 'recent' => 'pma__recent', + 'table_uiprefs' => 'pma__table_uiprefs', + 'tracking' => 'pma__tracking', + 'table_coords' => 'pma__table_coords', + 'pdf_pages' => 'pma__pdf_pages', + 'designer_coords' => 'pma__designer_coords', + 'MaxTableUiprefs' => 100))); +$forms['Servers']['Server_tracking'] = array('Servers' => array(1 => array( + 'tracking_version_auto_create', + 'tracking_default_statements', + 'tracking_add_drop_view', + 'tracking_add_drop_table', + 'tracking_add_drop_database', +))); +$forms['Features']['Import_export'] = array( + 'UploadDir', + 'SaveDir', + 'RecodingEngine' => ':group', + 'IconvExtraParams', + ':group:end', + 'ZipDump', + 'GZipDump', + 'BZipDump', + 'CompressOnFly'); +$forms['Features']['Security'] = array( + 'blowfish_secret', + 'ForceSSL', + 'CheckConfigurationPermissions', + 'TrustedProxies', + 'AllowUserDropDatabase', + 'AllowArbitraryServer', + 'LoginCookieRecall', + 'LoginCookieValidity', + 'LoginCookieStore', + 'LoginCookieDeleteAll'); +$forms['Features']['Page_titles'] = array( + 'TitleDefault', + 'TitleTable', + 'TitleDatabase', + 'TitleServer'); +$forms['Features']['Warnings'] = array( + 'ServerLibraryDifference_DisableWarning', + 'PmaNoRelation_DisableWarning', + 'SuhosinDisableWarning', + 'McryptDisableWarning'); +$forms['Features']['Developer'] = array( + 'UserprefsDeveloperTab', + 'Error_Handler/display', + 'Error_Handler/gather', + 'DBG/sql'); +$forms['Features']['Other_core_settings'] = array( + 'VersionCheck', + 'NaturalOrder', + 'InitialSlidersState', + 'MaxDbList', + 'MaxTableList', + 'NumRecentTables', + 'ShowHint', + 'OBGzip', + 'PersistentConnections', + 'ExecTimeLimit', + 'MemoryLimit', + 'SkipLockedTables', + 'DisableMultiTableMaintenance', + 'UseDbSearch', + 'AllowThirdPartyFraming'); +$forms['Sql_queries']['Sql_queries'] = array( + 'ShowSQL', + 'Confirm', + 'QueryHistoryDB', + 'QueryHistoryMax', + 'IgnoreMultiSubmitErrors', + 'MaxCharactersInDisplayedSQL', + 'EditInWindow', + //'QueryWindowWidth', // overridden in theme + //'QueryWindowHeight', + 'QueryWindowDefTab', + 'RetainQueryBox', + 'CodemirrorEnable'); +$forms['Sql_queries']['Sql_box'] = array('SQLQuery' => array( + 'Edit', + 'Explain', + 'ShowAsPHP', + 'Validate', + 'Refresh')); +$forms['Sql_queries']['Sql_validator'] = array('SQLValidator' => array( + 'use', + 'username', + 'password')); +$forms['Navi_panel']['Navi_panel'] = array( + 'NavigationDisplayLogo', + 'NavigationLogoLink', + 'NavigationLogoLinkWindow', + 'NavigationTreePointerEnable', + 'MaxNavigationItems', + 'NavigationTreeEnableGrouping', + 'NavigationTreeDisplayItemFilterMinimum'); +$forms['Navi_panel']['Navi_servers'] = array( + 'NavigationDisplayServers', + 'DisplayServersList'); +$forms['Navi_panel']['Navi_databases'] = array( + 'NavigationTreeDbSeparator'); +$forms['Navi_panel']['Navi_tables'] = array( + 'NavigationTreeDefaultTabTable', + 'NavigationTreeTableSeparator', + 'NavigationTreeTableLevel', +); +$forms['Main_panel']['Startup'] = array( + 'ShowCreateDb', + 'ShowStats', + 'ShowServerInfo', + 'ShowPhpInfo', + 'ShowChgPassword'); +$forms['Main_panel']['DbStructure'] = array( + 'ShowDbStructureCreation', + 'ShowDbStructureLastUpdate', + 'ShowDbStructureLastCheck'); +$forms['Main_panel']['TableStructure'] = array( + 'HideStructureActions'); +$forms['Main_panel']['Browse'] = array( + 'TableNavigationLinksMode', + 'ShowAll', + 'MaxRows', + 'Order', + 'BrowsePointerEnable', + 'BrowseMarkerEnable', + 'GridEditing', + 'SaveCellsAtOnce', + 'ShowDisplayDirection', + 'RepeatCells', + 'LimitChars', + 'RowActionLinks', + 'DefaultDisplay', + 'RememberSorting'); +$forms['Main_panel']['Edit'] = array( + 'ProtectBinary', + 'ShowFunctionFields', + 'ShowFieldTypesInDataEditView', + 'CharEditing', + 'MinSizeForInputField', + 'MaxSizeForInputField', + 'CharTextareaCols', + 'CharTextareaRows', + 'TextareaCols', + 'TextareaRows', + 'LongtextDoubleTextarea', + 'InsertRows', + 'ForeignKeyDropdownOrder', + 'ForeignKeyMaxLimit'); +$forms['Main_panel']['Tabs'] = array( + 'TabsMode', + 'ActionLinksMode', + 'DefaultTabServer', + 'DefaultTabDatabase', + 'DefaultTabTable', + 'QueryWindowDefTab'); +$forms['Import']['Import_defaults'] = array('Import' => array( + 'format', + 'charset', + 'allow_interrupt', + 'skip_queries')); +$forms['Import']['Sql'] = array('Import' => array( + 'sql_compatibility', + 'sql_no_auto_value_on_zero')); +$forms['Import']['Csv'] = array('Import' => array( + ':group:' . __('CSV'), + 'csv_replace', + 'csv_ignore', + 'csv_terminated', + 'csv_enclosed', + 'csv_escaped', + 'csv_col_names', + ':group:end', + ':group:' . __('CSV using LOAD DATA'), + 'ldi_replace', + 'ldi_ignore', + 'ldi_terminated', + 'ldi_enclosed', + 'ldi_escaped', + 'ldi_local_option', + ':group:end')); +$forms['Import']['Open_Document'] = array('Import' => array( + ':group:' . __('OpenDocument Spreadsheet'), + 'ods_col_names', + 'ods_empty_rows', + 'ods_recognize_percentages', + 'ods_recognize_currency')); +$forms['Export']['Export_defaults'] = array('Export' => array( + 'method', + ':group:' . __('Quick'), + 'quick_export_onserver', + 'quick_export_onserver_overwrite', + ':group:end', + ':group:' . __('Custom'), + 'format', + 'compression', + 'charset', + 'asfile' => ':group', + 'onserver', + 'onserver_overwrite', + ':group:end', + 'remember_file_template', + 'file_template_table', + 'file_template_database', + 'file_template_server')); +$forms['Export']['Sql'] = array('Export' => array( + 'sql_include_comments' => ':group', + 'sql_dates', + 'sql_relation', + 'sql_mime', + ':group:end', + 'sql_use_transaction', + 'sql_disable_fk', + 'sql_compatibility', + ':group:' . __('Database export options'), + 'sql_drop_database', + 'sql_structure_or_data', + ':group:end', + ':group:' . __('Structure'), + 'sql_drop_table', + 'sql_procedure_function', + 'sql_create_table_statements' => ':group', + 'sql_if_not_exists', + 'sql_auto_increment', + ':group:end', + 'sql_backquotes', + ':group:end', + ':group:' . __('Data'), + 'sql_delayed', + 'sql_ignore', + 'sql_type', + 'sql_insert_syntax', + 'sql_max_query_size', + 'sql_hex_for_blob', + 'sql_utc_time')); +$forms['Export']['CodeGen'] = array('Export' => array( + 'codegen_format')); +$forms['Export']['Csv'] = array('Export' => array( + ':group:' . __('CSV'), + 'csv_separator', + 'csv_enclosed', + 'csv_escaped', + 'csv_terminated', + 'csv_null', + 'csv_removeCRLF', + 'csv_columns', + ':group:end', + ':group:' . __('CSV for MS Excel'), + 'excel_null', + 'excel_removeCRLF', + 'excel_columns', + 'excel_edition')); +$forms['Export']['Latex'] = array('Export' => array( + 'latex_caption', + 'latex_structure_or_data', + ':group:' . __('Structure'), + 'latex_structure_caption', + 'latex_structure_continued_caption', + 'latex_structure_label', + 'latex_relation', + 'latex_comments', + 'latex_mime', + ':group:end', + ':group:' . __('Data'), + 'latex_columns', + 'latex_data_caption', + 'latex_data_continued_caption', + 'latex_data_label', + 'latex_null')); +$forms['Export']['Microsoft_Office'] = array('Export' => array( + ':group:' . __('Microsoft Word 2000'), + 'htmlword_structure_or_data', + 'htmlword_null', + 'htmlword_columns')); +$forms['Export']['Open_Document'] = array('Export' => array( + ':group:' . __('OpenDocument Spreadsheet'), + 'ods_columns', + 'ods_null', + ':group:end', + ':group:' . __('OpenDocument Text'), + 'odt_structure_or_data', + ':group:' . __('Structure'), + 'odt_relation', + 'odt_comments', + 'odt_mime', + ':group:end', + ':group:' . __('Data'), + 'odt_columns', + 'odt_null')); +$forms['Export']['Texy'] = array('Export' => array( + 'texytext_structure_or_data', + ':group:' . __('Data'), + 'texytext_null', + 'texytext_columns')); +?> diff --git a/hugo/libraries/config/user_preferences.forms.php b/hugo/libraries/config/user_preferences.forms.php new file mode 100644 index 0000000..ede3d2c --- /dev/null +++ b/hugo/libraries/config/user_preferences.forms.php @@ -0,0 +1,272 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * List of avaible forms, each form is described as an array of fields to display. + * Fields MUST have their counterparts in the $cfg array. + * + * To define form field, use the notatnion below: + * $forms['Form group']['Form name'] = array('Option/path'); + * + * You can assign default values set by special button ("set value: ..."), eg.: + * 'Servers/1/pmadb' => 'phpmyadmin' + * + * To group options, use: + * ':group:' . __('group name') // just define a group + * or + * 'option' => ':group' // group starting from this option + * End group blocks with: + * ':group:end' + * + * @package PhpMyAdmin + */ + +$forms = array(); +$forms['Features']['General'] = array( + 'VersionCheck', + 'NaturalOrder', + 'InitialSlidersState', + 'LoginCookieValidity', + 'Servers/1/only_db', // saves to Server/only_db + 'Servers/1/hide_db', // saves to Server/hide_db + 'SkipLockedTables', + 'DisableMultiTableMaintenance', + 'MaxDbList', + 'MaxTableList', + 'NumRecentTables', + 'ShowHint'); +$forms['Features']['Text_fields'] = array( + 'CharEditing', + 'MinSizeForInputField', + 'MaxSizeForInputField', + 'CharTextareaCols', + 'CharTextareaRows', + 'TextareaCols', + 'TextareaRows', + 'LongtextDoubleTextarea'); +$forms['Features']['Page_titles'] = array( + 'TitleDefault', + 'TitleTable', + 'TitleDatabase', + 'TitleServer'); +$forms['Features']['Warnings'] = array( + 'ServerLibraryDifference_DisableWarning', + 'PmaNoRelation_DisableWarning', + 'SuhosinDisableWarning', + 'McryptDisableWarning', + 'ReservedWordDisableWarning'); +// settings from this form are treated specially, +// see prefs_forms.php and user_preferences.lib.php +$forms['Features']['Developer'] = array( + 'Error_Handler/display', + 'Error_Handler/gather', + 'DBG/sql'); +$forms['Sql_queries']['Sql_queries'] = array( + 'ShowSQL', + 'Confirm', + 'QueryHistoryMax', + 'IgnoreMultiSubmitErrors', + 'MaxCharactersInDisplayedSQL', + 'EditInWindow', + //'QueryWindowWidth', // overridden in theme + //'QueryWindowHeight', + 'QueryWindowDefTab', + 'RetainQueryBox', + 'CodemirrorEnable'); +$forms['Sql_queries']['Sql_box'] = array( + 'SQLQuery/Edit', + 'SQLQuery/Explain', + 'SQLQuery/ShowAsPHP', + 'SQLQuery/Validate', + 'SQLQuery/Refresh'); +$forms['Navi_panel']['Navi_panel'] = array( + 'NavigationDisplayLogo', + 'NavigationLogoLink', + 'NavigationLogoLinkWindow', + 'NavigationTreePointerEnable', + 'MaxNavigationItems', + 'NavigationTreeEnableGrouping', + 'NavigationTreeDisplayItemFilterMinimum'); +$forms['Navi_panel']['Navi_databases'] = array( + 'NavigationTreeDisplayDbFilterMinimum', + 'NavigationTreeDbSeparator'); +$forms['Navi_panel']['Navi_tables'] = array( + 'NavigationTreeDefaultTabTable', + 'NavigationTreeTableSeparator', + 'NavigationTreeTableLevel', +); +$forms['Main_panel']['Startup'] = array( + 'ShowCreateDb', + 'ShowStats', + 'ShowServerInfo'); +$forms['Main_panel']['DbStructure'] = array( + 'ShowDbStructureCreation', + 'ShowDbStructureLastUpdate', + 'ShowDbStructureLastCheck'); +$forms['Main_panel']['TableStructure'] = array( + 'HideStructureActions'); +$forms['Main_panel']['Browse'] = array( + 'TableNavigationLinksMode', + 'ActionLinksMode', + 'ShowAll', + 'MaxRows', + 'Order', + 'DisplayBinaryAsHex', + 'BrowsePointerEnable', + 'BrowseMarkerEnable', + 'GridEditing', + 'SaveCellsAtOnce', + 'ShowDisplayDirection', + 'RepeatCells', + 'LimitChars', + 'RowActionLinks', + 'DefaultDisplay', + 'RememberSorting'); +$forms['Main_panel']['Edit'] = array( + 'ProtectBinary', + 'ShowFunctionFields', + 'ShowFieldTypesInDataEditView', + 'InsertRows', + 'ForeignKeyDropdownOrder', + 'ForeignKeyMaxLimit'); +$forms['Main_panel']['Tabs'] = array( + 'TabsMode', + 'DefaultTabServer', + 'DefaultTabDatabase', + 'DefaultTabTable'); +$forms['Import']['Import_defaults'] = array( + 'Import/format', + 'Import/charset', + 'Import/allow_interrupt', + 'Import/skip_queries'); +$forms['Import']['Sql'] = array( + 'Import/sql_compatibility', + 'Import/sql_no_auto_value_on_zero'); +$forms['Import']['Csv'] = array( + ':group:' . __('CSV'), + 'Import/csv_replace', + 'Import/csv_ignore', + 'Import/csv_terminated', + 'Import/csv_enclosed', + 'Import/csv_escaped', + 'Import/csv_col_names', + ':group:end', + ':group:' . __('CSV using LOAD DATA'), + 'Import/ldi_replace', + 'Import/ldi_ignore', + 'Import/ldi_terminated', + 'Import/ldi_enclosed', + 'Import/ldi_escaped', + 'Import/ldi_local_option'); +$forms['Import']['Open_Document'] = array( + ':group:' . __('OpenDocument Spreadsheet'), + 'Import/ods_col_names', + 'Import/ods_empty_rows', + 'Import/ods_recognize_percentages', + 'Import/ods_recognize_currency'); +$forms['Export']['Export_defaults'] = array( + 'Export/method', + ':group:' . __('Quick'), + 'Export/quick_export_onserver', + 'Export/quick_export_onserver_overwrite', + ':group:end', + ':group:' . __('Custom'), + 'Export/format', + 'Export/compression', + 'Export/charset', + 'Export/asfile' => ':group', + 'Export/onserver', + 'Export/onserver_overwrite', + ':group:end', + 'Export/file_template_table', + 'Export/file_template_database', + 'Export/file_template_server'); +$forms['Export']['Sql'] = array( + 'Export/sql_include_comments' => ':group', + 'Export/sql_dates', + 'Export/sql_relation', + 'Export/sql_mime', + ':group:end', + 'Export/sql_use_transaction', + 'Export/sql_disable_fk', + 'Export/sql_compatibility', + ':group:' . __('Database export options'), + 'Export/sql_drop_database', + 'Export/sql_structure_or_data', + ':group:end', + ':group:' . __('Structure'), + 'Export/sql_drop_table', + 'Export/sql_procedure_function', + 'Export/sql_create_table_statements' => ':group', + 'Export/sql_if_not_exists', + 'Export/sql_auto_increment', + ':group:end', + 'Export/sql_backquotes', + ':group:end', + ':group:' . __('Data'), + 'Export/sql_delayed', + 'Export/sql_ignore', + 'Export/sql_type', + 'Export/sql_insert_syntax', + 'Export/sql_max_query_size', + 'Export/sql_hex_for_blob', + 'Export/sql_utc_time'); +$forms['Export']['CodeGen'] = array( + 'Export/codegen_format'); +$forms['Export']['Csv'] = array( + ':group:' . __('CSV'), + 'Export/csv_separator', + 'Export/csv_enclosed', + 'Export/csv_escaped', + 'Export/csv_terminated', + 'Export/csv_null', + 'Export/csv_removeCRLF', + 'Export/csv_columns', + ':group:end', + ':group:' . __('CSV for MS Excel'), + 'Export/excel_null', + 'Export/excel_removeCRLF', + 'Export/excel_columns', + 'Export/excel_edition'); +$forms['Export']['Latex'] = array( + 'Export/latex_caption', + 'Export/latex_structure_or_data', + ':group:' . __('Structure'), + 'Export/latex_structure_caption', + 'Export/latex_structure_continued_caption', + 'Export/latex_structure_label', + 'Export/latex_relation', + 'Export/latex_comments', + 'Export/latex_mime', + ':group:end', + ':group:' . __('Data'), + 'Export/latex_columns', + 'Export/latex_data_caption', + 'Export/latex_data_continued_caption', + 'Export/latex_data_label', + 'Export/latex_null'); +$forms['Export']['Microsoft_Office'] = array( + ':group:' . __('Microsoft Word 2000'), + 'Export/htmlword_structure_or_data', + 'Export/htmlword_null', + 'Export/htmlword_columns'); +$forms['Export']['Open_Document'] = array( + ':group:' . __('OpenDocument Spreadsheet'), + 'Export/ods_columns', + 'Export/ods_null', + ':group:end', + ':group:' . __('OpenDocument Text'), + 'Export/odt_structure_or_data', + ':group:' . __('Structure'), + 'Export/odt_relation', + 'Export/odt_comments', + 'Export/odt_mime', + ':group:end', + ':group:' . __('Data'), + 'Export/odt_columns', + 'Export/odt_null'); +$forms['Export']['Texy'] = array( + 'Export/texytext_structure_or_data', + ':group:' . __('Data'), + 'Export/texytext_null', + 'Export/texytext_columns'); +?> diff --git a/hugo/libraries/config/validate.lib.php b/hugo/libraries/config/validate.lib.php new file mode 100644 index 0000000..8c62013 --- /dev/null +++ b/hugo/libraries/config/validate.lib.php @@ -0,0 +1,584 @@ +<?php +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * Various validation functions + * + * Validation function takes two argument: id for which it is called + * and array of fields' values (usually values for entire formset, as defined + * in forms.inc.php). + * The function must always return an array with an error (or error array) + * assigned to a form element (formset name or field path). Even if there are + * no errors, key must be set with an empty value. + * + * Valdiation functions are assigned in $cfg_db['_validators'] (config.values.php). + * + * @package PhpMyAdmin + */ + +/** + * Returns validator list + * + * @return array + */ +function PMA_config_get_validators() +{ + static $validators = null; + + if ($validators === null) { + $cf = ConfigFile::getInstance(); + $validators = $cf->getDbEntry('_validators', array()); + if (!defined('PMA_SETUP')) { + // not in setup script: load additional validators for user + // preferences we need original config values not overwritten + // by user preferences, creating a new PMA_Config instance is a + // better idea than hacking into its code + $org_cfg = $cf->getOrgConfigObj(); + $uvs = $cf->getDbEntry('_userValidators', array()); + foreach ($uvs as $field => $uv_list) { + $uv_list = (array)$uv_list; + foreach ($uv_list as &$uv) { + if (!is_array($uv)) { + continue; + } + for ($i = 1; $i < count($uv); $i++) { + if (substr($uv[$i], 0, 6) == 'value:') { + $uv[$i] = PMA_arrayRead( + substr($uv[$i], 6), $org_cfg->settings + ); + } + } + } + $validators[$field] = isset($validators[$field]) + ? array_merge((array)$validators[$field], $uv_list) + : $uv_list; + } + } + } + return $validators; +} + +/** + * Runs validation $validator_id on values $values and returns error list. + * + * Return values: + * o array, keys - field path or formset id, values - array of errors + * when $isPostSource is true values is an empty array to allow for error list + * cleanup in HTML documen + * o false - when no validators match name(s) given by $validator_id + * + * @param string|array $validator_id ID of validator(s) to run + * @param array &$values Values to validate + * @param bool $isPostSource tells whether $values are directly from + * POST request + * + * @return bool|array + */ +function PMA_config_validate($validator_id, &$values, $isPostSource) +{ + // find validators + $validator_id = (array) $validator_id; + $validators = PMA_config_get_validators(); + $vids = array(); + $cf = ConfigFile::getInstance(); + foreach ($validator_id as &$vid) { + $vid = $cf->getCanonicalPath($vid); + if (isset($validators[$vid])) { + $vids[] = $vid; + } + } + if (empty($vids)) { + return false; + } + + // create argument list with canonical paths and remember path mapping + $arguments = array(); + $key_map = array(); + foreach ($values as $k => $v) { + $k2 = $isPostSource ? str_replace('-', '/', $k) : $k; + $k2 = strpos($k2, '/') ? $cf->getCanonicalPath($k2) : $k2; + $key_map[$k2] = $k; + $arguments[$k2] = $v; + } + + // validate + $result = array(); + foreach ($vids as $vid) { + // call appropriate validation functions + foreach ((array)$validators[$vid] as $validator) { + $vdef = (array) $validator; + $vname = array_shift($vdef); + $args = array_merge(array($vid, &$arguments), $vdef); + $r = call_user_func_array($vname, $args); + + // merge results + if (is_array($r)) { + foreach ($r as $key => $error_list) { + // skip empty values if $isPostSource is false + if (!$isPostSource && empty($error_list)) { + continue; + } + if (!isset($result[$key])) { + $result[$key] = array(); + } + $result[$key] = array_merge($result[$key], (array)$error_list); + } + } + } + } + + // restore original paths + $new_result = array(); + foreach ($result as $k => $v) { + $k2 = isset($key_map[$k]) ? $key_map[$k] : $k; + $new_result[$k2] = $v; + } + return empty($new_result) ? true : $new_result; +} + +/** + * Empty error handler, used to temporarily restore PHP internal error handler + * + * @return bool + */ +function PMA_null_error_handler() +{ + return false; +} + +/** + * Ensures that $php_errormsg variable will be registered in case of an error + * and enables output buffering (when $start = true). + * Called with $start = false disables output buffering end restores + * html_errors and track_errors. + * + * @param boolean $start Whether to start buffering + * + * @return void + */ +function test_php_errormsg($start = true) +{ + static $old_html_errors, $old_track_errors, $old_error_reporting; + static $old_display_errors; + if ($start) { + $old_html_errors = ini_get('html_errors'); + $old_track_errors = ini_get('track_errors'); + $old_display_errors = ini_get('display_errors'); + $old_error_reporting = error_reporting(E_ALL); + ini_set('html_errors', false); + ini_set('track_errors', true); + ini_set('display_errors', true); + set_error_handler("PMA_null_error_handler"); + ob_start(); + } else { + ob_end_clean(); + restore_error_handler(); + error_reporting($old_error_reporting); + ini_set('html_errors', $old_html_errors); + ini_set('track_errors', $old_track_errors); + ini_set('display_errors', $old_display_errors); + } +} + +/** + * Test database connection + * + * @param string $extension 'drizzle', 'mysql' or 'mysqli' + * @param string $connect_type 'tcp' or 'socket' + * @param string $host host name + * @param string $port tcp port to use + * @param string $socket socket to use + * @param string $user username to use + * @param string $pass password to use + * @param string $error_key key to use in return array + * + * @return bool|array + */ +function test_db_connection( + $extension, + $connect_type, + $host, + $port, + $socket, + $user, + $pass = null, + $error_key = 'Server' +) { + // test_php_errormsg(); + $socket = empty($socket) || $connect_type == 'tcp' ? null : $socket; + $port = empty($port) || $connect_type == 'socket' ? null : ':' . $port; + $error = null; + if ($extension == 'drizzle') { + while (1) { + $drizzle = @drizzle_create(); + if (!$drizzle) { + $error = __('Could not initialize Drizzle connection library'); + break; + } + $conn = $socket + ? @drizzle_con_add_uds($socket, $user, $pass, null, 0) + : @drizzle_con_add_tcp( + $drizzle, $host, $port, $user, $pass, null, 0 + ); + if (!$conn) { + $error = __('Could not connect to Drizzle server'); + drizzle_free($drizzle); + break; + } + // connection object is set up but we have to send some query + // to actually connect + $res = @drizzle_query($conn, 'SELECT 1'); + if (!$res) { + $error = __('Could not connect to Drizzle server'); + } else { + drizzle_result_free($res); + } + drizzle_con_free($conn); + drizzle_free($drizzle); + break; + } + } else if ($extension == 'mysql') { + $conn = @mysql_connect($host . $socket . $port, $user, $pass); + if (!$conn) { + $error = __('Could not connect to MySQL server'); + } else { + mysql_close($conn); + } + } else { + $conn = @mysqli_connect($host, $user, $pass, null, $port, $socket); + if (!$conn) { + $error = __('Could not connect to MySQL server'); + } else { + mysqli_close($conn); + } + } + // test_php_errormsg(false); + if (isset($php_errormsg)) { + $error .= " - $php_errormsg"; + } + return is_null($error) ? true : array($error_key => $error); +} + +/** + * Validate server config + * + * @param string $path path to config, not used + * @param array $values config values + * + * @return array + */ +function validate_server($path, $values) +{ + $result = array( + 'Server' => '', + 'Servers/1/user' => '', + 'Servers/1/SignonSession' => '', + 'Servers/1/SignonURL' => '' + ); + $error = false; + if ($values['Servers/1/auth_type'] == 'config' + && empty($values['Servers/1/user']) + ) { + $result['Servers/1/user'] + = __('Empty username while using config authentication method'); + $error = true; + } + if ($values['Servers/1/auth_type'] == 'signon' + && empty($values['Servers/1/SignonSession']) + ) { + $result['Servers/1/SignonSession'] = __( + 'Empty signon session name ' + . 'while using signon authentication method' + ); + $error = true; + } + if ($values['Servers/1/auth_type'] == 'signon' + && empty($values['Servers/1/SignonURL']) + ) { + $result['Servers/1/SignonURL'] + = __('Empty signon URL while using signon authentication method'); + $error = true; + } + + if (!$error && $values['Servers/1/auth_type'] == 'config') { + $password = $values['Servers/1/nopassword'] ? null + : $values['Servers/1/password']; + $test = test_db_connection( + $values['Servers/1/extension'], + $values['Servers/1/connect_type'], + $values['Servers/1/host'], + $values['Servers/1/port'], + $values['Servers/1/socket'], + $values['Servers/1/user'], + $password, + 'Server' + ); + if ($test !== true) { + $result = array_merge($result, $test); + } + } + return $result; +} + +/** + * Validate pmadb config + * + * @param string $path path to config, not used + * @param array $values config values + * + * @return array + */ +function validate_pmadb($path, $values) +{ + $result = array( + 'Server_pmadb' => '', + 'Servers/1/controluser' => '', + 'Servers/1/controlpass' => '' + ); + $error = false; + + if ($values['Servers/1/pmadb'] == '') { + return $result; + } + + $result = array(); + if ($values['Servers/1/controluser'] == '') { + $result['Servers/1/controluser'] + = __('Empty phpMyAdmin control user while using pmadb'); + $error = true; + } + if ($values['Servers/1/controlpass'] == '') { + $result['Servers/1/controlpass'] + = __('Empty phpMyAdmin control user password while using pmadb'); + $error = true; + } + if (!$error) { + $test = test_db_connection( + $values['Servers/1/extension'], $values['Servers/1/connect_type'], + $values['Servers/1/host'], $values['Servers/1/port'], + $values['Servers/1/socket'], $values['Servers/1/controluser'], + $values['Servers/1/controlpass'], 'Server_pmadb' + ); + if ($test !== true) { + $result = array_merge($result, $test); + } + } + return $result; +} + + +/** + * Validates regular expression + * + * @param string $path path to config + * @param array $values config values + * + * @return array + */ +function validate_regex($path, $values) +{ + $result = array($path => ''); + + if ($values[$path] == '') { + return $result; + } + + test_php_errormsg(); + + $matches = array(); + // in libraries/List_Database.class.php _checkHideDatabase(), + // a '/' is used as the delimiter for hide_db + preg_match('/' . $values[$path] . '/', '', $matches); + + test_php_errormsg(false); + + if (isset($php_errormsg)) { + $error = preg_replace('/^preg_match\(\): /', '', $php_errormsg); + return array($path => $error); + } + + return $result; +} + +/** + * Validates TrustedProxies field + * + * @param string $path path to config + * @param array $values config values + * + * @return array + */ +function validate_trusted_proxies($path, $values) +{ + $result = array($path => array()); + + if (empty($values[$path])) { + return $result; + } + + if (is_array($values[$path])) { + // value already processed by FormDisplay::save + $lines = array(); + foreach ($values[$path] as $ip => $v) { + $lines[] = preg_match('/^-\d+$/', $ip) + ? $v + : $ip . ': ' . $v; + } + } else { + // AJAX validation + $lines = explode("\n", $values[$path]); + } + foreach ($lines as $line) { + $line = trim($line); + $matches = array(); + // we catch anything that may (or may not) be an IP + if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) { + $result[$path][] = __('Incorrect value') . ': ' . htmlspecialchars($line); + continue; + } + // now let's check whether we really have an IP address + if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false + && filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false + ) { + $ip = htmlspecialchars(trim($matches[1])); + $result[$path][] = sprintf(__('Incorrect IP address: %s'), $ip); + continue; + } + } + + return $result; +} + +/** + * Tests integer value + * + * @param string $path path to config + * @param array $values config values + * @param bool $allow_neg allow negative values + * @param bool $allow_zero allow zero + * @param int $max_value max allowed value + * @param string $error_string error message key: + * $GLOBALS["strConfig$error_lang_key"] + * + * @return string empty string if test is successful + */ +function test_number( + $path, + $values, + $allow_neg, + $allow_zero, + $max_value, + $error_string +) { + if ($values[$path] === '') { + return ''; + } + + if (intval($values[$path]) != $values[$path] + || (!$allow_neg && $values[$path] < 0) + || (!$allow_zero && $values[$path] == 0) + || $values[$path] > $max_value + ) { + return $error_string; + } + + return ''; +} + +/** + * Validates port number + * + * @param string $path path to config + * @param array $values config values + * + * @return array + */ +function validate_port_number($path, $values) +{ + return array( + $path => test_number( + $path, + $values, + false, + false, + 65535, + __('Not a valid port number') + ) + ); +} + +/** + * Validates positive number + * + * @param string $path path to config + * @param array $values config values + * + * @return array + */ +function validate_positive_number($path, $values) +{ + return array( + $path => test_number( + $path, + $values, + false, + false, + PHP_INT_MAX, + __('Not a positive number') + ) + ); +} + +/** + * Validates non-negative number + * + * @param string $path path to config + * @param array $values config values + * + * @return array + */ +function validate_non_negative_number($path, $values) +{ + return array( + $path => test_number( + $path, + $values, + false, + true, + PHP_INT_MAX, + __('Not a non-negative number') + ) + ); +} + +/** + * Validates value according to given regular expression + * Pattern and modifiers must be a valid for PCRE <b>and</b> JavaScript RegExp + * + * @param string $path path to config + * @param array $values config values + * @param string $regex regullar expression to match + * + * @return array + */ +function validate_by_regex($path, $values, $regex) +{ + $result = preg_match($regex, $values[$path]); + return array($path => ($result ? '' : __('Incorrect value'))); +} + +/** + * Validates upper bound for numeric inputs + * + * @param string $path path to config + * @param array $values config values + * @param int $max_value maximal allowed value + * + * @return array + */ +function validate_upper_bound($path, $values, $max_value) +{ + $result = $values[$path] <= $max_value; + return array($path => ($result ? '' + : sprintf(__('Value must be equal or lower than %s'), $max_value))); +} +?> |
