Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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