Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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