2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Various validation functions
6 * Validation function takes two argument: id for which it is called
7 * and array of fields' values (usually values for entire formset, as defined
9 * The function must always return an array with an error (or error array)
10 * assigned to a form element (formset name or field path). Even if there are
11 * no errors, key must be set with an empty value.
13 * Valdiation functions are assigned in $cfg_db['_validators'] (config.values.php).
19 * Returns validator list
21 * @uses ConfigFile::getDbEntry()
22 * @uses ConfigFile::getInstance()
25 function PMA_config_get_validators()
27 static $validators = null;
29 if ($validators === null) {
30 $cf = ConfigFile
::getInstance();
31 $validators = $cf->getDbEntry('_validators', array());
32 if (!defined('PMA_SETUP')) {
33 $uvs = $cf->getDbEntry('_userValidators', array());
34 foreach ($uvs as $field => $uv_list) {
35 $uv_list = (array)$uv_list;
36 foreach ($uv_list as &$uv) {
40 for ($i = 1; $i < count($uv); $i++
) {
41 if (substr($uv[$i], 0, 6) == 'value:') {
42 $uv[$i] = PMA_array_read(substr($uv[$i], 6), $GLOBALS['cfg']);
46 $validators[$field] = isset($validators[$field])
47 ?
array_merge((array)$validators[$field], $uv_list)
56 * Runs validation $validator_id on values $values and returns error list.
59 * o array, keys - field path or formset id, values - array of errors
60 * when $isPostSource is true values is an empty array to allow for error list
61 * cleanup in HTML documen
62 * o false - when no validators match name(s) given by $validator_id
64 * @uses ConfigFile::getCanonicalPath()
65 * @uses ConfigFile::getInstance()
66 * @uses PMA_config_get_validators()
67 * @param string|array $validator_id
68 * @param array $values
69 * @param bool $isPostSource tells whether $values are directly from POST request
72 function PMA_config_validate($validator_id, &$values, $isPostSource)
75 $validator_id = (array) $validator_id;
76 $validators = PMA_config_get_validators();
78 $cf = ConfigFile
::getInstance();
79 foreach ($validator_id as &$vid) {
80 $vid = $cf->getCanonicalPath($vid);
81 if (isset($validators[$vid])) {
89 // create argument list with canonical paths and remember path mapping
92 foreach ($values as $k => $v) {
93 $k2 = $isPostSource ?
str_replace('-', '/', $k) : $k;
94 $k2 = strpos($k2, '/') ?
$cf->getCanonicalPath($k2) : $k2;
101 foreach ($vids as $vid) {
102 // call appropriate validation functions
103 foreach ((array)$validators[$vid] as $validator) {
104 $vdef = (array) $validator;
105 $vname = array_shift($vdef);
106 $args = array_merge(array($vid, &$arguments), $vdef);
107 $r = call_user_func_array($vname, $args);
111 foreach ($r as $key => $error_list) {
112 // skip empty values if $isPostSource is false
113 if (!$isPostSource && empty($error_list)) {
116 if (!isset($result[$key])) {
117 $result[$key] = array();
119 $result[$key] = array_merge($result[$key], (array)$error_list);
125 // restore original paths
126 $new_result = array();
127 foreach ($result as $k => $v) {
128 $k2 = isset($key_map[$k]) ?
$key_map[$k] : $k;
129 $new_result[$k2] = $v;
131 return empty($new_result) ?
true : $new_result;
135 * Empty error handler, used to temporarily restore PHP internal error handler
139 function PMA_null_error_handler()
145 * Ensures that $php_errormsg variable will be registered in case of an error
146 * and enables output buffering (when $start = true).
147 * Called with $start = false disables output buffering end restores
148 * html_errors and track_errors.
150 * @param boolean $start
152 function test_php_errormsg($start = true)
154 static $old_html_errors, $old_track_errors, $old_error_reporting;
155 static $old_display_errors;
157 $old_html_errors = ini_get('html_errors');
158 $old_track_errors = ini_get('track_errors');
159 $old_display_errors = ini_get('display_errors');
160 $old_error_reporting = error_reporting(E_ALL
);
161 ini_set('html_errors', false);
162 ini_set('track_errors', true);
163 ini_set('display_errors', true);
164 set_error_handler("PMA_null_error_handler");
168 restore_error_handler();
169 error_reporting($old_error_reporting);
170 ini_set('html_errors', $old_html_errors);
171 ini_set('track_errors', $old_track_errors);
172 ini_set('display_errors', $old_display_errors);
177 * Test database connection
179 * @param string $extension 'mysql' or 'mysqli'
180 * @param string $connect_type 'tcp' or 'socket'
181 * @param string $host
182 * @param string $port
183 * @param string $socket
184 * @param string $user
185 * @param string $pass
186 * @param string $error_key
189 function test_db_connection($extension, $connect_type, $host, $port, $socket, $user, $pass = null, $error_key = 'Server')
191 // test_php_errormsg();
192 $socket = empty($socket) ||
$connect_type == 'tcp' ?
null : ':' . $socket;
193 $port = empty($port) ||
$connect_type == 'socket' ?
null : ':' . $port;
195 if ($extension == 'mysql') {
196 $conn = @mysql_connect
($host . $socket . $port, $user, $pass);
198 $error = __('Could not connect to MySQL server');
203 $conn = @mysqli_connect
($host, $user, $pass, null, $port, $socket);
205 $error = __('Could not connect to MySQL server');
210 // test_php_errormsg(false);
211 if (isset($php_errormsg)) {
212 $error .= " - $php_errormsg";
214 return is_null($error) ?
true : array($error_key => $error);
218 * Validate server config
220 * @uses test_db_connection()
221 * @param string $path
222 * @param array $values
225 function validate_server($path, $values)
227 $result = array('Server' => '', 'Servers/1/user' => '', 'Servers/1/SignonSession' => '', 'Servers/1/SignonURL' => '');
229 if ($values['Servers/1/auth_type'] == 'config' && empty($values['Servers/1/user'])) {
230 $result['Servers/1/user'] = __('Empty username while using config authentication method');
233 if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonSession'])) {
234 $result['Servers/1/SignonSession'] = __('Empty signon session name while using signon authentication method');
237 if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonURL'])) {
238 $result['Servers/1/SignonURL'] = __('Empty signon URL while using signon authentication method');
242 if (!$error && $values['Servers/1/auth_type'] == 'config') {
243 $password = $values['Servers/1/nopassword'] ?
null : $values['Servers/1/password'];
244 $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');
245 if ($test !== true) {
246 $result = array_merge($result, $test);
253 * Validate pmadb config
255 * @uses test_db_connection()
256 * @param string $path
257 * @param array $values
260 function validate_pmadb($path, $values)
262 //$tables = array('Servers/1/bookmarktable', 'Servers/1/relation', 'Servers/1/table_info', 'Servers/1/table_coords', 'Servers/1/pdf_pages', 'Servers/1/column_info', 'Servers/1/history', 'Servers/1/designer_coords');
263 $result = array('Server_pmadb' => '', 'Servers/1/controluser' => '', 'Servers/1/controlpass' => '');
266 if ($values['Servers/1/pmadb'] == '') {
271 if ($values['Servers/1/controluser'] == '') {
272 $result['Servers/1/controluser'] = __('Empty phpMyAdmin control user while using pmadb');
275 if ($values['Servers/1/controlpass'] == '') {
276 $result['Servers/1/controlpass'] = __('Empty phpMyAdmin control user password while using pmadb');
280 $test = test_db_connection($values['Servers/1/extension'], $values['Servers/1/connect_type'],
281 $values['Servers/1/host'], $values['Servers/1/port'], $values['Servers/1/socket'],
282 $values['Servers/1/controluser'], $values['Servers/1/controlpass'], 'Server_pmadb');
283 if ($test !== true) {
284 $result = array_merge($result, $test);
292 * Validates regular expression
294 * @uses test_php_errormsg()
295 * @param string $path
296 * @param array $values
299 function validate_regex($path, $values)
301 $result = array($path => '');
303 if ($values[$path] == '') {
310 preg_match($values[$path], '', $matches);
312 test_php_errormsg(false);
314 if (isset($php_errormsg)) {
315 $error = preg_replace('/^preg_match\(\): /', '', $php_errormsg);
316 return array($path => $error);
323 * Validates TrustedProxies field
325 * @param string $path
326 * @param array $values
329 function validate_trusted_proxies($path, $values)
331 $result = array($path => array());
333 if (empty($values[$path])) {
337 if (is_array($values[$path])) {
338 // value already processed by FormDisplay::save
340 foreach ($values[$path] as $ip => $v) {
341 $lines[] = preg_match('/^-\d+$/', $ip)
347 $lines = explode("\n", $values[$path]);
349 foreach ($lines as $line) {
352 // we catch anything that may (or may not) be an IP
353 if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) {
354 $result[$path][] = __('Incorrect value') . ': ' . $line;
357 // now let's check whether we really have an IP address
358 if (filter_var($matches[1], FILTER_VALIDATE_IP
, FILTER_FLAG_IPV4
) === false
359 && filter_var($matches[1], FILTER_VALIDATE_IP
, FILTER_FLAG_IPV6
) === false) {
360 $ip = htmlspecialchars(trim($matches[1]));
361 $result[$path][] = sprintf(__('Incorrect IP address: %s'), $ip);
370 * Tests integer value
372 * @param string $path
373 * @param array $values
374 * @param bool $allow_neg allow negative values
375 * @param bool $allow_zero allow zero
376 * @param int $max_value max allowed value
377 * @param string $error_string error message key: $GLOBALS["strConfig$error_lang_key"]
378 * @return string empty string if test is successful
380 function test_number($path, $values, $allow_neg, $allow_zero, $max_value, $error_string)
382 if ($values[$path] === '') {
386 if (intval($values[$path]) != $values[$path] ||
(!$allow_neg && $values[$path] < 0) ||
(!$allow_zero && $values[$path] == 0) ||
$values[$path] > $max_value) {
387 return $error_string;
394 * Validates port number
396 * @uses test_number()
397 * @param string $path
398 * @param array $values
401 function validate_port_number($path, $values)
403 return array($path => test_number($path, $values, false, false, 65535, __('Not a valid port number')));
407 * Validates positive number
409 * @uses test_number()
410 * @param string $path
411 * @param array $values
414 function validate_positive_number($path, $values)
416 return array($path => test_number($path, $values, false, false, PHP_INT_MAX
, __('Not a positive number')));
420 * Validates non-negative number
422 * @uses test_number()
423 * @param string $path
424 * @param array $values
427 function validate_non_negative_number($path, $values)
429 return array($path => test_number($path, $values, false, true, PHP_INT_MAX
, __('Not a non-negative number')));
433 * Validates value according to given regular expression
434 * Pattern and modifiers must be a valid for PCRE <b>and</b> JavaScript RegExp
436 * @param string $path
437 * @param array $values
438 * @param string $regex
441 function validate_by_regex($path, $values, $regex)
443 $result = preg_match($regex, $values[$path]);
444 return array($path => ($result ?
'' : __('Incorrect value')));
448 * Validates upper bound for numeric inputs
450 * @param string $path
451 * @param array $values
452 * @param int $max_value
455 function validate_upper_bound($path, $values, $max_value)
457 $result = $values[$path] <= $max_value;
458 return array($path => ($result ?
'' : sprintf(__('Value must be equal or lower than %s'), $max_value)));