3.3.5-rc1
[phpmyadmin/arisferyanto.git] / setup / lib / validate.lib.php
blob45f35617dffa5a0b0cc760eafd8f5bf64b451d3f
1 <?php
2 /**
3 * Various validation functions
5 * Validation function takes two argument: id for which it is called
6 * and array of fields' values (usually values for entire formset, as defined
7 * in forms.inc.php).
8 * The function must always return an array with an error (or error array)
9 * assigned to a form element (formset name or field path). Even if there are
10 * no errors, key must be set with an empty value.
12 * Valdiation functions are assigned in $cfg_db['_validators'] (config_info.inc.php).
14 * @package phpMyAdmin-setup
15 * @author Piotr Przybylski <piotrprz@gmail.com>
16 * @license http://www.gnu.org/licenses/gpl.html GNU GPL 2.0
17 * @version $Id$
20 /**
21 * Runs validation $validator_id on values $values and returns error list.
23 * Return values:
24 * o array, keys - field path or formset id, values - array of errors
25 * when $isPostSource is true values is an empty array to allow for error list
26 * cleanup in HTML documen
27 * o false - when no validators match name(s) given by $validator_id
29 * @param string|array $validator_id
30 * @param array $values
31 * @param bool $isPostSource tells whether $values are directly from POST request
32 * @return bool|array
34 function validate($validator_id, &$values, $isPostSource)
36 // find validators
37 $cf = ConfigFile::getInstance();
38 $validator_id = (array) $validator_id;
39 $validators = $cf->getDbEntry('_validators');
40 $vids = array();
41 foreach ($validator_id as &$vid) {
42 $vid = $cf->getCanonicalPath($vid);
43 if (isset($validators[$vid])) {
44 $vids[] = $vid;
47 if (empty($vids)) {
48 return false;
51 // create argument list with canonical paths and remember path mapping
52 $arguments = array();
53 $key_map = array();
54 foreach ($values as $k => $v) {
55 $k2 = $isPostSource ? str_replace('-', '/', $k) : $k;
56 $k2 = strpos($k2, '/') ? $cf->getCanonicalPath($k2) : $k2;
57 $key_map[$k2] = $k;
58 $arguments[$k2] = $v;
61 // validate
62 $result = array();
63 foreach ($vids as $vid) {
64 $r = call_user_func($validators[$vid], $vid, $arguments);
65 // merge results
66 if (is_array($r)) {
67 foreach ($r as $key => $error_list) {
68 // skip empty values if $isPostSource is false
69 if (!$isPostSource && empty($error_list)) {
70 continue;
72 if (!isset($result[$key])) {
73 $result[$key] = array();
75 $result[$key] = array_merge($result[$key], (array)$error_list);
80 // restore original paths
81 $new_result = array();
82 foreach ($result as $k => $v) {
83 $k2 = isset($key_map[$k]) ? $key_map[$k] : $k;
84 $new_result[$k2] = $v;
86 return empty($new_result) ? true : $new_result;
89 /**
90 * Ensures that $php_errormsg variable will be registered in case of an error
91 * and enables output buffering (when $start = true).
92 * Called with $start = false disables output buffering end restores
93 * html_errors and track_errors.
95 * @param boolean $start
97 function test_php_errormsg($start = true)
99 static $old_html_errors, $old_track_errors;
100 if ($start) {
101 $old_html_errors = ini_get('html_errors');
102 $old_track_errors = ini_get('track_errors');
103 ini_set('html_errors', false);
104 ini_set('track_errors', true);
105 ob_start();
106 } else {
107 ob_end_clean();
108 ini_set('html_errors', $old_html_errors);
109 ini_set('track_errors', $old_track_errors);
114 * Test database connection
116 * @param string $extension 'mysql' or 'mysqli'
117 * @param string $connect_type 'tcp' or 'socket'
118 * @param string $host
119 * @param string $port
120 * @param string $socket
121 * @param string $user
122 * @param string $pass
123 * @param string $error_key
124 * @return bool|array
126 function test_db_connection($extension, $connect_type, $host, $port, $socket, $user, $pass = null, $error_key = 'Server')
128 // test_php_errormsg();
129 $socket = empty($socket) || $connect_type == 'tcp' ? null : ':' . $socket;
130 $port = empty($port) || $connect_type == 'socket' ? null : ':' . $port;
131 $error = null;
132 if ($extension == 'mysql') {
133 $conn = @mysql_connect($host . $socket . $port, $user, $pass);
134 if (!$conn) {
135 $error = PMA_lang('error_connection');
136 } else {
137 mysql_close($conn);
139 } else {
140 $conn = @mysqli_connect($host, $user, $pass, null, $port, $socket);
141 if (!$conn) {
142 $error = PMA_lang('error_connection');
143 } else {
144 mysqli_close($conn);
147 // test_php_errormsg(false);
148 if (isset($php_errormsg)) {
149 $error .= " - $php_errormsg";
151 return is_null($error) ? true : array($error_key => $error);
155 * Validate server config
157 * @param string $path
158 * @param array $values
159 * @return array
161 function validate_server($path, $values)
163 $result = array('Server' => '', 'Servers/1/user' => '', 'Servers/1/SignonSession' => '', 'Servers/1/SignonURL' => '');
164 $error = false;
165 if ($values['Servers/1/auth_type'] == 'config' && empty($values['Servers/1/user'])) {
166 $result['Servers/1/user'] = PMA_lang('error_empty_user_for_config_auth');
167 $error = true;
169 if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonSession'])) {
170 $result['Servers/1/SignonSession'] = PMA_lang('error_empty_signon_session');
171 $error = true;
173 if ($values['Servers/1/auth_type'] == 'signon' && empty($values['Servers/1/SignonURL'])) {
174 $result['Servers/1/SignonURL'] = PMA_lang('error_empty_signon_url');
175 $error = true;
178 if (!$error && $values['Servers/1/auth_type'] == 'config') {
179 $password = $values['Servers/1/nopassword'] ? null : $values['Servers/1/password'];
180 $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');
181 if ($test !== true) {
182 $result = array_merge($result, $test);
185 return $result;
189 * Validate pmadb config
191 * @param string $path
192 * @param array $values
193 * @return array
195 function validate_pmadb($path, $values)
197 $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');
198 $result = array('Server_pmadb' => '', 'Servers/1/controluser' => '', 'Servers/1/controlpass' => '');
199 $error = false;
201 if ($values['Servers/1/pmadb'] == '') {
202 return $result;
205 $result = array();
206 if ($values['Servers/1/controluser'] == '') {
207 $result['Servers/1/controluser'] = PMA_lang('error_empty_pmadb_user');
208 $error = true;
210 if ($values['Servers/1/controlpass'] == '') {
211 $result['Servers/1/controlpass'] = PMA_lang('error_empty_pmadb_password');
212 $error = true;
214 if (!$error) {
215 $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');
216 if ($test !== true) {
217 $result = array_merge($result, $test);
220 return $result;
225 * Validates regular expression
227 * @param string $path
228 * @param array $values
229 * @return array
231 function validate_regex($path, $values)
233 $result = array($path => '');
235 if ($values[$path] == '') {
236 return $result;
239 test_php_errormsg();
241 $matches = array();
242 preg_match($values[$path], '', $matches);
243 ob_end_clean();
245 test_php_errormsg(false);
247 if (isset($php_errormsg)) {
248 $error = preg_replace('/^preg_match\(\): /', '', $php_errormsg);
249 return array($path => $error);
252 return $result;
256 * Validates TrustedProxies field
258 * @param string $path
259 * @param array $values
260 * @return array
262 function validate_trusted_proxies($path, $values)
264 $result = array($path => array());
266 if (empty($values[$path])) {
267 return $result;
270 if (is_array($values[$path])) {
271 // value already processed by FormDisplay::save
272 $lines = array();
273 foreach ($values[$path] as $ip => $v) {
274 $lines[] = preg_match('/^-\d+$/', $ip)
275 ? $v
276 : $ip . ': ' . $v;
278 } else {
279 // AJAX validation
280 $lines = explode("\n", $values[$path]);
282 foreach ($lines as $line) {
283 $line = trim($line);
284 $matches = array();
285 // we catch anything that may (or may not) be an IP
286 if (!preg_match("/^(.+):(?:[ ]?)\\w+$/", $line, $matches)) {
287 $result[$path][] = PMA_lang('error_incorrect_value') . ': ' . $line;
288 continue;
290 // now let's check whether we really have an IP address
291 if (filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false
292 && filter_var($matches[1], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
293 $ip = htmlspecialchars(trim($matches[1]));
294 $result[$path][] = PMA_lang('error_incorrect_ip_address', $ip);
295 continue;
299 return $result;
304 * Tests integer value
306 * @param string $path
307 * @param array $values
308 * @param bool $allow_neg allow negative values
309 * @param bool $allow_zero allow zero
310 * @param int $max_value max allowed value
311 * @param string $error_lang_key error message key: $GLOBALS["strSetup$error_lang_key"]
312 * @return string empty string if test is successful
314 function test_number($path, $values, $allow_neg, $allow_zero, $max_value, $error_lang_key)
316 if ($values[$path] === '') {
317 return '';
320 if (intval($values[$path]) != $values[$path] || (!$allow_neg && $values[$path] < 0) || (!$allow_zero && $values[$path] == 0) || $values[$path] > $max_value) {
321 return PMA_lang($error_lang_key);
324 return '';
328 * Validates port number
330 * @param string $path
331 * @param array $values
332 * @return array
334 function validate_port_number($path, $values)
336 return array($path => test_number($path, $values, false, false, 65536, 'error_incorrect_port'));
340 * Validates positive number
342 * @param string $path
343 * @param array $values
344 * @return array
346 function validate_positive_number($path, $values)
348 return array($path => test_number($path, $values, false, false, PHP_INT_MAX, 'error_nan_p'));
352 * Validates non-negative number
354 * @param string $path
355 * @param array $values
356 * @return array
358 function validate_non_negative_number($path, $values)
360 return array($path => test_number($path, $values, false, true, PHP_INT_MAX, 'error_nan_nneg'));