Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 877 lines (818 sloc) 26.108 kb
667bfec Decomposition
jakubvrana authored
1 <?php
9a176b0 Comments
jakubvrana authored
2 /** Get database connection
3 * @return Min_DB
4 */
64d616c Rename get_dbh to connection
jakubvrana authored
5 function connection() {
6 // can be used in customization, $connection is minified
7 global $connection;
8 return $connection;
c64c4fd Adminer class
jakubvrana authored
9 }
10
9a176b0 Comments
jakubvrana authored
11 /** Unescape database identifier
12 * @param string text inside ``
13 * @return string
14 */
667bfec Decomposition
jakubvrana authored
15 function idf_unescape($idf) {
a29ac72 Improve drivers
jakubvrana authored
16 $last = substr($idf, -1);
17 return str_replace($last . $last, $last, substr($idf, 1, -1));
667bfec Decomposition
jakubvrana authored
18 }
19
5e01a62 Prepare for SQLite
jakubvrana authored
20 /** Escape string to use inside ''
21 * @param string
22 * @return string
23 */
24 function escape_string($val) {
7e644b4 @vrana Save bytes ($connection->quote shortcut)
authored
25 return substr(q($val), 1, -1);
5e01a62 Prepare for SQLite
jakubvrana authored
26 }
27
72f4d9e @vrana Function parse_str respects magic_quotes_gpc (bug #3034575)
authored
28 /** Disable magic_quotes_gpc
29 * @param array e.g. (&$_GET, &$_POST, &$_COOKIE)
83d82d6 @vrana Pass $filter to remove_slashes (thanks to juzna)
authored
30 * @param bool whether to leave values as is
72f4d9e @vrana Function parse_str respects magic_quotes_gpc (bug #3034575)
authored
31 * @return null modified in place
32 */
83d82d6 @vrana Pass $filter to remove_slashes (thanks to juzna)
authored
33 function remove_slashes($process, $filter = false) {
72f4d9e @vrana Function parse_str respects magic_quotes_gpc (bug #3034575)
authored
34 if (get_magic_quotes_gpc()) {
35 while (list($key, $val) = each($process)) {
36 foreach ($val as $k => $v) {
37 unset($process[$key][$k]);
38 if (is_array($v)) {
39 $process[$key][stripslashes($k)] = $v;
40 $process[] = &$process[$key][stripslashes($k)];
41 } else {
42 $process[$key][stripslashes($k)] = ($filter ? $v : stripslashes($v));
43 }
44 }
45 }
46 }
47 }
48
9a176b0 Comments
jakubvrana authored
49 /** Escape or unescape string to use inside form []
50 * @param string
51 * @param bool
52 * @return string
53 */
667bfec Decomposition
jakubvrana authored
54 function bracket_escape($idf, $back = false) {
64ba924 Comments
jakubvrana authored
55 // escape brackets inside name="x[]"
73e8631 Move stuff to functions.inc.php
jakubvrana authored
56 static $trans = array(':' => ':1', ']' => ':2', '[' => ':3');
667bfec Decomposition
jakubvrana authored
57 return strtr($idf, ($back ? array_flip($trans) : $trans));
58 }
59
9a176b0 Comments
jakubvrana authored
60 /** Escape for HTML
61 * @param string
62 * @return string
63 */
689699a Shortcut for htmlspecialchars
jakubvrana authored
64 function h($string) {
0474c21 @vrana Hide null byte in HTML (bug #3358372)
authored
65 return htmlspecialchars(str_replace("\0", "", $string), ENT_QUOTES);
689699a Shortcut for htmlspecialchars
jakubvrana authored
66 }
67
9a176b0 Comments
jakubvrana authored
68 /** Escape for TD
69 * @param string
70 * @return string
71 */
c196985 Function nbsp
jakubvrana authored
72 function nbsp($string) {
7352c28 Replace strlen() by != ""
jakubvrana authored
73 return (trim($string) != "" ? h($string) : "&nbsp;");
c196985 Function nbsp
jakubvrana authored
74 }
75
3f5b683 Reintegrate sqlite branch
jakubvrana authored
76 /** Convert \n to <br>
77 * @param string
78 * @return string
79 */
80 function nl_br($string) {
81 return str_replace("\n", "<br>", $string); // nl2br() uses XHTML before PHP 5.3
82 }
83
6b30cfa Separate checkbox
jakubvrana authored
84 /** Generate HTML checkbox
85 * @param string
86 * @param string
87 * @param bool
88 * @param string
89 * @param string
3a14845 @vrana Respect defaults and comments checkbox after post (bug #3311791)
authored
90 * @param bool
6b30cfa Separate checkbox
jakubvrana authored
91 * @return string
92 */
3a14845 @vrana Respect defaults and comments checkbox after post (bug #3311791)
authored
93 function checkbox($name, $value, $checked, $label = "", $onclick = "", $jsonly = false) {
c4fe12a Clickable labels in IE6
jakubvrana authored
94 static $id = 0;
95 $id++;
be4f2ef @vrana More thorough escaping
authored
96 $return = "<input type='checkbox' name='$name' value='" . h($value) . "'" . ($checked ? " checked" : "") . ($onclick ? ' onclick="' . h($onclick) . '"' : '') . ($jsonly ? " class='jsonly'" : "") . " id='checkbox-$id'>";
7352c28 Replace strlen() by != ""
jakubvrana authored
97 return ($label != "" ? "<label for='checkbox-$id'>$return" . h($label) . "</label>" : $return);
6b30cfa Separate checkbox
jakubvrana authored
98 }
99
9a176b0 Comments
jakubvrana authored
100 /** Generate list of HTML options
101 * @param array array of strings or arrays (creates optgroup)
102 * @param mixed
103 * @param bool always use array keys for value="", otherwise only string keys are used
104 * @return string
105 */
1e4d11e Select from foreign keys in Editor
jakubvrana authored
106 function optionlist($options, $selected = null, $use_keys = false) {
667bfec Decomposition
jakubvrana authored
107 $return = "";
108 foreach ($options as $k => $v) {
2f76084 @vrana Avoid big ternary operator (saves memory)
authored
109 $opts = array($k => $v);
667bfec Decomposition
jakubvrana authored
110 if (is_array($v)) {
689699a Shortcut for htmlspecialchars
jakubvrana authored
111 $return .= '<optgroup label="' . h($k) . '">';
2f76084 @vrana Avoid big ternary operator (saves memory)
authored
112 $opts = $v;
667bfec Decomposition
jakubvrana authored
113 }
2f76084 @vrana Avoid big ternary operator (saves memory)
authored
114 foreach ($opts as $key => $val) {
cb6d36c HTML instead of XHTML
jakubvrana authored
115 $return .= '<option' . ($use_keys || is_string($key) ? ' value="' . h($key) . '"' : '') . (($use_keys || is_string($key) ? (string) $key : $val) === $selected ? ' selected' : '') . '>' . h($val);
667bfec Decomposition
jakubvrana authored
116 }
117 if (is_array($v)) {
118 $return .= '</optgroup>';
119 }
120 }
121 return $return;
122 }
123
098b74b Move function
jakubvrana authored
124 /** Generate HTML radio list
125 * @param string
126 * @param array
127 * @param string
128 * @param string true for no onchange, false for radio
129 * @return string
130 */
131 function html_select($name, $options, $value = "", $onchange = true) {
132 if ($onchange) {
037c547 @vrana Fix XSS (thanks to Jigal van Hemert)
authored
133 return "<select name='" . h($name) . "'" . (is_string($onchange) ? ' onchange="' . h($onchange) . '"' : "") . ">" . optionlist($options, $value) . "</select>";
098b74b Move function
jakubvrana authored
134 }
135 $return = "";
136 foreach ($options as $key => $val) {
137 $return .= "<label><input type='radio' name='" . h($name) . "' value='" . h($key) . "'" . ($key == $value ? " checked" : "") . ">" . h($val) . "</label>";
138 }
139 return $return;
140 }
141
a93bc19 @vrana Create confirm function
authored
142 /** Get onclick confirmation
143 * @param string JavaScript expression
b7cd652 @vrana No AJAX in drop table, drop database and logout
authored
144 * @param bool stop event propagation
a93bc19 @vrana Create confirm function
authored
145 * @return string
146 */
b7cd652 @vrana No AJAX in drop table, drop database and logout
authored
147 function confirm($count = "", $stop = false) {
148 return " onclick=\"" . ($stop ? "eventStop(event); " : "") . "return confirm('" . lang('Are you sure?') . ($count ? " (' + $count + ')" : "") . "');\"";
a93bc19 @vrana Create confirm function
authored
149 }
150
28f21aa @vrana Escape JavaScript strings (bug #3093243)
authored
151 /** Escape string for JavaScript apostrophes
152 * @param string
153 * @return string
154 */
155 function js_escape($string) {
156 return addcslashes($string, "\r\n'\\/"); // slash for <script>
157 }
158
3f5b683 Reintegrate sqlite branch
jakubvrana authored
159 /** Get INI boolean value
160 * @param string
161 * @return bool
162 */
163 function ini_bool($ini) {
164 $val = ini_get($ini);
165 return (eregi('^(on|true|yes)$', $val) || (int) $val); // boolean values set by php_value are strings
166 }
167
f30fd12 @vrana Work without session.use_cookies (bug #3138640)
authored
168 /** Check if SID is neccessary
169 * @return bool
170 */
171 function sid() {
876af58 @vrana Fix sid function
authored
172 static $return;
173 if (!isset($return)) { // restart_session() defines SID
174 $return = (SID && !($_COOKIE && ini_bool("session.use_cookies"))); // $_COOKIE - don't pass SID with permanent login
175 }
176 return $return;
f30fd12 @vrana Work without session.use_cookies (bug #3138640)
authored
177 }
178
179 /** Shortcut for $connection->quote($string)
180 * @param string
181 * @return string
182 */
7e644b4 @vrana Save bytes ($connection->quote shortcut)
authored
183 function q($string) {
184 global $connection;
185 return $connection->quote($string);
186 }
187
9a176b0 Comments
jakubvrana authored
188 /** Get list of values from database
189 * @param string
190 * @param mixed
191 * @return array
192 */
0bd864e Allow specifying column in get_vals
jakubvrana authored
193 function get_vals($query, $column = 0) {
64d616c Rename get_dbh to connection
jakubvrana authored
194 global $connection;
7769f2c Separate get_vals
jakubvrana authored
195 $return = array();
64d616c Rename get_dbh to connection
jakubvrana authored
196 $result = $connection->query($query);
b84252f Display SQLite compile options
jakubvrana authored
197 if (is_object($result)) {
49f7886 SHOW DATABASES can be revoked
jakubvrana authored
198 while ($row = $result->fetch_row()) {
0bd864e Allow specifying column in get_vals
jakubvrana authored
199 $return[] = $row[$column];
49f7886 SHOW DATABASES can be revoked
jakubvrana authored
200 }
7769f2c Separate get_vals
jakubvrana authored
201 }
202 return $return;
203 }
204
3f5b683 Reintegrate sqlite branch
jakubvrana authored
205 /** Get keys from first column and values from second
206 * @param string
207 * @param Min_DB
208 * @return array
209 */
210 function get_key_vals($query, $connection2 = null) {
211 global $connection;
212 if (!is_object($connection2)) {
213 $connection2 = $connection;
214 }
215 $return = array();
216 $result = $connection2->query($query);
e26b186 @vrana Avoid fatal error (bug #3110257)
authored
217 if (is_object($result)) {
218 while ($row = $result->fetch_row()) {
219 $return[$row[0]] = $row[1];
220 }
3f5b683 Reintegrate sqlite branch
jakubvrana authored
221 }
222 return $return;
223 }
224
b0d637b @vrana Avoid fatal errors
authored
225 /** Get all rows of result
226 * @param string
227 * @return array associative
228 */
96544ba @vrana Report errors in get_rows()
authored
229 function get_rows($query, $connection2 = null, $error = "<p class='error'>") {
b0d637b @vrana Avoid fatal errors
authored
230 global $connection;
231 if (!is_object($connection2)) {
232 $connection2 = $connection;
233 }
234 $return = array();
235 $result = $connection2->query($query);
236 if (is_object($result)) { // can return true
237 while ($row = $result->fetch_assoc()) {
238 $return[] = $row;
239 }
850d1aa @vrana Report errors only
authored
240 } elseif (!$result && $connection->error && $error && defined("PAGE_HEADER")) {
96544ba @vrana Report errors in get_rows()
authored
241 echo $error . error() . "\n";
b0d637b @vrana Avoid fatal errors
authored
242 }
243 return $return;
244 }
245
9a176b0 Comments
jakubvrana authored
246 /** Find unique identifier of a row
247 * @param array
248 * @param array result of indexes()
35ec64c Link COUNT(*) result to listing
jakubvrana authored
249 * @return array
9a176b0 Comments
jakubvrana authored
250 */
35ec64c Link COUNT(*) result to listing
jakubvrana authored
251 function unique_array($row, $indexes) {
720f5fc Restructure indexes
jakubvrana authored
252 foreach ($indexes as $index) {
4b3d569 Save bytes
jakubvrana authored
253 if (ereg("PRIMARY|UNIQUE", $index["type"])) {
720f5fc Restructure indexes
jakubvrana authored
254 $return = array();
255 foreach ($index["columns"] as $key) {
64ba924 Comments
jakubvrana authored
256 if (!isset($row[$key])) { // NULL is ambiguous
720f5fc Restructure indexes
jakubvrana authored
257 continue 2;
667bfec Decomposition
jakubvrana authored
258 }
35ec64c Link COUNT(*) result to listing
jakubvrana authored
259 $return[$key] = $row[$key];
667bfec Decomposition
jakubvrana authored
260 }
720f5fc Restructure indexes
jakubvrana authored
261 return $return;
667bfec Decomposition
jakubvrana authored
262 }
263 }
264 $return = array();
265 foreach ($row as $key => $val) {
26c9d64 Fix long SQL query crash (bug #2839231)
jakubvrana authored
266 if (!preg_match('~^(COUNT\\((\\*|(DISTINCT )?`(?:[^`]|``)+`)\\)|(AVG|GROUP_CONCAT|MAX|MIN|SUM)\\(`(?:[^`]|``)+`\\))$~', $key)) { //! columns looking like functions
35ec64c Link COUNT(*) result to listing
jakubvrana authored
267 $return[$key] = $val;
988a29f Don't use aggregation functions in unique_idf
jakubvrana authored
268 }
430034c Cottage homework
jakubvrana authored
269 }
270 return $return;
271 }
272
9a176b0 Comments
jakubvrana authored
273 /** Create SQL condition from parsed query string
274 * @param array parsed query string
275 * @return string
276 */
9ea3112 Mandatory $where in where()
jakubvrana authored
277 function where($where) {
1a8d7f1 @vrana Use LIKE for text comparison in MS SQL (bug #3088222)
authored
278 global $jush;
430034c Cottage homework
jakubvrana authored
279 $return = array();
341362a Driver specific INSERT INTO
jakubvrana authored
280 foreach ((array) $where["where"] as $key => $val) {
66ff153 Use bracket_escape function
jakubvrana authored
281 $return[] = idf_escape(bracket_escape($key, 1)) // 1 - back
d26fb62 @vrana Backslash is special with LIKE (bug #3344307)
authored
282 . (ereg('\\.', $val) || $jush == "mssql" ? " LIKE " . exact_value(addcslashes($val, "%_\\")) : " = " . exact_value($val)) // LIKE because of floats, but slow with ints, in MS SQL because of text
66ff153 Use bracket_escape function
jakubvrana authored
283 ; //! enum and set
341362a Driver specific INSERT INTO
jakubvrana authored
284 }
285 foreach ((array) $where["null"] as $key) {
286 $return[] = idf_escape($key) . " IS NULL";
667bfec Decomposition
jakubvrana authored
287 }
c16c57b E-mail sending
jakubvrana authored
288 return implode(" AND ", $return);
667bfec Decomposition
jakubvrana authored
289 }
290
9a176b0 Comments
jakubvrana authored
291 /** Create SQL condition from query string
292 * @param string
293 * @return string
294 */
0cd2afb Remove single item clone
jakubvrana authored
295 function where_check($val) {
296 parse_str($val, $check);
72f4d9e @vrana Function parse_str respects magic_quotes_gpc (bug #3034575)
authored
297 remove_slashes(array(&$check));
0cd2afb Remove single item clone
jakubvrana authored
298 return where($check);
299 }
300
9a176b0 Comments
jakubvrana authored
301 /** Create query string where condition from value
302 * @param int condition order
303 * @param string column identifier
304 * @param string
305 * @return string
186c058 Utilize where_link function
jakubvrana authored
306 * @return string
9a176b0 Comments
jakubvrana authored
307 */
186c058 Utilize where_link function
jakubvrana authored
308 function where_link($i, $column, $value, $operator = "=") {
8062648 @vrana Use IS NULL operator for null value in where_link function
authored
309 return "&where%5B$i%5D%5Bcol%5D=" . urlencode($column) . "&where%5B$i%5D%5Bop%5D=" . urlencode((isset($value) ? $operator : "IS NULL")) . "&where%5B$i%5D%5Bval%5D=" . urlencode($value);
c42c46a Table relations
jakubvrana authored
310 }
311
319cba4 Save e-mail from to cookie
jakubvrana authored
312 /** Set cookie valid for 1 month
313 * @param string
314 * @param string
315 * @return bool
316 */
317 function cookie($name, $value) {
2cec758 @vrana Direct links from HTTPS to HTTP
authored
318 global $HTTPS;
3f5b683 Reintegrate sqlite branch
jakubvrana authored
319 $params = array(
320 $name,
321 (ereg("\n", $value) ? "" : $value), // HTTP Response Splitting protection in PHP < 5.1.2
322 time() + 2592000, // 2592000 - 30 days
323 preg_replace('~\\?.*~', '', $_SERVER["REQUEST_URI"]),
324 "",
2cec758 @vrana Direct links from HTTPS to HTTP
authored
325 $HTTPS
3f5b683 Reintegrate sqlite branch
jakubvrana authored
326 );
c2334db Secure cookies
jakubvrana authored
327 if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
328 $params[] = true; // HttpOnly
329 }
330 return call_user_func_array('setcookie', $params);
319cba4 Save e-mail from to cookie
jakubvrana authored
331 }
332
f9a2023 Improve concurrency
jakubvrana authored
333 /** Restart stopped session
334 * @return null
335 */
336 function restart_session() {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
337 if (!ini_bool("session.use_cookies")) {
f9a2023 Improve concurrency
jakubvrana authored
338 session_start();
339 }
340 }
341
3f5b683 Reintegrate sqlite branch
jakubvrana authored
342 /** Get session variable for current server
343 * @param string
344 * @return mixed
345 */
346 function &get_session($key) {
347 return $_SESSION[$key][DRIVER][SERVER][$_GET["username"]];
348 }
349
350 /** Set session variable for current server
351 * @param string
352 * @param mixed
353 * @return mixed
354 */
355 function set_session($key, $val) {
356 $_SESSION[$key][DRIVER][SERVER][$_GET["username"]] = $val; // used also in auth.inc.php
357 }
358
605b093 @vrana List authentications
authored
359 /** Get authenticated URL
360 * @param string
361 * @param string
362 * @param string
363 * @return string
364 */
365 function auth_url($driver, $server, $username) {
366 global $drivers;
367 preg_match('~([^?]*)\\??(.*)~', remove_from_uri(implode("|", array_keys($drivers)) . "|username|" . session_name()), $match);
368 return "$match[1]?"
f30fd12 @vrana Work without session.use_cookies (bug #3138640)
authored
369 . (sid() ? SID . "&" : "")
605b093 @vrana List authentications
authored
370 . ($driver != "server" || $server != "" ? urlencode($driver) . "=" . urlencode($server) . "&" : "")
371 . "username=" . urlencode($username)
372 . ($match[2] ? "&$match[2]" : "")
373 ;
374 }
375
390e38b @vrana Load long texts for inline-edit by AJAX
authored
376 /** Find whether it is an AJAX request
377 * @return bool
378 */
379 function is_ajax() {
fdea197 @vrana Simplify AJAX redirect
authored
380 return ($_SERVER["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest");
390e38b @vrana Load long texts for inline-edit by AJAX
authored
381 }
382
9a176b0 Comments
jakubvrana authored
383 /** Send Location header and exit
9bb1909 Fix Save and continue edit
jakubvrana authored
384 * @param string null to only set a message
9a176b0 Comments
jakubvrana authored
385 * @param string
386 * @return null
387 */
430034c Cottage homework
jakubvrana authored
388 function redirect($location, $message = null) {
389 if (isset($message)) {
be49e08 Improve session restarting
jakubvrana authored
390 restart_session();
a379bde @vrana Save bytes
authored
391 $_SESSION["messages"][preg_replace('~^[^?]*~', '', (isset($location) ? $location : $_SERVER["REQUEST_URI"]))][] = $message;
430034c Cottage homework
jakubvrana authored
392 }
de24145 @vrana Clear POST with AJAX redirect
authored
393 if (isset($location)) {
b535853 @vrana Full AJAX only with pushState to work correctly with history
authored
394 if ($location == "") {
395 $location = ".";
396 }
fdea197 @vrana Simplify AJAX redirect
authored
397 header((is_ajax() ? "X-AJAX-Redirect" : "Location") . ": $location");
38894b2 @vrana Send all forms by AJAX
authored
398 exit;
9bb1909 Fix Save and continue edit
jakubvrana authored
399 }
430034c Cottage homework
jakubvrana authored
400 }
401
9a176b0 Comments
jakubvrana authored
402 /** Execute query and redirect if successful
403 * @param string
404 * @param string
405 * @param string
406 * @param bool
407 * @param bool
408 * @param bool
409 * @return bool
410 */
748ee83 Print SQL command with multiple queries
jakubvrana authored
411 function query_redirect($query, $location, $message, $redirect = true, $execute = true, $failed = false) {
64d616c Rename get_dbh to connection
jakubvrana authored
412 global $connection, $error, $adminer;
f9a2023 Improve concurrency
jakubvrana authored
413 if ($execute) {
414 $failed = !$connection->query($query);
415 }
10bdbed Save queries to history
jakubvrana authored
416 $sql = "";
417 if ($query) {
2e6ad20 @vrana Display ; in history (thanks to Jan Cerny)
authored
418 $sql = $adminer->messageQuery("$query;");
10bdbed Save queries to history
jakubvrana authored
419 }
748ee83 Print SQL command with multiple queries
jakubvrana authored
420 if ($failed) {
c1130ed Simplify SQL syntax errors everywhere
jakubvrana authored
421 $error = error() . $sql;
c48a017 Print SQL query by error
jakubvrana authored
422 return false;
f91b2c4 Print SQL query by message
jakubvrana authored
423 }
c48a017 Print SQL query by error
jakubvrana authored
424 if ($redirect) {
425 redirect($location, $message . $sql);
426 }
427 return true;
f91b2c4 Print SQL query by message
jakubvrana authored
428 }
429
9a176b0 Comments
jakubvrana authored
430 /** Execute and remember query
d06de55 @vrana Use DELIMITER in history
authored
431 * @param string null to return remembered queries, end with ';' to use DELIMITER
9a176b0 Comments
jakubvrana authored
432 * @return Min_Result
433 */
748ee83 Print SQL command with multiple queries
jakubvrana authored
434 function queries($query = null) {
64d616c Rename get_dbh to connection
jakubvrana authored
435 global $connection;
748ee83 Print SQL command with multiple queries
jakubvrana authored
436 static $queries = array();
437 if (!isset($query)) {
64ba924 Comments
jakubvrana authored
438 // return executed queries without parameter
2e6ad20 @vrana Display ; in history (thanks to Jan Cerny)
authored
439 return implode(";\n", $queries);
748ee83 Print SQL command with multiple queries
jakubvrana authored
440 }
2e6ad20 @vrana Display ; in history (thanks to Jan Cerny)
authored
441 $queries[] = (ereg(';$', $query) ? "DELIMITER ;;\n$query;\nDELIMITER " : $query);
64d616c Rename get_dbh to connection
jakubvrana authored
442 return $connection->query($query);
748ee83 Print SQL command with multiple queries
jakubvrana authored
443 }
444
f9bb1c5 @vrana Introduce apply_queries function
authored
445 /** Apply command to all array items
446 * @param string
447 * @param array
448 * @param callback
449 * @return bool
450 */
451 function apply_queries($query, $tables, $escape = 'table') {
452 foreach ($tables as $table) {
453 if (!queries("$query " . $escape($table))) {
454 return false;
455 }
456 }
457 return true;
458 }
459
dbdd40a Introduce queries_redirect function
jakubvrana authored
460 /** Redirect by remembered queries
461 * @param string
462 * @param string
463 * @param bool
52b9820 @vrana Comment
authored
464 * @return bool
dbdd40a Introduce queries_redirect function
jakubvrana authored
465 */
466 function queries_redirect($location, $message, $redirect) {
467 return query_redirect(queries(), $location, $message, $redirect, false, !$redirect);
468 }
469
9a176b0 Comments
jakubvrana authored
470 /** Remove parameter from query string
471 * @param string
472 * @return string
473 */
d41d446 remove_from_uri()
jakubvrana authored
474 function remove_from_uri($param = "") {
483d7dc Remove session_name() only without SID (bug #2910681)
jakubvrana authored
475 return substr(preg_replace("~(?<=[?&])($param" . (SID ? "" : "|" . session_name()) . ")=[^&]*&~", '', "$_SERVER[REQUEST_URI]&"), 0, -1);
d41d446 remove_from_uri()
jakubvrana authored
476 }
477
9a176b0 Comments
jakubvrana authored
478 /** Generate page number for pagination
479 * @param int
480 * @return string
481 */
bd25295 Don't redirect from last page
jakubvrana authored
482 function pagination($page, $current) {
6585b23 @vrana Generic AJAX links
authored
483 return " " . ($page == $current ? $page + 1 : '<a href="' . h(remove_from_uri("page") . ($page ? "&page=$page" : "")) . '">' . ($page + 1) . "</a>");
1456283 Pages on last page
jakubvrana authored
484 }
485
3e9b1ba Don't store files in hidden fields
jakubvrana authored
486 /** Get file contents from $_FILES
9a176b0 Comments
jakubvrana authored
487 * @param string
488 * @param bool
3e9b1ba Don't store files in hidden fields
jakubvrana authored
489 * @return mixed int for error, string otherwise
9a176b0 Comments
jakubvrana authored
490 */
25f01d3 Compress export and import
jakubvrana authored
491 function get_file($key, $decompress = false) {
492 $file = $_FILES[$key];
493 if (!$file || $file["error"]) {
494 return $file["error"];
430034c Cottage homework
jakubvrana authored
495 }
9ff10f8 @vrana Parse UTF-16 and UTF-8 BOM in all text uploads
authored
496 $return = file_get_contents($decompress && ereg('\\.gz$', $file["name"]) ? "compress.zlib://$file[tmp_name]"
0a2d81d Bzip2 import
jakubvrana authored
497 : ($decompress && ereg('\\.bz2$', $file["name"]) ? "compress.bzip2://$file[tmp_name]"
498 : $file["tmp_name"]
499 )); //! may not be reachable because of open_basedir
9ff10f8 @vrana Parse UTF-16 and UTF-8 BOM in all text uploads
authored
500 if ($decompress) {
b5cbbce @vrana Save memory
authored
501 $start = substr($return, 0, 3);
502 if (function_exists("iconv") && ereg("^\xFE\xFF|^\xFF\xFE", $start, $regs)) { // not ternary operator to save memory
9ff10f8 @vrana Parse UTF-16 and UTF-8 BOM in all text uploads
authored
503 $return = iconv("utf-16", "utf-8", $return);
b5cbbce @vrana Save memory
authored
504 } elseif ($start == "\xEF\xBB\xBF") { // UTF-8 BOM
505 $return = substr($return, 3);
9ff10f8 @vrana Parse UTF-16 and UTF-8 BOM in all text uploads
authored
506 }
507 }
508 return $return;
430034c Cottage homework
jakubvrana authored
509 }
510
9a176b0 Comments
jakubvrana authored
511 /** Determine upload error
512 * @param int
513 * @return string
514 */
e2a03c0 Show upload_max_filesize
jakubvrana authored
515 function upload_error($error) {
516 $max_size = ($error == UPLOAD_ERR_INI_SIZE ? ini_get("upload_max_filesize") : null); // post_max_size is checked in index.php
b2a7c7a Execute SQL file stored on server disk
jakubvrana authored
517 return ($error ? lang('Unable to upload a file.') . ($max_size ? " " . lang('Maximum allowed file size is %sB.', $max_size) : "") : lang('File does not exist.'));
e2a03c0 Show upload_max_filesize
jakubvrana authored
518 }
519
9a176b0 Comments
jakubvrana authored
520 /** Generate class for odd rows
521 * @param string return this for odd rows, empty to reset counter
522 * @return string
523 */
524 function odd($return = ' class="odd"') {
4e5b126 Highlight odd and hover rows
jakubvrana authored
525 static $i = 0;
9a176b0 Comments
jakubvrana authored
526 if (!$return) { // reset counter
1b97f48 Reset odd() for each result
jakubvrana authored
527 $i = -1;
4e5b126 Highlight odd and hover rows
jakubvrana authored
528 }
9a176b0 Comments
jakubvrana authored
529 return ($i++ % 2 ? $return : '');
4e5b126 Highlight odd and hover rows
jakubvrana authored
530 }
531
c313dd8 @vrana Deferred operations by AJAX instead of JS (doesn't require sending token...
authored
532 /** Print one row in JSON object
533 * @param string or "" to close the object
534 * @param string
535 * @return null
536 */
537 function json_row($key, $val = null) {
538 static $first = true;
539 if ($first) {
540 echo "{";
541 }
542 if ($key != "") {
be58b9c @vrana Escape \n in JSON
authored
543 echo ($first ? "" : ",") . "\n\t\"" . addcslashes($key, "\r\n\"\\") . '": ' . (isset($val) ? '"' . addcslashes($val, "\r\n\"\\") . '"' : 'undefined');
c313dd8 @vrana Deferred operations by AJAX instead of JS (doesn't require sending token...
authored
544 $first = false;
545 } else {
546 echo "\n}\n";
547 $first = true;
548 }
549 }
550
9a176b0 Comments
jakubvrana authored
551 /** Check whether the string is in UTF-8
552 * @param string
553 * @return bool
554 */
017ffb5 Better UTF-8 detection
jakubvrana authored
555 function is_utf8($val) {
64ba924 Comments
jakubvrana authored
556 // don't print control chars except \t\r\n
017ffb5 Better UTF-8 detection
jakubvrana authored
557 return (preg_match('~~u', $val) && !preg_match('~[\\0-\\x8\\xB\\xC\\xE-\\x1F]~', $val));
558 }
559
1315537 @vrana No error for big text length (bug #264133)
authored
560 /** Create repeat pattern for preg
561 * @param string
562 * @param int
563 * @return string
564 */
565 function repeat_pattern($pattern, $length) {
566 // fix for Compilation failed: number too big in {} quantifier
567 return str_repeat("$pattern{0,65535}", $length / 65535) . "$pattern{0," . ($length % 65535) . "}"; // can create {0,0} which is OK
568 }
569
9a176b0 Comments
jakubvrana authored
570 /** Shorten UTF-8 string
571 * @param string
572 * @param int
573 * @param string
574 * @return string escaped string with appended ...
575 */
cd07584 Save SQL query to history
jakubvrana authored
576 function shorten_utf8($string, $length = 80, $suffix = "") {
1315537 @vrana No error for big text length (bug #264133)
authored
577 if (!preg_match("(^(" . repeat_pattern("[\t\r\n -\x{FFFF}]", $length) . ")($)?)u", $string, $match)) { // ~s causes trash in $match[2] under some PHP versions, (.|\n) is slow
578 preg_match("(^(" . repeat_pattern("[\t\r\n -~]", $length) . ")($)?)", $string, $match);
95764b0 Shorten binary strings
jakubvrana authored
579 }
687b3fd @vrana Replace <strong> by <b> and <em> by <i>
authored
580 return h($match[1]) . $suffix . (isset($match[2]) ? "" : "<i>...</i>");
02a851c Shorten texts in PHP
jakubvrana authored
581 }
3920ebb Remove InnoDB table comment in Tables and views
jakubvrana authored
582
9a176b0 Comments
jakubvrana authored
583 /** Generate friendly URL
584 * @param string
585 * @return string
586 */
8251896 Downloaded file name
jakubvrana authored
587 function friendly_url($val) {
64ba924 Comments
jakubvrana authored
588 // used for blobs and export
8251896 Downloaded file name
jakubvrana authored
589 return preg_replace('~[^a-z0-9_]~i', '-', $val);
590 }
591
9a176b0 Comments
jakubvrana authored
592 /** Print hidden fields
593 * @param array
594 * @param array
595 * @return null
596 */
820c882 Bulk clone
jakubvrana authored
597 function hidden_fields($process, $ignore = array()) {
5d7071a Choose language through option-list
jakubvrana authored
598 while (list($key, $val) = each($process)) {
599 if (is_array($val)) {
600 foreach ($val as $k => $v) {
601 $process[$key . "[$k]"] = $v;
602 }
603 } elseif (!in_array($key, $ignore)) {
689699a Shortcut for htmlspecialchars
jakubvrana authored
604 echo '<input type="hidden" name="' . h($key) . '" value="' . h($val) . '">';
5d7071a Choose language through option-list
jakubvrana authored
605 }
606 }
607 }
61640ee Move common functions
jakubvrana authored
608
3f5b683 Reintegrate sqlite branch
jakubvrana authored
609 /** Print hidden fields for GET forms
610 * @return null
611 */
612 function hidden_fields_get() {
f30fd12 @vrana Work without session.use_cookies (bug #3138640)
authored
613 echo (sid() ? '<input type="hidden" name="' . session_name() . '" value="' . h(session_id()) . '">' : '');
3f5b683 Reintegrate sqlite branch
jakubvrana authored
614 echo (SERVER !== null ? '<input type="hidden" name="' . DRIVER . '" value="' . h(SERVER) . '">' : "");
615 echo '<input type="hidden" name="username" value="' . h($_GET["username"]) . '">';
616 }
617
9a176b0 Comments
jakubvrana authored
618 /** Find out foreign keys for each column
619 * @param string
620 * @return array array($col => array())
621 */
1e4d11e Select from foreign keys in Editor
jakubvrana authored
622 function column_foreign_keys($table) {
753909e @vrana Support for virtual foreign keys
authored
623 global $adminer;
1e4d11e Select from foreign keys in Editor
jakubvrana authored
624 $return = array();
753909e @vrana Support for virtual foreign keys
authored
625 foreach ($adminer->foreignKeys($table) as $foreign_key) {
1e4d11e Select from foreign keys in Editor
jakubvrana authored
626 foreach ($foreign_key["source"] as $val) {
627 $return[$val][] = $foreign_key;
628 }
629 }
630 return $return;
631 }
632
3f5b683 Reintegrate sqlite branch
jakubvrana authored
633 /** Print enum input field
634 * @param string "radio"|"checkbox"
635 * @param string
636 * @param array
637 * @param mixed int|string|array
684e70d @vrana Search for empty enum
authored
638 * @param string
3f5b683 Reintegrate sqlite branch
jakubvrana authored
639 * @return null
640 */
684e70d @vrana Search for empty enum
authored
641 function enum_input($type, $attrs, $field, $value, $empty = null) {
c068206 @vrana Use $adminer->editVal in enum_input function
authored
642 global $adminer;
3f5b683 Reintegrate sqlite branch
jakubvrana authored
643 preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
684e70d @vrana Search for empty enum
authored
644 $return = (isset($empty) ? "<label><input type='$type'$attrs value='$empty'" . ((is_array($value) ? in_array($empty, $value) : $value === 0) ? " checked" : "") . "><i>" . lang('empty') . "</i></label>" : "");
3f5b683 Reintegrate sqlite branch
jakubvrana authored
645 foreach ($matches[1] as $i => $val) {
646 $val = stripcslashes(str_replace("''", "'", $val));
647 $checked = (is_int($value) ? $value == $i+1 : (is_array($value) ? in_array($i+1, $value) : $value === $val));
c068206 @vrana Use $adminer->editVal in enum_input function
authored
648 $return .= " <label><input type='$type'$attrs value='" . ($i+1) . "'" . ($checked ? ' checked' : '') . '>' . h($adminer->editVal($val, $field)) . '</label>';
3f5b683 Reintegrate sqlite branch
jakubvrana authored
649 }
fe06908 @vrana Allow redefining editInput for enum (bug #3048711)
authored
650 return $return;
3f5b683 Reintegrate sqlite branch
jakubvrana authored
651 }
652
9a176b0 Comments
jakubvrana authored
653 /** Print edit input field
654 * @param array one field from fields()
655 * @param mixed
656 * @param string
657 * @return null
658 */
1e4d11e Select from foreign keys in Editor
jakubvrana authored
659 function input($field, $value, $function) {
e672694 @vrana Rename $driver to $jush
authored
660 global $types, $adminer, $jush;
689699a Shortcut for htmlspecialchars
jakubvrana authored
661 $name = h(bracket_escape($field["field"]));
61640ee Move common functions
jakubvrana authored
662 echo "<td class='function'>";
9f69d7a @vrana MS SQL: Do not update AI value
authored
663 $reset = ($jush == "mssql" && $field["auto_increment"]);
664 if ($reset && !$_POST["save"]) {
665 $function = null;
666 }
667 $functions = (isset($_GET["select"]) || $reset ? array("orig" => lang('original')) : array()) + $adminer->editFunctions($field);
454c80f @vrana Save bytes
authored
668 $attrs = " name='fields[$name]'";
61640ee Move common functions
jakubvrana authored
669 if ($field["type"] == "enum") {
fe06908 @vrana Allow redefining editInput for enum (bug #3048711)
authored
670 echo nbsp($functions[""]) . "<td>" . $adminer->editInput($_GET["edit"], $field, $attrs, $value);
61640ee Move common functions
jakubvrana authored
671 } else {
9903946 Use original values in Editor multi edit
jakubvrana authored
672 $first = 0;
673 foreach ($functions as $key => $val) {
674 if ($key === "" || !$val) {
675 break;
676 }
677 $first++;
678 }
037c547 @vrana Fix XSS (thanks to Jigal van Hemert)
authored
679 $onchange = ($first ? " onchange=\"var f = this.form['function[" . h(js_escape($name)) . "]']; if ($first > f.selectedIndex) f.selectedIndex = $first;\"" : "");
454c80f @vrana Save bytes
authored
680 $attrs .= $onchange;
622845b @vrana Disable maxlength with edit functions
authored
681 echo (count($functions) > 1 ? html_select("function[$name]", $functions, !isset($function) || in_array($function, $functions) || isset($functions[$function]) ? $function : "", "functionChange(this);") : nbsp(reset($functions))) . '<td>';
a561252 Use distinct name for blob inputs
jakubvrana authored
682 $input = $adminer->editInput($_GET["edit"], $field, $attrs, $value); // usage in call is without a table
7352c28 Replace strlen() by != ""
jakubvrana authored
683 if ($input != "") {
e1abcda Treat tinyint(1) as boolean
jakubvrana authored
684 echo $input;
1e4d11e Select from foreign keys in Editor
jakubvrana authored
685 } elseif ($field["type"] == "set") { //! 64 bits
26c9d64 Fix long SQL query crash (bug #2839231)
jakubvrana authored
686 preg_match_all("~'((?:[^']|'')*)'~", $field["length"], $matches);
61640ee Move common functions
jakubvrana authored
687 foreach ($matches[1] as $i => $val) {
688 $val = stripcslashes(str_replace("''", "'", $val));
689 $checked = (is_int($value) ? ($value >> $i) & 1 : in_array($val, explode(",", $value), true));
045bce3 @vrana Use editVal for set values
authored
690 echo " <label><input type='checkbox' name='fields[$name][$i]' value='" . (1 << $i) . "'" . ($checked ? ' checked' : '') . "$onchange>" . h($adminer->editVal($val, $field)) . '</label>';
61640ee Move common functions
jakubvrana authored
691 }
5a73c01 @vrana Treat binary type as hex
authored
692 } elseif (ereg('blob|bytea|raw|file', $field["type"]) && ini_bool("file_uploads")) {
a561252 Use distinct name for blob inputs
jakubvrana authored
693 echo "<input type='file' name='fields-$name'$onchange>";
375a5c8 @vrana Non-MySQL binary types
authored
694 } elseif (ereg('text|lob', $field["type"])) {
7d152fb @vrana Utilize bodyKeydown function
authored
695 echo "<textarea " . ($jush != "sqlite" || ereg("\n", $value) ? "cols='50' rows='12'" : "cols='30' rows='1' style='height: 1.2em;'") . "$attrs>" . h($value) . '</textarea>'; // 1.2em - line-height
61640ee Move common functions
jakubvrana authored
696 } else {
697 // int(3) is only a display hint
5002b89 @vrana Big numbers without E
authored
698 $maxlength = (!ereg('int', $field["type"]) && preg_match('~^(\\d+)(,(\\d+))?$~', $field["length"], $match) ? ((ereg("binary", $field["type"]) ? 2 : 1) * $match[1] + ($match[3] ? 1 : 0) + ($match[2] && !$field["unsigned"] ? 1 : 0)) : ($types[$field["type"]] ? $types[$field["type"]] + ($field["unsigned"] ? 0 : 1) : 0));
5a73c01 @vrana Treat binary type as hex
authored
699 echo "<input value='" . h($value) . "'" . ($maxlength ? " maxlength='$maxlength'" : "") . (ereg('char|binary', $field["type"]) && $maxlength > 20 ? " size='40'" : "") . "$attrs>";
61640ee Move common functions
jakubvrana authored
700 }
701 }
702 }
703
9a176b0 Comments
jakubvrana authored
704 /** Process edit input field
705 * @param one field from fields()
706 * @return string
707 */
a0def47 Date localization
jakubvrana authored
708 function process_input($field) {
7e644b4 @vrana Save bytes ($connection->quote shortcut)
authored
709 global $adminer;
a0def47 Date localization
jakubvrana authored
710 $idf = bracket_escape($field["field"]);
61640ee Move common functions
jakubvrana authored
711 $function = $_POST["function"][$idf];
712 $value = $_POST["fields"][$idf];
3f5b683 Reintegrate sqlite branch
jakubvrana authored
713 if ($field["type"] == "enum") {
714 if ($value == -1) {
715 return false;
716 }
717 if ($value == "") {
718 return "NULL";
719 }
04eccba @vrana Allow bigger numbers under 32 bits
authored
720 return +$value;
3f5b683 Reintegrate sqlite branch
jakubvrana authored
721 }
722 if ($field["auto_increment"] && $value == "") {
723 return null;
724 }
725 if ($function == "orig") {
c0c21d4 @vrana Preserve original timestamp value in multiple update (bug #3312614)
authored
726 return ($field["on_update"] == "CURRENT_TIMESTAMP" ? idf_escape($field["field"]) : false);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
727 }
728 if ($function == "NULL") {
61640ee Move common functions
jakubvrana authored
729 return "NULL";
3f5b683 Reintegrate sqlite branch
jakubvrana authored
730 }
731 if ($field["type"] == "set") {
4cead56 Edit default values directly in table creation
jakubvrana authored
732 return array_sum((array) $value);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
733 }
5a73c01 @vrana Treat binary type as hex
authored
734 if (ereg('blob|bytea|raw|file', $field["type"]) && ini_bool("file_uploads")) {
a561252 Use distinct name for blob inputs
jakubvrana authored
735 $file = get_file("fields-$idf");
61640ee Move common functions
jakubvrana authored
736 if (!is_string($file)) {
737 return false; //! report errors
738 }
7e644b4 @vrana Save bytes ($connection->quote shortcut)
authored
739 return q($file);
61640ee Move common functions
jakubvrana authored
740 }
3f5b683 Reintegrate sqlite branch
jakubvrana authored
741 return $adminer->processInput($field, $value, $function);
61640ee Move common functions
jakubvrana authored
742 }
743
db07325 Search in all tables
jakubvrana authored
744 /** Print results of search in all tables
745 * @uses $_GET["where"][0]
746 * @uses $_POST["tables"]
747 * @return null
748 */
749 function search_tables() {
750 global $adminer, $connection;
dfa6cbf @vrana Show tables overview in Editor
authored
751 $_GET["where"][0]["op"] = "LIKE %%";
752 $_GET["where"][0]["val"] = $_POST["query"];
db07325 Search in all tables
jakubvrana authored
753 $found = false;
754 foreach (table_status() as $table => $table_status) {
755 $name = $adminer->tableName($table_status);
756 if (isset($table_status["Engine"]) && $name != "" && (!$_POST["tables"] || in_array($table, $_POST["tables"]))) {
ee3e045 @vrana Separate $where in limit function
authored
757 $result = $connection->query("SELECT" . limit("1 FROM " . table($table), " WHERE " . implode(" AND ", $adminer->selectSearchProcess(fields($table), array())), 1));
782921b @vrana Finish SQLite
authored
758 if ($result->fetch_row()) {
db07325 Search in all tables
jakubvrana authored
759 if (!$found) {
760 echo "<ul>\n";
761 $found = true;
762 }
5ee1407 @vrana Avoid double escaping
authored
763 echo "<li><a href='" . h(ME . "select=" . urlencode($table) . "&where[0][op]=" . urlencode($_GET["where"][0]["op"]) . "&where[0][val]=" . urlencode($_GET["where"][0]["val"])) . "'>$name</a>\n";
db07325 Search in all tables
jakubvrana authored
764 }
765 }
766 }
767 echo ($found ? "</ul>" : "<p class='message'>" . lang('No tables.')) . "\n";
768 }
769
8ab6fff @vrana Centralize dump_headers
authored
770 /** Send headers for export
771 * @param string
772 * @param bool
773 * @return string extension
774 */
775 function dump_headers($identifier, $multi_table = false) {
776 global $adminer;
777 $return = $adminer->dumpHeaders($identifier, $multi_table);
778 $output = $_POST["output"];
779 if ($output != "text") {
5792eab @vrana Use server name for server dump
authored
780 header("Content-Disposition: attachment; filename=" . friendly_url($identifier != "" ? $identifier : (SERVER != "" ? SERVER : "localhost")) . ".$return" . ($output != "file" && !ereg('[^0-9a-z]', $output) ? ".$output" : ""));
8ab6fff @vrana Centralize dump_headers
authored
781 }
782 session_write_close();
783 return $return;
784 }
785
9a176b0 Comments
jakubvrana authored
786 /** Print CSV row
787 * @param array
788 * @return null
789 */
61640ee Move common functions
jakubvrana authored
790 function dump_csv($row) {
791 foreach ($row as $key => $val) {
e225d22 @vrana TSV export and import (bug #3097657)
authored
792 if (preg_match("~[\"\n,;\t]~", $val) || $val === "") {
61640ee Move common functions
jakubvrana authored
793 $row[$key] = '"' . str_replace('"', '""', $val) . '"';
794 }
795 }
02d6b90 @vrana CR+LF in CSV export
authored
796 echo implode(($_POST["format"] == "csv" ? "," : ($_POST["format"] == "tsv" ? "\t" : ";")), $row) . "\r\n";
61640ee Move common functions
jakubvrana authored
797 }
c16c57b E-mail sending
jakubvrana authored
798
9a176b0 Comments
jakubvrana authored
799 /** Apply SQL function
800 * @param string
801 * @param string escaped column identifier
802 * @return string
803 */
e331067 Move apply_sql_function
jakubvrana authored
804 function apply_sql_function($function, $column) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
805 return ($function ? ($function == "unixepoch" ? "DATETIME($column, '$function')" : ($function == "count distinct" ? "COUNT(DISTINCT " : strtoupper("$function(")) . "$column)") : $column);
e331067 Move apply_sql_function
jakubvrana authored
806 }
807
4ba2d85 @vrana Allow permanent login without customization
authored
808 /** Read password from file adminer.key in temporary directory or create one
809 * @return string or false if the file can not be created
810 */
811 function password_file() {
812 $dir = ini_get("upload_tmp_dir"); // session_save_path() may contain other storage path
813 if (!$dir) {
814 if (function_exists('sys_get_temp_dir')) {
815 $dir = sys_get_temp_dir();
816 } else {
817 $filename = @tempnam("", ""); // @ - temp directory can be disabled by open_basedir
818 if (!$filename) {
819 return false;
820 }
821 $dir = dirname($filename);
822 unlink($filename);
823 }
824 }
825 $filename = "$dir/adminer.key";
826 $return = @file_get_contents($filename); // @ - can not exist
827 if ($return) {
828 return $return;
829 }
830 $fp = @fopen($filename, "w"); // @ - can have insufficient rights //! is not atomic
831 if ($fp) {
832 $return = md5(uniqid(mt_rand(), true));
833 fwrite($fp, $return);
834 fclose($fp);
835 }
836 return $return;
837 }
838
9a176b0 Comments
jakubvrana authored
839 /** Check whether the string is e-mail address
840 * @param string
841 * @return bool
842 */
1cf374b @vrana Rename functions (avoid conflict with WordPress)
authored
843 function is_mail($email) {
c16c57b E-mail sending
jakubvrana authored
844 $atom = '[-a-z0-9!#$%&\'*+/=?^_`{|}~]'; // characters of local-name
845 $domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // one domain component
28e1dd2 Allow multiple e-mails
jakubvrana authored
846 $pattern = "$atom+(\\.$atom+)*@($domain?\\.)+$domain";
847 return preg_match("(^$pattern(,\\s*$pattern)*\$)i", $email);
c16c57b E-mail sending
jakubvrana authored
848 }
dc667ea Hide select export and import
jakubvrana authored
849
bc78866 Link URLs in select
jakubvrana authored
850 /** Check whether the string is URL address
851 * @param string
2cec758 @vrana Direct links from HTTPS to HTTP
authored
852 * @return string "http", "https" or ""
bc78866 Link URLs in select
jakubvrana authored
853 */
854 function is_url($string) {
2cec758 @vrana Direct links from HTTPS to HTTP
authored
855 $domain = '[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])'; // one domain component //! IDN
5002b89 @vrana Big numbers without E
authored
856 return (preg_match("~^(https?)://($domain?\\.)+$domain(:\\d+)?(/.*)?(\\?.*)?(#.*)?\$~i", $string, $match) ? strtolower($match[1]) : ""); //! restrict path, query and fragment characters
bc78866 Link URLs in select
jakubvrana authored
857 }
858
dc667ea Hide select export and import
jakubvrana authored
859 /** Print header for hidden fieldset (close by </div></fieldset>)
860 * @param string
861 * @param string
862 * @param bool
d9c2e80 @vrana Show only errors with Webserver file
authored
863 * @param string
dc667ea Hide select export and import
jakubvrana authored
864 * @return null
865 */
d9c2e80 @vrana Show only errors with Webserver file
authored
866 function print_fieldset($id, $legend, $visible = false, $onclick = "") {
be4f2ef @vrana More thorough escaping
authored
867 echo "<fieldset><legend><a href='#fieldset-$id' onclick=\"" . h($onclick) . "return !toggle('fieldset-$id');\">$legend</a></legend><div id='fieldset-$id'" . ($visible ? "" : " class='hidden'") . ">\n";
dc667ea Hide select export and import
jakubvrana authored
868 }
94a2be5 Highlight current links
jakubvrana authored
869
8ad4809 @vrana Use class="active" instead of <b>
authored
870 /** Return class='active' if $bold is true
94a2be5 Highlight current links
jakubvrana authored
871 * @param bool
872 * @return string
873 */
8ad4809 @vrana Use class="active" instead of <b>
authored
874 function bold($bold) {
875 return ($bold ? " class='active'" : "");
94a2be5 Highlight current links
jakubvrana authored
876 }
Something went wrong with that request. Please try again.