Upgraded phpmyadmin to 4.0.4 (All Languages) - No modifications yet
[openemr.git] / phpmyadmin / libraries / config / validate.lib.php
blobcd03b6bed99d48abdb549e378620b138c848e2e3
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
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
8 * in forms.inc.php).
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).
15 * @package PhpMyAdmin
18 /**
19 * Returns validator list
21 * @return array
23 function PMA_config_get_validators()
25 static $validators = null;
27 if ($validators === null) {
28 $cf = ConfigFile::getInstance();
29 $validators = $cf->getDbEntry('_validators', array());
30 if (!defined('PMA_SETUP')) {
31 // not in setup script: load additional validators for user
32 // preferences we need original config values not overwritten
33 // by user preferences, creating a new PMA_Config instance is a
34 // better idea than hacking into its code
35 $org_cfg = $cf->getOrgConfigObj();
36 $uvs = $cf->getDbEntry('_userValidators', array());
37 foreach ($uvs as $field => $uv_list) {
38 $uv_list = (array)$uv_list;
39 foreach ($uv_list as &$uv) {
40 if (!is_array($uv)) {
41 continue;
43 for ($i = 1; $i < count($uv); $i++) {
44 if (substr($uv[$i], 0, 6) == 'value:') {
45 $uv[$i] = PMA_arrayRead(
46 substr($uv[$i], 6), $org_cfg->settings
51 $validators[$field] = isset($validators[$field])
52 ? array_merge((array)$validators[$field], $uv_list)
53 : $uv_list;
57 return $validators;
60 /**
61 * Runs validation $validator_id on values $values and returns error list.
63 * Return values:
64 * o array, keys - field path or formset id, values - array of errors
65 * when $isPostSource is true values is an empty array to allow for error list
66 * cleanup in HTML documen
67 * o false - when no validators match name(s) given by $validator_id
69 * @param string|array $validator_id ID of validator(s) to run
70 * @param array &$values Values to validate
71 * @param bool $isPostSource tells whether $values are directly from
72 * POST request
74 * @return bool|array
76 function PMA_config_validate($validator_id, &$values, $isPostSource)
78 // find validators
79 $validator_id = (array) $validator_id;
80 $validators = PMA_config_get_validators();
81 $vids = array();
82 $cf = ConfigFile::getInstance();
83 foreach ($validator_id as &$vid) {
84 $vid = $cf->getCanonicalPath($vid);
85 if (isset($validators[$vid])) {
86 $vids[] = $vid;
89 if (empty($vids)) {
90 return false;
93 // create argument list with canonical paths and remember path mapping
94 $arguments = array();
95 $key_map = array();
96 foreach ($values as $k => $v) {
97 $k2 = $isPostSource ? str_replace('-', '/', $k) : $k;
98 $k2 = strpos($k2, '/') ? $cf->getCanonicalPath($k2) : $k2;
99 $key_map[$k2] = $k;
100 $arguments[$k2] = $v;
103 // validate
104 $result = array();
105 foreach ($vids as $vid) {
106 // call appropriate validation functions
107 foreach ((array)$validators[$vid] as $validator) {
108 $vdef = (array) $validator;
109 $vname = array_shift($vdef);
110 $args = array_merge(array($vid, &$arguments), $vdef);
111 $r = call_user_func_array($vname, $args);
113 // merge results
114 if (is_array($r)) {
115 foreach ($r as $key => $error_list) {
116 // skip empty values if $isPostSource is false
117 if (!$isPostSource && empty($error_list)) {
118 continue;
120 if (!isset($result[$key])) {
121 $result[$key] = array();
123 $result[$key] = array_merge($result[$key], (array)$error_list);
129 // restore original paths
130 $new_result = array();
131 foreach ($result as $k => $v) {
132 $k2 = isset($key_map[$k]) ? $key_map[$k] : $k;
133 $new_result[$k2] = $v;
135 return empty($new_result) ? true : $new_result;
139 * Empty error handler, used to temporarily restore PHP internal error handler
141 * @return bool
143 function PMA_null_error_handler()
145 return false;
149 * Ensures that $php_errormsg variable will be registered in case of an error
150 * and enables output buffering (when $start = true).
151 * Called with $start = false disables output buffering end restores
152 * html_errors and track_errors.
154 * @param boolean $start Whether to start buffering
156 * @return void
158 function test_php_errormsg($start = true)
160 static $old_html_errors, $old_track_errors, $old_error_reporting;
161 static $old_display_errors;
162 if ($start) {
163 $old_html_errors = ini_get('html_errors');
164 $old_track_errors = ini_get('track_errors');
165 $old_display_errors = ini_get('display_errors');
166 $old_error_reporting = error_reporting(E_ALL);
167 ini_set('html_errors', false);
168 ini_set('track_errors', true);
169 ini_set('display_errors', true);
170 set_error_handler("PMA_null_error_handler");
171 ob_start();
172 } else {
173 ob_end_clean();
174 restore_error_handler();
175 error_reporting($old_error_reporting);
176 ini_set('html_errors', $old_html_errors);
177 ini_set('track_errors', $old_track_errors);
178 ini_set('display_errors', $old_display_errors);
183 * Test database connection
185 * @param string $extension 'drizzle', 'mysql' or 'mysqli'
186 * @param string $connect_type 'tcp' or 'socket'
187 * @param string $host host name
188 * @param string $port tcp port to use
189 * @param string $socket socket to use
190 * @param string $user username to use
191 * @param string $pass password to use
192 * @param string $error_key key to use in return array
194 * @return bool|array
196 function test_db_connection(
197 $extension,
198 $connect_type,
199 $host,
200 $port,
201 $socket,
202 $user,
203 $pass = null,
204 $error_key = 'Server'
206 // test_php_errormsg();
207 $socket = empty($socket) || $connect_type == 'tcp' ? null : $socket;
208 $port = empty($port) || $connect_type == 'socket' ? null : ':' . $port;
209 $error = null;
210 if ($extension == 'drizzle') {
211 while (1) {
212 $drizzle = @drizzle_create();
213 if (!$drizzle) {
214 $error = __('Could not initialize Drizzle connection library');
215 break;
217 $conn = $socket
218 ? @drizzle_con_add_uds($socket, $user, $pass, null, 0)
219 : @drizzle_con_add_tcp(
220 $drizzle, $host, $port, $user, $pass, null, 0
222 if (!$conn) {
223 $error = __('Could not connect to Drizzle server');
224 drizzle_free($drizzle);
225 break;
227 // connection object is set up but we have to send some query
228 // to actually connect
229 $res = @drizzle_query($conn, 'SELECT 1');
230 if (!$res) {
231 $error = __('Could not connect to Drizzle server');
232 } else {
233 drizzle_result_free($res);
235 drizzle_con_free($conn);
236 drizzle_free($drizzle);
237 break;
239 } else if ($extension == 'mysql') {
240 $conn = @mysql_connect($host . $socket . $port, $user, $pass);
241 if (!$conn) {
242 $error = __('Could not connect to MySQL server');
243 } else {
244 mysql_close($conn);
246 } else {
247 $conn = @mysqli_connect($host, $user, $pass, null, $port, $socket);
248 if (!$conn) {
249 $error = __('Could not connect to MySQL server');
250 } else {
251 mysqli_close($conn);
254 // test_php_errormsg(false);
255 if (isset($php_errormsg)) {
256 $error .= " - $php_errormsg";
258 return is_null($error) ? true : array($error_key => $error);
262 * Validate server config
264 * @param string $path path to config, not used
265 * @param array $values config values
267 * @return array
269 function validate_server($path, $values)
271 $result = array(
272 'Server' => '',
273 'Servers/1/user' => '',
274 'Servers/1/SignonSession' => '',
275 'Servers/1/SignonURL' => ''
277 $error = false;
278 if ($values['Servers/1/auth_type'] == 'config'
279 && empty($values['Servers/1/user'])
281 $result['Servers/1/user']
282 = __('Empty username while using config authentication method');
283 $error = true;
285 if ($values['Servers/1/auth_type'] == 'signon'
286 && empty($values['Servers/1/SignonSession'])
288 $result['Servers/1/SignonSession'] = __(
289 'Empty signon session name '
290 . 'while using signon authentication method'
292 $error = true;
294 if ($values['Servers/1/auth_type'] == 'signon'
295 && empty($values['Servers/1/SignonURL'])
297 $result['Servers/1/SignonURL']
298 = __('Empty signon URL while using signon authentication method');
299 $error = true;
302 if (!$error && $values['Servers/1/auth_type'] == 'config') {
303 $password = $values['Servers/1/nopassword'] ? null
304 : $values['Servers/1/password'];
305 $test = test_db_connection(
306 $values['Servers/1/extension'],
307 $values['Servers/1/connect_type'],
308 $values['Servers/1/host'],
309 $values['Servers/1/port'],
310 $values['Servers/1/socket'],
311 $values['Servers/1/user'],
312 $password,
313 'Server'
315 if ($test !== true) {
316 $result = array_merge($result, $test);
319 return $result;
323 * Validate pmadb config
325 * @param string $path path to config, not used
326 * @param array $values config values
328 * @return array
330 function validate_pmadb($path, $values)
332 $result = array(
333 'Server_pmadb' => '',
334 'Servers/1/controluser' => '',
335 'Servers/1/controlpass' => ''
337 $error = false;
339 if ($values['Servers/1/pmadb'] == '') {
340 return $result;
343 $result = array();
344 if ($values['Servers/1/controluser'] == '') {
345 $result['Servers/1/controluser']
346 = __('Empty phpMyAdmin control user while using pmadb');
347 $error = true;
349 if ($values['Servers/1/controlpass'] == '') {
350 $result['Servers/1/controlpass']
351 = __('Empty phpMyAdmin control user password while using pmadb');
352 $error = true;
354 if (!$error) {
355 $test = test_db_connection(
356 $values['Servers/1/extension'], $values['Servers/1/connect_type'],
357 $values['Servers/1/host'], $values['Servers/1/port'],
358 $values['Servers/1/socket'], $values['Servers/1/controluser'],
359 $values['Servers/1/controlpass'], 'Server_pmadb'
361 if ($test !== true) {
362 $result = array_merge($result, $test);
365 return $result;
370 * Validates regular expression
372 * @param string $path path to config
373 * @param array $values config values
375 * @return array
377 function validate_regex($path, $values)
379 $result = array($path => '');
381 if ($values[$path] == '') {
382 return $result;
385 test_php_errormsg();
387 $matches = array();
388 // in libraries/List_Database.class.php _checkHideDatabase(),
389 // a '/' is used as the delimiter for hide_db
390 preg_match('/' . $values[$path] . '/', '', $matches);
392 test_php_errormsg(false);
394 if (isset($php_errormsg)) {
395 $error = preg_replace('/^preg_match\(\): /', '', $php_errormsg);
396 return array($path => $error);
399 return $result;
403 * Validates TrustedProxies field
405 * @param string $path path to config
406 * @param array $values config values
408 * @return array
410 function validate_trusted_proxies($path, $values)
412 $result = array($path => array());
414 if (empty($values[$path])) {
415 return $result;
418 if (is_array($values[$path])) {
419 // value already processed by FormDisplay::save
420 $lines = array();
421 foreach ($values[$path] as $ip => $v) {
422 $lines[] = preg_match('/^-\d+$/', $ip)
423 ? $v
424 : $ip . ': ' . $v;
426 } else {
427 // AJAX validation
428 $lines = explode("\n", $values[$path]);
430 foreach ($lines as $line) {
431 $line = trim($line);
432 $matches = array();
433 // we catch anything that may (or may not) be an IP
434 if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) {
435 $result[$path][] = __('Incorrect value') . ': ' . $line;
436 continue;
438 // now let's check whether we really have an IP address
439 if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false
440 && filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false
442 $ip = htmlspecialchars(trim($matches[1]));
443 $result[$path][] = sprintf(__('Incorrect IP address: %s'), $ip);
444 continue;
448 return $result;
452 * Tests integer value
454 * @param string $path path to config
455 * @param array $values config values
456 * @param bool $allow_neg allow negative values
457 * @param bool $allow_zero allow zero
458 * @param int $max_value max allowed value
459 * @param string $error_string error message key:
460 * $GLOBALS["strConfig$error_lang_key"]
462 * @return string empty string if test is successful
464 function test_number(
465 $path,
466 $values,
467 $allow_neg,
468 $allow_zero,
469 $max_value,
470 $error_string
472 if ($values[$path] === '') {
473 return '';
476 if (intval($values[$path]) != $values[$path]
477 || (!$allow_neg && $values[$path] < 0)
478 || (!$allow_zero && $values[$path] == 0)
479 || $values[$path] > $max_value
481 return $error_string;
484 return '';
488 * Validates port number
490 * @param string $path path to config
491 * @param array $values config values
493 * @return array
495 function validate_port_number($path, $values)
497 return array(
498 $path => test_number(
499 $path,
500 $values,
501 false,
502 false,
503 65535,
504 __('Not a valid port number')
510 * Validates positive number
512 * @param string $path path to config
513 * @param array $values config values
515 * @return array
517 function validate_positive_number($path, $values)
519 return array(
520 $path => test_number(
521 $path,
522 $values,
523 false,
524 false,
525 PHP_INT_MAX,
526 __('Not a positive number')
532 * Validates non-negative number
534 * @param string $path path to config
535 * @param array $values config values
537 * @return array
539 function validate_non_negative_number($path, $values)
541 return array(
542 $path => test_number(
543 $path,
544 $values,
545 false,
546 true,
547 PHP_INT_MAX,
548 __('Not a non-negative number')
554 * Validates value according to given regular expression
555 * Pattern and modifiers must be a valid for PCRE <b>and</b> JavaScript RegExp
557 * @param string $path path to config
558 * @param array $values config values
559 * @param string $regex regullar expression to match
561 * @return array
563 function validate_by_regex($path, $values, $regex)
565 $result = preg_match($regex, $values[$path]);
566 return array($path => ($result ? '' : __('Incorrect value')));
570 * Validates upper bound for numeric inputs
572 * @param string $path path to config
573 * @param array $values config values
574 * @param int $max_value maximal allowed value
576 * @return array
578 function validate_upper_bound($path, $values, $max_value)
580 $result = $values[$path] <= $max_value;
581 return array($path => ($result ? ''
582 : sprintf(__('Value must be equal or lower than %s'), $max_value)));