Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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