· 6 years ago · Jul 12, 2019, 05:16 PM
1<?php
2/*
3 DBKiss 1.12 (2011-07-30)
4 Author: Cezary Tomczak [cagret@gmail.com]
5 Web site: http://www.gosu.pl/dbkiss/
6 License: BSD revised (free for any use)
7*/
8
9ob_start('ob_gzhandler');
10
11// Some of the features in the SQL editor require creating 'dbkiss_sql' directory,
12// where history of queries are kept and other data. If the script has permission
13// it will create that directory automatically, otherwise you need to create that
14// directory manually and make it writable. You can also set it to empty '' string,
15// but some of the features in the sql editor will not work (templates, pagination)
16
17if (!defined('DBKISS_SQL_DIR')) {
18 define('DBKISS_SQL_DIR', 'dbkiss_sql');
19}
20
21/*
22 An example configuration script that will automatically connect to localhost database.
23 This is useful on localhost if you don't want to see the "Connect" screen.
24
25 mysql_local.php:
26 ---------------------------------------------------------------------
27 define('COOKIE_PREFIX', str_replace('.php', '', basename(__FILE__)).'_');
28 define('DBKISS_SQL_DIR', 'dbkiss_mysql');
29
30 $cookie = array(
31 'db_driver' => 'mysql',
32 'db_server' => 'localhost',
33 'db_name' => 'test',
34 'db_user' => 'root',
35 'db_pass' => 'toor',
36 'db_charset' => 'latin2',
37 'page_charset' => 'iso-8859-2',
38 'remember' => 1
39 );
40
41 foreach ($cookie as $k => $v) {
42 if ('db_pass' == $k) { $v = base64_encode($v); }
43 $k = COOKIE_PREFIX.$k;
44 if (!isset($_COOKIE[$k])) {
45 $_COOKIE[$k] = $v;
46 }
47 }
48
49 require './dbkiss.php';
50 ---------------------------------------------------------------------
51*/
52
53/*
54 Changelog:
55
56 1.12
57 * Fixed "order by" bug in views.
58 1.11
59 * Links in data output are now clickable. Clicking them does not reveal the location of your dbkiss script to external sites.
60 1.10
61 * Support for views in Postgresql (mysql had it already).
62 * Views are now displayed in a seperate listing, to the right of the tables on main page.
63 * Secure redirection - no referer header sent - when clicking external links (ex. powered by), so that the location of the dbkiss script on your site is not revealed.
64 1.09
65 * CSV export in sql editor and table view (feature sponsored by Patrick McGovern)
66 1.08
67 * date.timezone E_STRICT error fixed
68 1.07
69 * mysql tables with dash in the name generated errors, now all tables in mysql driver are
70 enquoted with backtick.
71 1.06
72 * postgresql fix
73 1.05
74 * export of all structure and data does take into account the table name filter on the main page,
75 so you can filter the tables that you want to export.
76 1.04
77 * exporting all structure/data didn't work (ob_gzhandler flush bug)
78 * cookies are now set using httponly option
79 * text editor complained about bad cr/lf in exported sql files
80 (mysql create table uses \n, so insert queries need to be seperated by \n and not \r\n)
81 1.03
82 * re-created array_walk_recursive for php4 compatibility
83 * removed stripping slashes from displayed content
84 * added favicon (using base64_encode to store the icon in php code, so it is still one-file database browser)
85 1.02
86 * works with short_open_tag disabled
87 * code optimizations/fixes
88 * postgresql error fix for large tables
89 1.01
90 * fix for mysql 3.23, which doesnt understand "LIMIT x OFFSET z"
91 1.00
92 * bug fixes
93 * minor feature enhancements
94 * this release is stable and can be used in production environment
95 0.61
96 * upper casing keywords in submitted sql is disabled (it also modified quoted values)
97 * sql error when displaying table with 0 rows
98 * could not connect to database that had upper case characters
99
100*/
101
102// todo: php error handler which cancels buffer output and exits on error
103// todo: XSS and CSRF protection.
104// todo: connect screen: [x] create database (if not exists) [charset]
105// todo: connect screen: database (optional, if none provided will select the first database the user has access to)
106// todo: mysqli driver (check if mysql extension is loaded, if not try to use mysqli)
107// todo: support for the enum field type when editing row
108// todo: search whole database form should appear also on main page
109// todo: improve detecting primary keys when editing row (querying information_schema , for mysql > 4)
110// todo: when dbkiss_sql dir is missing, display a message in sql editor that some features won't work (templates, pagination) currently it displays a message to create that dir and EXIT, but should allow basic operations
111// todo: "Insert" on table view page
112// todo: edit table structure
113
114error_reporting(-1);
115ini_set('display_errors', true);
116if (!ini_get('date.timezone')) {
117 ini_set('date.timezone', 'Europe/Warsaw');
118}
119
120set_error_handler('errorHandler');
121register_shutdown_function('errorHandler_last');
122ini_set('display_errors', 1);
123global $Global_LastError;
124
125function errorHandler_last()
126{
127 if (function_exists("error_get_last")) {
128 $error = error_get_last();
129 if ($error) {
130 errorHandler($error['type'], $error['message'], $error['file'], $error['line']);
131 }
132 }
133}
134function errorHandler($errno, $errstr, $errfile, $errline)
135{
136 global $Global_LastError;
137 $Global_LastError = $errstr;
138
139 // Check with error_reporting, if statement is preceded with @ we have to ignore it.
140 if (!($errno & error_reporting())) {
141 return;
142 }
143
144 // Headers.
145 if (!headers_sent()) {
146 header('HTTP/1.0 503 Service Unavailable');
147 while (ob_get_level()) { ob_end_clean(); } // This will cancel ob_gzhandler, so later we set Content-encoding to none.
148 header('Content-Encoding: none'); // Fix gzip encoding header.
149 header("Content-Type: text/html; charset=utf-8");
150 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
151 header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
152 header("Cache-Control: no-store, no-cache, must-revalidate");
153 header("Cache-Control: post-check=0, pre-check=0", false);
154 header("Pragma: no-cache");
155 }
156
157 // Error short message.
158 $errfile = basename($errfile);
159
160 $msg = sprintf('%s<br>In %s on line %d.', nl2br($errstr), $errfile, $errline);
161
162 // Display error.
163
164 printf("<!doctype html><html><head><meta charset=utf-8><title>PHP Error</title>");
165 printf("<meta name=\"robots\" content=\"noindex,nofollow\">");
166 printf("<link rel=\"shortcut icon\" href=\"{$_SERVER['PHP_SELF']}?dbkiss_favicon=1\">");
167 printf("<style type=text/css>");
168 printf("body { font: 12px Arial, Sans-serif; line-height: 17px; padding: 0em; margin: 2em 3em; }");
169 printf("h1 { font: bold 18px Tahoma; border-bottom: rgb(175, 50, 0) 1px solid; margin-bottom: 0.85em; padding-bottom: 0.25em; color: rgb(200, 50, 0); text-shadow: 1px 1px 1px #fff; }");
170 print("h2 { font: bold 15px Tahoma; margin-top: 1em; color: #000; text-shadow: 1px 1px 1px #fff; }");
171 printf("</style></head><body>");
172
173 printf("<h1>PHP Error</h1>");
174 printf($msg);
175
176 if ("127.0.0.1" == $_SERVER["SERVER_ADDR"] && "127.0.0.1" == $_SERVER["REMOTE_ADDR"])
177 {
178 // Showing backtrace only on localhost, cause it shows full arguments passed to functions,
179 // that would be a security hole to display such data, cause it could contain some sensitive
180 // data fetched from tables or could even contain a database connection user and password.
181
182 printf("<h2>Backtrace</h2>");
183 ob_start();
184 debug_print_backtrace();
185 $trace = ob_get_clean();
186 $trace = preg_replace("/^#0[\s\S]+?\n#1/", "#1", $trace); // Remove call to errorHandler() from trace.
187 $trace = trim($trace);
188 print nl2br($trace);
189 }
190
191 printf("</body></html>");
192
193 // Log error to file.
194 if ("127.0.0.1" == $_SERVER["SERVER_ADDR"] && "127.0.0.1" == $_SERVER["REMOTE_ADDR"]) {
195 error_log($msg);
196 }
197
198 // Email error.
199
200 exit();
201}
202
203// You can access this function only on localhost.
204
205if ("127.0.0.1" == $_SERVER["SERVER_ADDR"] && "127.0.0.1" == $_SERVER["REMOTE_ADDR"])
206{
207 function dump($data)
208 {
209 // @dump
210
211 if (!headers_sent()) {
212 header('HTTP/1.0 503 Service Unavailable');
213 while (ob_get_level()) { ob_end_clean(); } // This will cancel ob_gzhandler, so later we set Content-encoding to none.
214 header('Content-encoding: none'); // Fix gzip encoding header.
215 header("Content-type: text/html");
216 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
217 header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
218 header("Cache-Control: no-store, no-cache, must-revalidate");
219 header("Cache-Control: post-check=0, pre-check=0", false);
220 header("Pragma: no-cache");
221 }
222
223 if (func_num_args() > 1) { $data = func_get_args(); }
224
225 if ($data && count($data) == 2 && isset($data[1]) && "windows-1250" == strtolower($data[1])) {
226 $charset = "windows-1250";
227 $data = $data[0];
228 } else if ($data && count($data) == 2 && isset($data[1]) && "iso-8859-2" == strtolower($data[1])) {
229 $charset = "iso-8859-2";
230 $data = $data[0];
231 } else {
232 $charset = "utf-8";
233 }
234
235 printf('<!doctype html><head><meta charset='.$charset.'><title>dump()</title></head><body>');
236 printf('<h1 style="color: rgb(150,15,225);">dump()</h1>');
237 ob_start();
238 print_r($data);
239 $html = ob_get_clean();
240 $html = htmlspecialchars($html);
241 printf('<pre>%s</pre>', $html);
242 printf('</body></html>');
243 exit();
244 }
245}
246
247if (isset($_GET['dbkiss_favicon'])) {
248 $favicon = 'AAABAAIAEBAAAAEACABoBQAAJgAAABAQAAABACAAaAQAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wDQcRIAAGaZAL5mCwCZ//8Av24SAMVwEgCa//8AvmcLAKn//wAV0/8Awf//AErL5QDGcBIAvnESAHCpxgDf7PIA37aIAMNpDQDHcRIAZO7/AErl/wAdrNYAYMbZAI/1+QDouYkAO+D/AIT4/wDHcBIAjPr/AMJvEgDa//8AQIyzAMNvEgCfxdkA8v//AEzl/wB46fQAMLbZACms1gAAeaYAGou1AJfX6gAYo84AHrLbAN+zhgCXxtkAv/P5AI30+ADv9fkAFH2pABja/wDGaw4AwXASAAVwoQDjuIkAzXARADCmyQAAe64Ade35AMBxEgC+aQ0AAKnGACnw/wAngqwAxW8RABBwnwAAg6wAxW4QAL7w9wCG7PIAHKnSAMFsDwC/ZwwADnWkAASQwgAd1v8Aj7zSAMZvEQDv+fwABXSmABZ+qgAC6fIAAG+iAMhsDwAcz/kAvmsOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICOTUTCQQECRMQEQACAgICVUpJEgEfBxRCJ1FOAgEBGgQ4AQEGAQEBDhZWAwICAgEEASIBBgEHFA4WTQMCAgECBAE2AQ8BDw89QDQDAgECAgQBVwEJAQQJPj9TKQIaAQEELgESBgEHHUU6N0QCAgICBA4iBgYfBx1PDUgDAAAAAAMcJQsLGxUeJg0XAwAAAAADHCULCxsVHiYNFwMAAAAAAzwtTDtUAwNLKiwDAAAAAAMoK0YMCggFRxgzAwAAAAADUCQgDAoIBQUFGQMAAAAAQzIkIAwKCAUFBRkDAAAAACNBLzAMCggFMRhSIwAAAAAAERAhAwMDAyEQEQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAD4AQAAKAAAABAAAAAgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMxmAO3MZgDtzGYA7cxmAO3MZgDtymYB78RmBvfCZgj6vmYK/r5mC/++Zgv/vmYK/sJmCPoAZpmPAGaZIAAAAADMZgDtzGYA7cxmAO3MZgDtxmYF9b9nDP/BbA//37aI///////CbxL/xXAS/8dxEv/FbxH/MLbZ/wV0pv8AZplwzGYA7f//////////57aF9r5mC//juIn///////////+/bhL/////////////////xnAS/0rl//8cz/n/AGaZ/8xmAO3MZgDtzGYA7f////++Zgv//////8NvEv//////v24S///////FcBL/x3ES/8ZwEv9K5f//Hdb//wBmmf/MZgDtzGYA7f/////MZgDtvmYL///////BcBL//////75xEv//////vnES/75xEv/AcRL/KfD//xja//8AZpn/zGYA7f/////MZgDtzGYA7b5mC///////vmsO//////++Zwv//////75mC/++Zwv/vmkN/wCpxv8C6fL/AHmm/8xmAO3ntoX2//////////++Zgv/37OG///////ftoj/v24S///////FcBL/x3AS/8VuEP8wpsn/BXCh/wCDrP/MZgDtzGYA7cxmAO3MZgDtvmYL/8ZwEv/DbxL/v24S/79uEv/CbxL/xXAS/8dwEv/GbxH/Ssvl/xyp0v8AZpn/AAAAAAAAAAAAAAAAAAAAAABmmf+E+P//TOX//xXT//8V0///O+D//2Tu//+M+v//eOn0/0rL5f8drNb/AGaZ/wAAAAAAAAAAAAAAAAAAAAAAZpn/hPj//0zl//8V0///FdP//zvg//9k7v//jPr//3jp9P9Ky+X/HazW/wBmmf8AAAAAAAAAAAAAAAAAAAAAAGaZ/3Xt+f8estv/BJDC/wB7rv8Ab6L/AGaZ/wBmmf8OdaT/Gou1/xijzv8AZpn/AAAAAAAAAAAAAAAAAAAAAABmmf8prNb/l9fq/77w9//B////qf///5r///+Z////huzy/2DG2f8Ufan/AGaZ/wAAAAAAAAAAAAAAAAAAAAAAZpn/7/n8//L////a////wf///6n///+a////mf///5n///+Z////j/X5/wBmmf8AAAAAAAAAAAAAAAAAAAAAAGaZ7+/1+f/y////2v///8H///+p////mv///5n///+Z////mf///4/1+f8AZpn/AAAAAAAAAAAAAAAAAAAAAABmmWAngqz/l8bZ/7/z+f/B////qf///5r///+Z////jfT4/2DG2f8Wfqr/AGaZYAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaZIABmmY8AZpm/AGaZ/wBmmf8AZpn/AGaZ/wBmmb8AZpmPAGaZIAAAAAAAAQICAAA1EwAABAkAABEAAAACAgAASRIAAAcUAABRTvAAARrwAAEB8AABAfAAVgPwAAIB8AAiAfAABxT4AU0D';
249 header('Content-type: image/vnd.microsoft.icon');
250 echo base64_decode($favicon);
251 exit();
252}
253
254if (!function_exists('array_walk_recursive'))
255{
256 function array_walk_recursive(&$array, $func)
257 {
258 foreach ($array as $k => $v) {
259 if (is_array($v)) {
260 array_walk_recursive($array[$k], $func);
261 } else {
262 $func($array[$k], $k);
263 }
264 }
265 }
266}
267function create_links($text)
268{
269 // Protocols: http, https, ftp, irc, svn
270 // Parse emails also?
271
272 $text = preg_replace('#([a-z]+://[a-zA-Z0-9\.\,\;\:\[\]\{\}\-\_\+\=\!\@\#\%\&\(\)\/\?\`\~]+)#e', 'create_links_eval("\\1")', $text);
273
274 // Excaptions:
275
276 // 1) cut last char if link ends with ":" or ";" or "." or "," - cause in 99% cases that char doesnt belong to the link
277 // (check if previous char was "=" then let it stay cause that could be some variable in a query, some kind of separator)
278 // (should we add also "-" ? But it is a valid char in links and very common, many links might end with it when creating from some title of an article?)
279
280 // 2) brackets, the link could be inside one of 3 types of brackets:
281 // [http://...] , {http://...}
282 // and most common: (http://some.com/) OR http://some.com(some description of the link)
283 // In these cases regular expression will catch: "http://some.com/)" AND "http://some.com(some"
284 // So when we catch some kind of bracket in the link we will cut it unless there is also a closing bracket in the link:
285 // We will not cut brackets in this link: http://en.wikipedia.org/wiki/Common_(entertainer) - wikipedia often uses brackets.
286
287 return $text;
288}
289function create_links_eval($link)
290{
291 $orig_link = $link;
292 $cutted = "";
293
294 if (in_array($link[strlen($link)-1], array(":", ";", ".", ","))) {
295 $link = substr($link, 0, -1);
296 $cutted = $orig_link[strlen($orig_link)-1];
297 }
298
299 if (($pos = strpos($link, "(")) !== false) {
300 if (strpos($link, ")") === false) {
301 $link = substr($link, 0, $pos);
302 $cutted = substr($orig_link, $pos);
303 }
304 } else if (($pos = strpos($link, ")")) !== false) {
305 if (strpos($link, "(") === false) {
306 $link = substr($link, 0, $pos);
307 $cutted = substr($orig_link, $pos);
308 }
309 } else if (($pos = strpos($link, "[")) !== false) {
310 if (strpos($link, "]") === false) {
311 $link = substr($link, 0, $pos);
312 $cutted = substr($orig_link, $pos);
313 }
314 } else if (($pos = strpos($link, "]")) !== false) {
315 if (strpos($link, "[") === false) {
316 $link = substr($link, 0, $pos);
317 $cutted = substr($orig_link, $pos);
318 }
319 } else if (($pos = strpos($link, "{")) !== false) {
320 if (strpos($link, "}") === false) {
321 $link = substr($link, 0, $pos);
322 $cutted = substr($orig_link, $pos);
323 }
324 } else if (($pos = strpos($link, "}")) !== false) {
325 if (strpos($link, "{") === false) {
326 $link = substr($link, 0, $pos);
327 $cutted = substr($orig_link, $pos);
328 }
329 }
330 return "<a title=\"$link\" style=\"color: #000; text-decoration: none; border-bottom: #000 1px dotted;\" href=\"javascript:;\" onclick=\"link_noreferer('$link')\">$link</a>$cutted";
331}
332function truncate_html($string, $length, $break_words = false, $end_str = '..')
333{
334 // Does not break html tags whilte truncating, does not take into account chars inside tags: <b>a</b> = 1 char length.
335 // Break words is always TRUE - no breaking is not implemented.
336
337 // Limits: no handling of <script> tags.
338
339 $inside_tag = false;
340 $inside_amp = 0;
341 $finished = false; // finished but the loop is still running cause inside tag or amp.
342 $opened = 0;
343
344 $string_len = strlen($string);
345
346 $count = 0;
347 $ret = "";
348
349 for ($i = 0; $i < $string_len; $i++)
350 {
351 $char = $string[$i];
352 $nextchar = isset($string[$i+1]) ? $string[$i+1] : null;
353
354 if ('<' == $char && ('/' == $nextchar || ctype_alpha($nextchar))) {
355 if ('/' == $nextchar) {
356 $opened--;
357 } else {
358 $opened++;
359 }
360 $inside_tag = true;
361 }
362 if ('>' == $char) {
363 $inside_tag = false;
364 $ret .= $char;
365 continue;
366 }
367 if ($inside_tag) {
368 $ret .= $char;
369 continue;
370 }
371
372 if (!$finished)
373 {
374 if ('&' == $char) {
375 $inside_amp = 1;
376 $ret .= $char;
377 continue;
378 }
379 if (';' == $char && $inside_amp) {
380 $inside_amp = 0;
381 $count++;
382 $ret .= $char;
383 continue;
384 }
385 if ($inside_amp) {
386 $inside_amp++;
387 $ret .= $char;
388 if ('#' == $char || ctype_alnum($char)) {
389 if ($inside_amp > 7) {
390 $count += $inside_amp;
391 $inside_amp = 0;
392 }
393 } else {
394 $count += $inside_amp;
395 $inside_amp = 0;
396 }
397 continue;
398 }
399 }
400
401 $count++;
402
403 if (!$finished) {
404 $ret .= $char;
405 }
406
407 if ($count >= $length) {
408 if (!$inside_tag && !$inside_amp) {
409 if (!$finished) {
410 $ret .= $end_str;
411 $finished = true;
412 if (0 == $opened) {
413 break;
414 }
415 }
416 if (0 == $opened) {
417 break;
418 }
419 }
420 }
421 }
422 return $ret;
423}
424function table_filter($tables, $filter)
425{
426 $filter = trim($filter);
427 if ($filter) {
428 foreach ($tables as $k => $table) {
429 if (!str_has_any($table, $filter, $ignore_case = true)) {
430 unset($tables[$k]);
431 }
432 }
433 }
434 return $tables;
435}
436function get($key, $type='string')
437{
438 if (is_string($key)) {
439 $_GET[$key] = isset($_GET[$key]) ? $_GET[$key] : null;
440 if ('float' == $type) $_GET[$key] = str_replace(',','.',$_GET[$key]);
441 settype($_GET[$key], $type);
442 if ('string' == $type) $_GET[$key] = trim($_GET[$key]);
443 return $_GET[$key];
444 }
445 $vars = $key;
446 foreach ($vars as $key => $type) {
447 $_GET[$key] = isset($_GET[$key]) ? $_GET[$key] : null;
448 if ('float' == $type) $_GET[$key] = str_replace(',','.',$_GET[$key]);
449 settype($_GET[$key], $type);
450 if ('string' == $type) $_GET[$key] = trim($_GET[$key]);
451 $vars[$key] = $_GET[$key];
452 }
453 return $vars;
454}
455function post($key, $type='string')
456{
457 if (is_string($key)) {
458 $_POST[$key] = isset($_POST[$key]) ? $_POST[$key] : null;
459 if ('float' == $type) $_POST[$key] = str_replace(',','.',$_POST[$key]);
460 settype($_POST[$key], $type);
461 if ('string' == $type) $_POST[$key] = trim($_POST[$key]);
462 return $_POST[$key];
463 }
464 $vars = $key;
465 foreach ($vars as $key => $type) {
466 $_POST[$key] = isset($_POST[$key]) ? $_POST[$key] : null;
467 if ('float' == $type) $_POST[$key] = str_replace(',','.',$_POST[$key]);
468 settype($_POST[$key], $type);
469 if ('string' == $type) $_POST[$key] = trim($_POST[$key]);
470 $vars[$key] = $_POST[$key];
471 }
472 return $vars;
473}
474$_ENV['IS_GET'] = ('GET' == $_SERVER['REQUEST_METHOD']);
475$_ENV['IS_POST'] = ('POST' == $_SERVER['REQUEST_METHOD']);
476function req_gpc_has($str)
477{
478 /* finds if value exists in GPC data, used in filter_() functions, to check whether use html_tags_undo() on the data */
479 foreach ($_GET as $k => $v) {
480 if ($str == $v) {
481 return true;
482 }
483 }
484 foreach ($_POST as $k => $v) {
485 if ($str == $v) {
486 return true;
487 }
488 }
489 foreach ($_COOKIE as $k => $v) {
490 if ($str == $v) {
491 return true;
492 }
493 }
494 return false;
495}
496
497if (ini_get('magic_quotes_gpc')) {
498 ini_set('magic_quotes_runtime', 0);
499 array_walk_recursive($_GET, 'db_magic_quotes_gpc');
500 array_walk_recursive($_POST, 'db_magic_quotes_gpc');
501 array_walk_recursive($_COOKIE, 'db_magic_quotes_gpc');
502}
503function db_magic_quotes_gpc(&$val)
504{
505 $val = stripslashes($val);
506}
507
508$sql_font = 'font-size: 12px; font-family: courier new;';
509$sql_area = $sql_font.' width: 708px; height: 182px; border: #ccc 1px solid; background: #f9f9f9; padding: 3px;';
510
511if (!isset($db_name_style)) {
512 $db_name_style = '';
513}
514if (!isset($db_name_h1)) {
515 $db_name_h1 = '';
516}
517
518global $db_link, $db_name;
519
520if (!defined('COOKIE_PREFIX')) {
521 define('COOKIE_PREFIX', 'dbkiss_');
522}
523
524define('COOKIE_WEEK', 604800); // 3600*24*7
525define('COOKIE_SESS', 0);
526function cookie_get($key)
527{
528 $key = COOKIE_PREFIX.$key;
529 if (isset($_COOKIE[$key])) return $_COOKIE[$key];
530 return null;
531}
532function cookie_set($key, $val, $time = COOKIE_SESS)
533{
534 $key = COOKIE_PREFIX.$key;
535 $expire = $time ? time() + $time : 0;
536 if (version_compare(PHP_VERSION, '5.2.0', '>=')) {
537 setcookie($key, $val, $expire, '', '', false, true);
538 } else {
539 setcookie($key, $val, $expire);
540 }
541 $_COOKIE[$key] = $val;
542}
543function cookie_del($key)
544{
545 $key = COOKIE_PREFIX.$key;
546 if (version_compare(PHP_VERSION, '5.2.0', '>=')) {
547 setcookie($key, '', time()-3600*24, '', '', false, true);
548 } else {
549 setcookie($key, '', time()-3600*24);
550 }
551 unset($_COOKIE[$key]);
552}
553
554conn_modify('db_name');
555conn_modify('db_charset');
556conn_modify('page_charset');
557
558function conn_modify($key)
559{
560 if (array_key_exists($key, $_GET)) {
561 cookie_set($key, $_GET[$key], cookie_get('remember') ? COOKIE_WEEK : COOKIE_SESS);
562 if (isset($_GET['from']) && $_GET['from']) {
563 header('Location: '.$_GET['from']);
564 } else {
565 header('Location: '.$_SERVER['PHP_SELF']);
566 }
567 exit;
568 }
569}
570
571$db_driver = cookie_get('db_driver');
572$db_server = cookie_get('db_server');
573$db_name = cookie_get('db_name');
574$db_user = cookie_get('db_user');
575$db_pass = base64_decode(cookie_get('db_pass'));
576$db_charset = cookie_get('db_charset');
577$page_charset = cookie_get('page_charset');
578
579$charset1 = array('latin1', 'latin2', 'utf8', 'cp1250');
580$charset2 = array('iso-8859-1', 'iso-8859-2', 'utf-8', 'windows-1250');
581$charset1[] = $db_charset;
582$charset2[] = $page_charset;
583$charset1 = charset_assoc($charset1);
584$charset2 = charset_assoc($charset2);
585
586$driver_arr = array('mysql', 'pgsql');
587$driver_arr = array_assoc($driver_arr);
588
589function array_assoc($a)
590{
591 $ret = array();
592 foreach ($a as $v) {
593 $ret[$v] = $v;
594 }
595 return $ret;
596}
597function charset_assoc($arr)
598{
599 sort($arr);
600 $ret = array();
601 foreach ($arr as $v) {
602 if (!$v) { continue; }
603 $v = strtolower($v);
604 $ret[$v] = $v;
605 }
606 return $ret;
607}
608
609
610if (isset($_GET['disconnect']) && $_GET['disconnect'])
611{
612 cookie_del('db_pass');
613 header('Location: '.$_SERVER['PHP_SELF']);
614 exit;
615}
616
617if (!$db_pass || (!$db_driver || !$db_server || !$db_name || !$db_user))
618{
619 if ('POST' == $_SERVER['REQUEST_METHOD'])
620 {
621 $db_driver = post('db_driver');
622 $db_server = post('db_server');
623 $db_name = post('db_name');
624 $db_user = post('db_user');
625 $db_pass = post('db_pass');
626 $db_charset = post('db_charset');
627 $page_charset = post('page_charset');
628
629 if ($db_driver && $db_server && $db_name && $db_user)
630 {
631 $db_test = true;
632 db_connect($db_server, $db_name, $db_user, $db_pass);
633 if (is_resource($db_link))
634 {
635 $time = post('remember') ? COOKIE_WEEK : COOKIE_SESS;
636 cookie_set('db_driver', $db_driver, $time);
637 cookie_set('db_server', $db_server, $time);
638 cookie_set('db_name', $db_name, $time);
639 cookie_set('db_user', $db_user, $time);
640 cookie_set('db_pass', base64_encode($db_pass), $time);
641 cookie_set('db_charset', $db_charset, $time);
642 cookie_set('page_charset', $page_charset, $time);
643 cookie_set('remember', post('remember'), $time);
644 header('Location: '.$_SERVER['PHP_SELF']);
645 exit;
646 }
647 }
648 }
649 else
650 {
651 $_POST['db_driver'] = $db_driver;
652 $_POST['db_server'] = $db_server ? $db_server : 'localhost';
653 $_POST['db_name'] = $db_name;
654 $_POST['db_user'] = $db_user;
655 $_POST['db_charset'] = $db_charset;
656 $_POST['page_charset'] = $page_charset;
657 $_POST['db_driver'] = $db_driver;
658 }
659 ?>
660
661 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
662 <html>
663 <head>
664 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
665 <title>Connect</title>
666 <link rel="shortcut icon" href="<?php echo $_SERVER['PHP_SELF']; ?>?dbkiss_favicon=1">
667 </head>
668 <body>
669
670 <?php layout(); ?>
671
672 <h1>Connect</h1>
673
674 <?php if (isset($db_test) && is_string($db_test)): ?>
675 <div style="background: #ffffd7; padding: 0.5em; border: #ccc 1px solid; margin-bottom: 1em;">
676 <span style="color: red; font-weight: bold;">Error:</span>
677 <?php echo $db_test;?>
678 </div>
679 <?php endif; ?>
680
681 <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
682 <table class="ls ls2" cellspacing="1">
683 <tr>
684 <th>Driver:</th>
685 <td><select name="db_driver"><?php echo options($driver_arr, post('db_driver'));?></select></td>
686 </tr>
687 <tr>
688 <th>Server:</th>
689 <td><input type="text" name="db_server" value="<?php echo post('db_server');?>"></td>
690 </tr>
691 <tr>
692 <th>Database:</th>
693 <td><input type="text" name="db_name" value="<?php echo post('db_name');?>"></td>
694 </tr>
695 <tr>
696 <th>User:</th>
697 <td><input type="text" name="db_user" value="<?php echo post('db_user');?>"></td>
698 </tr>
699 <tr>
700 <th>Password:</th>
701 <td><input type="password" name="db_pass" value=""></td>
702 </tr>
703 <tr>
704 <th>Db charset:</th>
705 <td><input type="text" name="db_charset" value="<?php echo post('db_charset');?>" size="10"> (optional)</td>
706 </tr>
707 <tr>
708 <th>Page charset:</th>
709 <td><input type="text" name="page_charset" value="<?php echo post('page_charset');?>" size="10"> (optional)</td>
710 </tr>
711 <tr>
712 <td colspan="2" class="none" style="padding: 0; background: none; padding-top: 0.3em;">
713 <table cellspacing="0" cellpadding="0"><tr><td>
714 <input type="checkbox" name="remember" id="remember" value="1" <?php echo checked(post('remember'));?>></td><td>
715 <label for="remember">remember me on this computer</label></td></tr></table>
716 </td>
717 </tr>
718 <tr>
719 <td class="none" colspan="2" style="padding-top: 0.4em;"><input type="submit" value="Connect"></td>
720 </tr>
721 </table>
722 </form>
723
724 <?php powered_by(); ?>
725
726 </body>
727 </html>
728
729 <?php
730
731 exit;
732}
733
734db_connect($db_server, $db_name, $db_user, $db_pass);
735
736if ($db_charset && 'mysql' == $db_driver) {
737 db_exe("SET NAMES $db_charset");
738}
739
740if (isset($_GET['dump_all']) && 1 == $_GET['dump_all'])
741{
742 dump_all($data = false);
743}
744if (isset($_GET['dump_all']) && 2 == $_GET['dump_all'])
745{
746 dump_all($data = true);
747}
748if (isset($_GET['dump_table']) && $_GET['dump_table'])
749{
750 dump_table($_GET['dump_table']);
751}
752if (isset($_GET['export']) && 'csv' == $_GET['export'])
753{
754 export_csv(base64_decode($_GET['query']), $_GET['separator']);
755}
756if (isset($_POST['sqlfile']) && $_POST['sqlfile'])
757{
758 $files = sql_files_assoc();
759 if (!isset($files[$_POST['sqlfile']])) {
760 exit('File not found. md5 = '.$_POST['sqlfile']);
761 }
762 $sqlfile = $files[$_POST['sqlfile']];
763 layout();
764 echo '<div>Importing: <b>'.$sqlfile.'</b> ('.size(filesize($sqlfile)).')</div>';
765 echo '<div>Database: <b>'.$db_name.'</b></div>';
766 flush();
767 import($sqlfile, post('ignore_errors'), post('transaction'), post('force_myisam'), post('query_start','int'));
768 exit;
769}
770if (isset($_POST['drop_table']) && $_POST['drop_table'])
771{
772 $drop_table_enq = quote_table($_POST['drop_table']);
773 db_exe('DROP TABLE '.$drop_table_enq);
774 header('Location: '.$_SERVER['PHP_SELF']);
775 exit;
776}
777if (isset($_POST['drop_view']) && $_POST['drop_view'])
778{
779 $drop_view_enq = quote_table($_POST['drop_view']);
780 db_exe('DROP VIEW '.$drop_view_enq);
781 header('Location: '.$_SERVER['PHP_SELF']);
782 exit;
783}
784function db_connect($db_server, $db_name, $db_user, $db_pass)
785{
786 global $db_driver, $db_link, $db_test;
787 if (!extension_loaded($db_driver)) {
788 trigger_error($db_driver.' extension not loaded', E_USER_ERROR);
789 }
790 if ('mysql' == $db_driver)
791 {
792 $db_link = @mysql_connect($db_server, $db_user, $db_pass);
793 if (!is_resource($db_link)) {
794 if ($db_test) {
795 $db_test = 'mysql_connect() failed: '.db_error();
796 return;
797 } else {
798 cookie_del('db_pass');
799 cookie_del('db_name');
800 die('mysql_connect() failed: '.db_error());
801 }
802 }
803 if (!@mysql_select_db($db_name, $db_link)) {
804 $error = db_error();
805 db_close();
806 if ($db_test) {
807 $db_test = 'mysql_select_db() failed: '.$error;
808 return;
809 } else {
810 cookie_del('db_pass');
811 cookie_del('db_name');
812 die('mysql_select_db() failed: '.$error);
813 }
814 }
815 }
816 if ('pgsql' == $db_driver)
817 {
818 $conn = sprintf("host='%s' dbname='%s' user='%s' password='%s'", $db_server, $db_name, $db_user, $db_pass);
819 $db_link = @pg_connect($conn);
820 if (!is_resource($db_link)) {
821 if ($db_test) {
822 $db_test = 'pg_connect() failed: '.db_error();
823 return;
824 } else {
825 cookie_del('db_pass');
826 cookie_del('db_name');
827 die('pg_connect() failed: '.db_error());
828 }
829 }
830 }
831 register_shutdown_function('db_cleanup');
832}
833function db_cleanup()
834{
835 db_close();
836}
837function db_close()
838{
839 global $db_driver, $db_link;
840 if (is_resource($db_link)) {
841 if ('mysql' == $db_driver) {
842 mysql_close($db_link);
843 }
844 if ('pgsql' == $db_driver) {
845 pg_close($db_link);
846 }
847 }
848}
849function db_query($query, $dat = false)
850{
851 global $db_driver, $db_link;
852 $query = db_bind($query, $dat);
853 if (!db_is_safe($query)) {
854 return false;
855 }
856 if ('mysql' == $db_driver)
857 {
858 $rs = mysql_query($query, $db_link);
859 if (!$rs) {
860 trigger_error("mysql_query() failed: $query.<br>Error: ".db_error(), E_USER_ERROR);
861 }
862 return $rs;
863 }
864 if ('pgsql' == $db_driver)
865 {
866 $rs = pg_query($db_link, $query);
867 if (!$rs) {
868 trigger_error("pg_query() failed: $query.<br>Error: ".db_error(), E_USER_ERROR);
869 }
870 return $rs;
871 }
872}
873function db_is_safe($q, $ret = false)
874{
875 // currently only checks UPDATE's/DELETE's if WHERE condition is not missing
876 $upd = 'update';
877 $del = 'delete';
878
879 $q = ltrim($q);
880 if (strtolower(substr($q, 0, strlen($upd))) == $upd
881 || strtolower(substr($q, 0, strlen($del))) == $del) {
882 if (!preg_match('#\swhere\s#i', $q)) {
883 if ($ret) {
884 return false;
885 } else {
886 trigger_error(sprintf('db_is_safe() failed. Detected UPDATE/DELETE without WHERE condition. Query: %s.', $q), E_USER_ERROR);
887 return false;
888 }
889 }
890 }
891
892 return true;
893}
894function db_exe($query, $dat = false)
895{
896 $rs = db_query($query, $dat);
897 db_free($rs);
898}
899function db_one($query, $dat = false)
900{
901 $row = db_row_num($query, $dat);
902 if ($row) {
903 return $row[0];
904 } else {
905 return false;
906 }
907}
908function db_row($query, $dat = false)
909{
910 global $db_driver, $db_link;
911 if ('mysql' == $db_driver)
912 {
913 if (is_resource($query)) {
914 $rs = $query;
915 return mysql_fetch_assoc($rs);
916 } else {
917 $query = db_limit($query, 0, 1);
918 $rs = db_query($query, $dat);
919 $row = mysql_fetch_assoc($rs);
920 db_free($rs);
921 if ($row) {
922 return $row;
923 }
924 }
925 return false;
926 }
927 if ('pgsql' == $db_driver)
928 {
929 if (is_resource($query) || is_object($query)) {
930 $rs = $query;
931 return pg_fetch_assoc($rs);
932 } else {
933 $query = db_limit($query, 0, 1);
934 $rs = db_query($query, $dat);
935 $row = pg_fetch_assoc($rs);
936 db_free($rs);
937 if ($row) {
938 return $row;
939 }
940 }
941 return false;
942 }
943}
944function db_row_num($query, $dat = false)
945{
946 global $db_driver, $db_link;
947 if ('mysql' == $db_driver)
948 {
949 if (is_resource($query)) {
950 $rs = $query;
951 return mysql_fetch_row($rs);
952 } else {
953 $rs = db_query($query, $dat);
954 if (!$rs) {
955 /*
956 echo '<pre>';
957 print_r($rs);
958 echo "\r\n";
959 print_r($query);
960 echo "\r\n";
961 print_r($dat);
962 exit;
963 */
964 }
965 $row = mysql_fetch_row($rs);
966 db_free($rs);
967 if ($row) {
968 return $row;
969 }
970 return false;
971 }
972 }
973 if ('pgsql' == $db_driver)
974 {
975 if (is_resource($query) || is_object($query)) {
976 $rs = $query;
977 return pg_fetch_row($rs);
978 } else {
979 $rs = db_query($query, $dat);
980 $row = pg_fetch_row($rs);
981 db_free($rs);
982 if ($row) {
983 return $row;
984 }
985 return false;
986 }
987 }
988}
989function db_list($query)
990{
991 global $db_driver, $db_link;
992 $rs = db_query($query);
993 $ret = array();
994 if ('mysql' == $db_driver) {
995 while ($row = mysql_fetch_assoc($rs)) {
996 $ret[] = $row;
997 }
998 }
999 if ('pgsql' == $db_driver) {
1000 while ($row = pg_fetch_assoc($rs)) {
1001 $ret[] = $row;
1002 }
1003 }
1004 db_free($rs);
1005 return $ret;
1006}
1007function db_assoc($query)
1008{
1009 global $db_driver, $db_link;
1010 $rs = db_query($query);
1011 $rows = array();
1012 $num = db_row_num($rs);
1013 if (!is_array($num)) {
1014 return array();
1015 }
1016 if (!array_key_exists(0, $num)) {
1017 return array();
1018 }
1019 if (1 == count($num)) {
1020 $rows[] = $num[0];
1021 while ($num = db_row_num($rs)) {
1022 $rows[] = $num[0];
1023 }
1024 return $rows;
1025 }
1026 if ('mysql' == $db_driver)
1027 {
1028 mysql_data_seek($rs, 0);
1029 }
1030 if ('pgsql' == $db_driver)
1031 {
1032 pg_result_seek($rs, 0);
1033 }
1034 $row = db_row($rs);
1035 if (!is_array($row)) {
1036 return array();
1037 }
1038 if (count($num) < 2) {
1039 trigger_error(sprintf('db_assoc() failed. Two fields required. Query: %s.', $query), E_USER_ERROR);
1040 }
1041 if (count($num) > 2 && count($row) <= 2) {
1042 trigger_error(sprintf('db_assoc() failed. If specified more than two fields, then each of them must have a unique name. Query: %s.', $query), E_USER_ERROR);
1043 }
1044 foreach ($row as $k => $v) {
1045 $first_key = $k;
1046 break;
1047 }
1048 if (count($row) > 2) {
1049 $rows[$row[$first_key]] = $row;
1050 while ($row = db_row($rs)) {
1051 $rows[$row[$first_key]] = $row;
1052 }
1053 } else {
1054 $rows[$num[0]] = $num[1];
1055 while ($num = db_row_num($rs)) {
1056 $rows[$num[0]] = $num[1];
1057 }
1058 }
1059 db_free($rs);
1060 return $rows;
1061}
1062function db_limit($query, $offset, $limit)
1063{
1064 global $db_driver;
1065
1066 $offset = (int) $offset;
1067 $limit = (int) $limit;
1068
1069 $query = trim($query);
1070 if (str_ends_with($query, ';')) {
1071 $query = str_cut_end($query, ';');
1072 }
1073
1074 $query = preg_replace('#^([\s\S]+)LIMIT\s+\d+\s+OFFSET\s+\d+\s*$#i', '$1', $query);
1075 $query = preg_replace('#^([\s\S]+)LIMIT\s+\d+\s*,\s*\d+\s*$#i', '$1', $query);
1076
1077 if ('mysql' == $db_driver) {
1078 // mysql 3.23 doesn't understand "LIMIT x OFFSET z"
1079 return $query." LIMIT $offset, $limit";
1080 } else {
1081 return $query." LIMIT $limit OFFSET $offset";
1082 }
1083}
1084function db_escape($value)
1085{
1086 global $db_driver, $db_link;
1087 if ('mysql' == $db_driver) {
1088 return mysql_real_escape_string($value, $db_link);
1089 }
1090 if ('pgsql' == $db_driver) {
1091 return pg_escape_string($value);
1092 }
1093}
1094function db_quote($s)
1095{
1096 switch (true) {
1097 case is_null($s): return 'NULL';
1098 case is_int($s): return $s;
1099 case is_float($s): return $s;
1100 case is_bool($s): return (int) $s;
1101 case is_string($s): return "'" . db_escape($s) . "'";
1102 case is_object($s): return $s->getValue();
1103 default:
1104 trigger_error(sprintf("db_quote() failed. Invalid data type: '%s'.", gettype($s)), E_USER_ERROR);
1105 return false;
1106 }
1107}
1108function db_strlen_cmp($a, $b)
1109{
1110 if (strlen($a) == strlen($b)) {
1111 return 0;
1112 }
1113 return strlen($a) > strlen($b) ? -1 : 1;
1114}
1115function db_bind($q, $dat)
1116{
1117 if (false === $dat) {
1118 return $q;
1119 }
1120 if (!is_array($dat)) {
1121 //return trigger_error('db_bind() failed. Second argument expects to be an array.', E_USER_ERROR);
1122 $dat = array($dat);
1123 }
1124
1125 $qBase = $q;
1126
1127 // special case: LIKE '%asd%', need to ignore that
1128 $q_search = array("'%", "%'");
1129 $q_replace = array("'\$", "\$'");
1130 $q = str_replace($q_search, $q_replace, $q);
1131
1132 preg_match_all('#%\w+#', $q, $match);
1133 if ($match) {
1134 $match = $match[0];
1135 }
1136 if (!$match || !count($match)) {
1137 return trigger_error('db_bind() failed. No binding keys found in the query.', E_USER_ERROR);
1138 }
1139 $keys = $match;
1140 usort($keys, 'db_strlen_cmp');
1141 $num = array();
1142
1143 foreach ($keys as $key)
1144 {
1145 $key2 = str_replace('%', '', $key);
1146 if (is_numeric($key2)) $num[$key] = true;
1147 if (!array_key_exists($key2, $dat)) {
1148 return trigger_error(sprintf('db_bind() failed. No data found for key: %s. Query: %s.', $key, $qBase), E_USER_ERROR);
1149 }
1150 $q = str_replace($key, db_quote($dat[$key2]), $q);
1151 }
1152 if (count($num)) {
1153 if (count($dat) != count($num)) {
1154 return trigger_error('db_bind() failed. When using numeric data binding you need to use all data passed to the query. You also cannot mix numeric and name binding.', E_USER_ERROR);
1155 }
1156 }
1157
1158 $q = str_replace($q_replace, $q_search, $q);
1159
1160 return $q;
1161}
1162function db_free($rs)
1163{
1164 global $db_driver;
1165 if (db_is_result($rs)) {
1166 if ('mysql' == $db_driver) return mysql_free_result($rs);
1167 if ('pgsql' == $db_driver) return pg_free_result($rs);
1168 }
1169}
1170function db_is_result($rs)
1171{
1172 global $db_driver;
1173 if ('mysql' == $db_driver) return is_resource($rs);
1174 if ('pgsql' == $db_driver) return is_object($rs) || is_resource($rs);
1175}
1176function db_error()
1177{
1178 global $db_driver, $db_link;
1179 if ('mysql' == $db_driver) {
1180 if (is_resource($db_link)) {
1181 if (mysql_error($db_link)) {
1182 return mysql_error($db_link). ' ('. mysql_errno($db_link).')';
1183 } else {
1184 return false;
1185 }
1186 } else {
1187 if (mysql_error()) {
1188 return mysql_error(). ' ('. mysql_errno().')';
1189 } else {
1190 return false;
1191 }
1192 }
1193 }
1194 if ('pgsql' == $db_driver) {
1195 if (is_resource($db_link)) {
1196 return pg_last_error($db_link);
1197 }
1198 }
1199}
1200function db_begin()
1201{
1202 global $db_driver;
1203 if ('mysql' == $db_driver) {
1204 db_exe('SET AUTOCOMMIT=0');
1205 db_exe('BEGIN');
1206 }
1207 if ('pgsql' == $db_driver) {
1208 db_exe('BEGIN');
1209 }
1210}
1211function db_end()
1212{
1213 global $db_driver;
1214 if ('mysql' == $db_driver) {
1215 db_exe('COMMIT');
1216 db_exe('SET AUTOCOMMIT=1');
1217 }
1218 if ('pgsql' == $db_driver) {
1219 db_exe('COMMIT');
1220 }
1221}
1222function db_rollback()
1223{
1224 global $db_driver;
1225 if ('mysql' == $db_driver) {
1226 db_exe('ROLLBACK');
1227 db_exe('SET AUTOCOMMIT=1');
1228 }
1229 if ('pgsql' == $db_driver) {
1230 db_exe('ROLLBACK');
1231 }
1232}
1233function db_in_array($arr)
1234{
1235 $in = '';
1236 foreach ($arr as $v) {
1237 if ($in) $in .= ',';
1238 $in .= db_quote($v);
1239 }
1240 return $in;
1241}
1242function db_where($where_array, $field_prefix = null, $omit_where = false)
1243{
1244 $field_prefix = str_replace('.', '', $field_prefix);
1245 $where = '';
1246 if (count($where_array)) {
1247 foreach ($where_array as $wh_k => $wh)
1248 {
1249 if (is_numeric($wh_k)) {
1250 if ($wh) {
1251 if ($field_prefix && !preg_match('#^\s*\w+\.#i', $wh) && !preg_match('#^\s*\w+\s*\(#i', $wh)) {
1252 $wh = $field_prefix.'.'.trim($wh);
1253 }
1254 if ($where) $where .= ' AND ';
1255 $where .= $wh;
1256 }
1257 } else {
1258 if ($wh_k) {
1259 if ($field_prefix && !preg_match('#^\s*\w+\.#i', $wh_k) && !preg_match('#^\s*\w+\s*\(#i', $wh)) {
1260 $wh_k = $field_prefix.'.'.$wh_k;
1261 }
1262 $wh = db_cond($wh_k, $wh);
1263 if ($where) $where .= ' AND ';
1264 $where .= $wh;
1265 }
1266 }
1267 }
1268 if ($where) {
1269 if (!$omit_where) {
1270 $where = ' WHERE '.$where;
1271 }
1272 }
1273 }
1274 return $where;
1275}
1276function db_insert($tbl, $dat)
1277{
1278 global $db_driver;
1279 if (!count($dat)) {
1280 trigger_error('db_insert() failed. Data is empty.', E_USER_ERROR);
1281 return false;
1282 }
1283 $cols = '';
1284 $vals = '';
1285 $first = true;
1286 foreach ($dat as $k => $v) {
1287 if ($first) {
1288 $cols .= $k;
1289 $vals .= db_quote($v);
1290 $first = false;
1291 } else {
1292 $cols .= ',' . $k;
1293 $vals .= ',' . db_quote($v);
1294 }
1295 }
1296 if ('mysql' == $db_driver) {
1297 $tbl = "`$tbl`";
1298 }
1299 $q = "INSERT INTO $tbl ($cols) VALUES ($vals)";
1300 db_exe($q);
1301}
1302// $wh = WHERE condition, might be (string) or (array)
1303function db_update($tbl, $dat, $wh)
1304{
1305 global $db_driver;
1306 if (!count($dat)) {
1307 trigger_error('db_update() failed. Data is empty.', E_USER_ERROR);
1308 return false;
1309 }
1310 $set = '';
1311 $first = true;
1312 foreach ($dat as $k => $v) {
1313 if ($first) {
1314 $set .= $k . '=' . db_quote($v);
1315 $first = false;
1316 } else {
1317 $set .= ',' . $k . '=' . db_quote($v);
1318 }
1319 }
1320 if (is_array($wh)) {
1321 $wh = db_where($wh, null, $omit_where = true);
1322 }
1323 if ('mysql' == $db_driver) {
1324 $tbl = "`$tbl`";
1325 }
1326 $q = "UPDATE $tbl SET $set WHERE $wh";
1327 return db_exe($q);
1328}
1329function db_insert_id($table = null, $pk = null)
1330{
1331 global $db_driver, $db_link;
1332 if ('mysql' == $db_driver) {
1333 return mysql_insert_id($_db['conn_id']);
1334 }
1335 if ('pgsql' == $db_driver) {
1336 if (!$table || !$pk) {
1337 trigger_error('db_insert_id(): table & pk required', E_USER_ERROR);
1338 }
1339 $seq_id = $table.'_'.$pk.'_seq';
1340 return db_seq_id($seq_id);
1341 }
1342}
1343function db_seq_id($seqName)
1344{
1345 return db_one('SELECT currval(%seqName)', array('seqName'=>$seqName));
1346}
1347function db_cond($k, $v)
1348{
1349 if (is_null($v)) return sprintf('%s IS NULL', $k);
1350 else return sprintf('%s = %s', $k, db_quote($v));
1351}
1352function list_dbs()
1353{
1354 global $db_driver, $db_link;
1355 if ('mysql' == $db_driver)
1356 {
1357 $result = mysql_query('SHOW DATABASES', $db_link);
1358 $ret = array();
1359 while ($row = mysql_fetch_row($result)) {
1360 $ret[$row[0]] = $row[0];
1361 }
1362 return $ret;
1363 }
1364 if ('pgsql' == $db_driver)
1365 {
1366 return db_assoc('SELECT datname, datname FROM pg_database');
1367 }
1368}
1369function views_supported()
1370{
1371 static $ret;
1372 if (isset($ret)) {
1373 return $ret;
1374 }
1375 global $db_driver, $db_link;
1376 if ('mysql' == $db_driver) {
1377 $version = mysql_get_server_info($db_link);
1378 if (strpos($version, "-") !== false) {
1379 $version = substr($version, 0, strpos($version, "-"));
1380 }
1381 if (version_compare($version, "5.0.2", ">=")) {
1382 // Views are available in 5.0.0 but we need SHOW FULL TABLES
1383 // and the FULL syntax was added in 5.0.2, FULL allows us to
1384 // to distinct between tables & views in the returned list by
1385 // by providing an additional column.
1386 $ret = true;
1387 return true;
1388 } else {
1389 $ret = false;
1390 return false;
1391 }
1392 }
1393 if ('pgsql' == $db_driver) {
1394 $ret = true;
1395 return true;
1396 }
1397}
1398function list_tables($views_mode=false)
1399{
1400 global $db_driver, $db_link, $db_name;
1401
1402 if ($views_mode && !views_supported()) {
1403 return array();
1404 }
1405
1406 static $cache_tables;
1407 static $cache_views;
1408
1409 if ($views_mode) {
1410 if (isset($cache_views)) {
1411 return $cache_views;
1412 }
1413 } else {
1414 if (isset($cache_tables)) {
1415 return $cache_tables;
1416 }
1417 }
1418
1419 static $all_tables; // tables and views
1420
1421 if ('mysql' == $db_driver)
1422 {
1423 if (!isset($all_tables)) {
1424 $all_tables = db_assoc("SHOW FULL TABLES");
1425 // assoc: table name => table type (BASE TABLE or VIEW)
1426 }
1427
1428 // This chunk of code is the same as in pgsql driver.
1429 if ($views_mode) {
1430 $views = array();
1431 foreach ($all_tables as $view => $type) {
1432 if ($type != 'VIEW') { continue; }
1433 $views[] = $view;
1434 }
1435 $cache_views = $views;
1436 return $views;
1437 } else {
1438 $tables = array();
1439 foreach ($all_tables as $table => $type) {
1440 if ($type != 'BASE TABLE') { continue; }
1441 $tables[] = $table;
1442 }
1443 $cache_tables = $tables;
1444 return $tables;
1445 }
1446 }
1447 if ('pgsql' == $db_driver)
1448 {
1449 if (!isset($all_tables)) {
1450 $query = "SELECT table_name, table_type ";
1451 $query .= "FROM information_schema.tables ";
1452 $query .= "WHERE table_schema = 'public' ";
1453 $query .= "AND (table_type = 'BASE TABLE' OR table_type = 'VIEW') ";
1454 $query .= "ORDER BY table_name ";
1455 $all_tables = db_assoc($query);
1456 }
1457
1458 // This chunk of code is the same as in mysql driver.
1459 if ($views_mode) {
1460 $views = array();
1461 foreach ($all_tables as $view => $type) {
1462 if ($type != 'VIEW') { continue; }
1463 $views[] = $view;
1464 }
1465 $cache_views = $views;
1466 return $views;
1467 } else {
1468 $tables = array();
1469 foreach ($all_tables as $table => $type) {
1470 if ($type != 'BASE TABLE') { continue; }
1471 $tables[] = $table;
1472 }
1473 $cache_tables = $tables;
1474 return $tables;
1475 }
1476 }
1477}
1478function IsTableAView($table)
1479{
1480 // There is no cache here, so call it only once!
1481
1482 global $db_driver, $db_name;
1483
1484 if ("mysql" == $db_driver) {
1485 // Views and information_schema is supported since 5.0
1486 if (views_supported()) {
1487 $query = "SELECT table_name FROM information_schema.tables WHERE table_schema=%0 AND table_name=%1 AND table_type='VIEW' ";
1488 $row = db_row($query, array($db_name, $table));
1489 return (bool) $row;
1490 }
1491 return false;
1492 }
1493 else if ("pgsql" == $db_driver) {
1494 $query = "SELECT table_name, table_type ";
1495 $query .= "FROM information_schema.tables ";
1496 $query .= "WHERE table_schema = 'public' ";
1497 $query .= "AND table_type = 'VIEW' AND table_name = %0 ";
1498 $row = db_row($query, $table);
1499 return (bool) $row;
1500 }
1501}
1502function quote_table($table)
1503{
1504 global $db_driver;
1505 if ('mysql' == $db_driver) {
1506 return "`$table`";
1507 } else {
1508 return "\"$table\"";
1509 }
1510}
1511function table_structure($table)
1512{
1513 global $db_driver;
1514 if ('mysql' == $db_driver)
1515 {
1516 $query = "SHOW CREATE TABLE `$table`";
1517 $row = db_row_num($query);
1518 echo $row[1].';';
1519 echo "\n\n";
1520 }
1521 if ('pgsql' == $db_driver)
1522 {
1523 return '';
1524 }
1525}
1526function table_data($table)
1527{
1528 global $db_driver;
1529 set_time_limit(0);
1530 if ('mysql' == $db_driver) {
1531 $query = "SELECT * FROM `$table`";
1532 } else {
1533 $query = "SELECT * FROM $table";
1534 }
1535 $result = db_query($query);
1536 $count = 0;
1537 while ($row = db_row($result))
1538 {
1539 if ('mysql' == $db_driver) {
1540 echo 'INSERT INTO `'.$table.'` VALUES (';
1541 }
1542 if ('pgsql' == $db_driver) {
1543 echo 'INSERT INTO '.$table.' VALUES (';
1544 }
1545 $x = 0;
1546 foreach($row as $key => $value)
1547 {
1548 if ($x == 1) { echo ', '; }
1549 else { $x = 1; }
1550 if (is_numeric($value)) { echo "'".$value."'"; }
1551 elseif (is_null($value)) { echo 'NULL'; }
1552 else { echo '\''. escape($value) .'\''; }
1553 }
1554 echo ");\n";
1555 $count++;
1556 if ($count % 100 == 0) { flush(); }
1557 }
1558 db_free($result);
1559 if ($count) {
1560 echo "\n";
1561 }
1562}
1563function table_status()
1564{
1565 // Size is not supported for Views, only for Tables.
1566
1567 global $db_driver, $db_link, $db_name;
1568 if ('mysql' == $db_driver)
1569 {
1570 $status = array();
1571 $status['total_size'] = 0;
1572 $result = mysql_query("SHOW TABLE STATUS FROM `$db_name`", $db_link);
1573 while ($row = mysql_fetch_assoc($result)) {
1574 if (!is_numeric($row['Data_length'])) {
1575 // Data_length for Views is NULL.
1576 continue;
1577 }
1578 $status['total_size'] += $row['Data_length']; // + Index_length
1579 $status[$row['Name']]['size'] = $row['Data_length'];
1580 $status[$row['Name']]['count'] = $row['Rows'];
1581 }
1582 return $status;
1583 }
1584 if ('pgsql' == $db_driver)
1585 {
1586 $status = array();
1587 $status['total_size'] = 0;
1588 $tables = list_tables(); // only tables, not views
1589 if (!count($tables)) {
1590 return $status;
1591 }
1592 $tables_in = db_in_array($tables);
1593 $rels = db_list("SELECT relname, reltuples, (relpages::decimal + 1) * 8 * 2 * 1024 AS relsize FROM pg_class WHERE relname IN ($tables_in)");
1594 foreach ($rels as $rel) {
1595 $status['total_size'] += $rel['relsize'];
1596 $status[$rel['relname']]['size'] = $rel['relsize'];
1597 $status[$rel['relname']]['count'] = $rel['reltuples'];
1598 }
1599 return $status;
1600 }
1601}
1602function table_columns($table)
1603{
1604 global $db_driver;
1605 static $cache = array();
1606 if (isset($cache[$table])) {
1607 return $cache[$table];
1608 }
1609 if ('mysql' == $db_driver) {
1610 $row = db_row("SELECT * FROM `$table`");
1611 } else {
1612 $row = db_row("SELECT * FROM $table");
1613 }
1614 if (!$row) {
1615 $cache[$table] = array();
1616 return array();
1617 }
1618 foreach ($row as $k => $v) {
1619 $row[$k] = $k;
1620 }
1621 $cache[$table] = $row;
1622 return $row;
1623}
1624function table_types($table)
1625{
1626 global $db_driver;
1627 if ('mysql' == $db_driver)
1628 {
1629 $rows = db_list("SHOW COLUMNS FROM `$table`");
1630 $types = array();
1631 foreach ($rows as $row) {
1632 $type = $row['Type'];
1633 $types[$row['Field']] = $type;
1634 }
1635 return $types;
1636 }
1637 if ('pgsql' == $db_driver)
1638 {
1639 return db_assoc("SELECT column_name, udt_name FROM information_schema.columns WHERE table_name ='$table' ORDER BY ordinal_position");
1640 }
1641}
1642function table_types2($table)
1643{
1644 global $db_driver;
1645 if ('mysql' == $db_driver)
1646 {
1647 $types = array();
1648 $rows = @db_list("SHOW COLUMNS FROM `$table`");
1649 if (!($rows && count($rows))) {
1650 return false;
1651 }
1652 foreach ($rows as $row) {
1653 $type = $row['Type'];
1654 preg_match('#^[a-z]+#', $type, $match);
1655 $type = $match[0];
1656 $types[$row['Field']] = $type;
1657 }
1658 }
1659 if ('pgsql' == $db_driver)
1660 {
1661 $types = db_assoc("SELECT column_name, udt_name FROM information_schema.columns WHERE table_name ='$table' ORDER BY ordinal_position");
1662 if (!count($types)) {
1663 return false;
1664 }
1665 foreach ($types as $col => $type) {
1666 // "_" also in regexp - error when retrieving column info from "pg_class",
1667 // udt_name might be "_aclitem" / "_text".
1668 preg_match('#^[a-z_]+#', $type, $match);
1669 $type = $match[0];
1670 $types[$col] = $type;
1671 }
1672 }
1673 foreach ($types as $col => $type) {
1674 if ('varchar' == $type) { $type = 'char'; }
1675 if ('integer' == $type) { $type = 'int'; }
1676 if ('timestamp' == $type) { $type = 'time'; }
1677 $types[$col] = $type;
1678 }
1679 return $types;
1680}
1681function table_types_group($types)
1682{
1683 foreach ($types as $k => $type) {
1684 preg_match('#^\w+#', $type, $match);
1685 $type = $match[0];
1686 $types[$k] = $type;
1687 }
1688 $types = array_unique($types);
1689 $types = array_values($types);
1690 $types2 = array();
1691 foreach ($types as $type) {
1692 $types2[$type] = $type;
1693 }
1694 return $types2;
1695}
1696function table_pk($table)
1697{
1698 $cols = table_columns($table);
1699 if (!$cols) return null;
1700 foreach ($cols as $col) {
1701 return $col;
1702 }
1703}
1704function escape($text)
1705{
1706 $text = addslashes($text);
1707 $search = array("\r", "\n", "\t");
1708 $replace = array('\r', '\n', '\t');
1709 return str_replace($search, $replace, $text);
1710}
1711function ob_cleanup()
1712{
1713 while (ob_get_level()) {
1714 ob_end_clean();
1715 }
1716 if (headers_sent()) {
1717 return;
1718 }
1719 if (function_exists('headers_list')) {
1720 foreach (headers_list() as $header) {
1721 if (preg_match('/Content-Encoding:/i', $header)) {
1722 header('Content-encoding: none');
1723 break;
1724 }
1725 }
1726 } else {
1727 header('Content-encoding: none');
1728 }
1729}
1730function query_color($query)
1731{
1732 $color = 'red';
1733 $words = array('SELECT', 'UPDATE', 'DELETE', 'FROM', 'LIMIT', 'OFFSET', 'AND', 'LEFT JOIN', 'WHERE', 'SET',
1734 'ORDER BY', 'GROUP BY', 'GROUP', 'DISTINCT', 'COUNT', 'COUNT\(\*\)', 'IS', 'NULL', 'IS NULL', 'AS', 'ON', 'INSERT INTO', 'VALUES', 'BEGIN', 'COMMIT', 'CASE', 'WHEN', 'THEN', 'END', 'ELSE', 'IN', 'NOT', 'LIKE', 'ILIKE', 'ASC', 'DESC', 'LOWER', 'UPPER');
1735 $words = implode('|', $words);
1736
1737 $query = preg_replace("#^({$words})(\s)#i", '<font color="'.$color.'">$1</font>$2', $query);
1738 $query = preg_replace("#(\s)({$words})$#i", '$1<font color="'.$color.'">$2</font>', $query);
1739 // replace twice, some words when preceding other are not replaced
1740 $query = preg_replace("#([\s\(\),])({$words})([\s\(\),])#i", '$1<font color="'.$color.'">$2</font>$3', $query);
1741 $query = preg_replace("#([\s\(\),])({$words})([\s\(\),])#i", '$1<font color="'.$color.'">$2</font>$3', $query);
1742 $query = preg_replace("#^($words)$#i", '<font color="'.$color.'">$1</font>', $query);
1743
1744 preg_match_all('#<font[^>]+>('.$words.')</font>#i', $query, $matches);
1745 foreach ($matches[0] as $k => $font) {
1746 $font2 = str_replace($matches[1][$k], strtoupper($matches[1][$k]), $font);
1747 $query = str_replace($font, $font2, $query);
1748 }
1749
1750 return $query;
1751}
1752function query_upper($sql)
1753{
1754 return $sql;
1755 // todo: don't upper quoted ' and ' values
1756 $queries = preg_split("#;(\s*--[ \t\S]*)?(\r\n|\n|\r)#U", $sql);
1757 foreach ($queries as $k => $query) {
1758 $strip = query_strip($query);
1759 $color = query_color($strip);
1760 $sql = str_replace($strip, $color, $sql);
1761 }
1762 $sql = preg_replace('#<font color="\w+">([^>]+)</font>#iU', '$1', $sql);
1763 return $sql;
1764}
1765function html_spaces($string)
1766{
1767 $inside_tag = false;
1768 for ($i = 0; $i < strlen($string); $i++)
1769 {
1770 $c = $string{$i};
1771 if ('<' == $c) {
1772 $inside_tag = true;
1773 }
1774 if ('>' == $c) {
1775 $inside_tag = false;
1776 }
1777 if (' ' == $c && !$inside_tag) {
1778 $string = substr($string, 0, $i).' '.substr($string, $i+1);
1779 $i += strlen(' ')-1;
1780 }
1781 }
1782 return $string;
1783}
1784function query_cut($query)
1785{
1786 // removes sub-queries and string values from query
1787 $brace_start = '(';
1788 $brace_end = ')';
1789 $quote = "'";
1790 $inside_brace = false;
1791 $inside_quote = false;
1792 $depth = 0;
1793 $ret = '';
1794 $query = str_replace('\\\\', '', $query);
1795
1796 for ($i = 0; $i < strlen($query); $i++)
1797 {
1798 $prev_char = isset($query{$i-1}) ? $query{$i-1} : null;
1799 $char = $query{$i};
1800 if ($char == $brace_start) {
1801 if (!$inside_quote) {
1802 $depth++;
1803 }
1804 }
1805 if ($char == $brace_end) {
1806 if (!$inside_quote) {
1807 $depth--;
1808 if ($depth == 0) {
1809 $ret .= '(...)';
1810 }
1811 continue;
1812 }
1813 }
1814 if ($char == $quote) {
1815 if ($inside_quote) {
1816 if ($prev_char != '\\') {
1817 $inside_quote = false;
1818 if (!$depth) {
1819 $ret .= "'...'";
1820 }
1821 continue;
1822 }
1823 } else {
1824 $inside_quote = true;
1825 }
1826 }
1827 if (!$depth && !$inside_quote) {
1828 $ret .= $char;
1829 }
1830 }
1831 return $ret;
1832}
1833function table_from_query($query)
1834{
1835 if (preg_match('#\sFROM\s+["`]?(\w+)["`]?#i', $query, $match)) {
1836 $cut = query_cut($query);
1837 if (preg_match('#\sFROM\s+["`]?(\w+)["`]?#i', $cut, $match2)) {
1838 $table = $match2[1];
1839 } else {
1840 $table = $match[1];
1841 }
1842 } else if (preg_match('#UPDATE\s+"?(\w+)"?#i', $query, $match)) {
1843 $table = $match[1];
1844 } else if (preg_match('#INSERT\s+INTO\s+"?(\w+)"?#', $query, $match)) {
1845 $table = $match[1];
1846 } else {
1847 $table = false;
1848 }
1849 return $table;
1850}
1851function is_select($query)
1852{
1853 return preg_match('#^\s*SELECT\s+#i', $query);
1854}
1855function query_strip($query)
1856{
1857 // strip comments and ';' from the end of query
1858 $query = trim($query);
1859 if (str_ends_with($query, ';')) {
1860 $query = str_cut_end($query, ';');
1861 }
1862 $lines = preg_split("#(\r\n|\n|\r)#", $query);
1863 foreach ($lines as $k => $line) {
1864 $line = trim($line);
1865 if (!$line || str_starts_with($line, '--')) {
1866 unset($lines[$k]);
1867 }
1868 }
1869 $query = implode("\r\n", $lines);
1870 return $query;
1871}
1872function dump_table($table)
1873{
1874 ob_cleanup();
1875 define('DEBUG_CONSOLE_HIDE', 1);
1876 set_time_limit(0);
1877 global $db_name;
1878 header("Cache-control: private");
1879 header("Content-type: application/octet-stream");
1880 header('Content-Disposition: attachment; filename='.$db_name.'_'.$table.'.sql');
1881 table_structure($table);
1882 table_data($table);
1883 exit;
1884}
1885function dump_all($data = false)
1886{
1887 global $db_name;
1888
1889 ob_cleanup();
1890 define('DEBUG_CONSOLE_HIDE', 1);
1891 set_time_limit(0);
1892
1893 $tables = list_tables();
1894 $table_filter = get('table_filter');
1895 $tables = table_filter($tables, $table_filter);
1896
1897 header("Cache-control: private");
1898 header("Content-type: application/octet-stream");
1899 header('Content-Disposition: attachment; filename='.date('Ymd').'_'.$db_name.'.sql');
1900
1901 foreach ($tables as $key => $table)
1902 {
1903 table_structure($table);
1904 if ($data) {
1905 table_data($table);
1906 }
1907 flush();
1908 }
1909 exit;
1910}
1911function export_csv($query, $separator)
1912{
1913 ob_cleanup();
1914 set_time_limit(0);
1915
1916 if (!is_select($query)) {
1917 trigger_error('export_csv() failed: not a SELECT query: '.$query, E_USER_ERROR);
1918 }
1919
1920 $table = table_from_query($query);
1921 if (!$table) {
1922 $table = 'unknown';
1923 }
1924
1925 header("Cache-control: private");
1926 header("Content-type: application/octet-stream");
1927 header('Content-Disposition: attachment; filename='.$table.'_'.date('Ymd').'.csv');
1928
1929 $rs = db_query($query);
1930 $first = true;
1931
1932 while ($row = db_row($rs)) {
1933 if ($first) {
1934 echo csv_row(array_keys($row), $separator);
1935 $first = false;
1936 }
1937 echo csv_row($row, $separator);
1938 flush();
1939 }
1940
1941 exit();
1942}
1943function csv_row($row, $separator)
1944{
1945 foreach ($row as $key => $val) {
1946 $enquote = false;
1947 if (false !== strpos($val, $separator)) {
1948 $enquote = true;
1949 }
1950 if (false !== strpos($val, "\"")) {
1951 $enquote = true;
1952 $val = str_replace("\"", "\"\"", $val);
1953 }
1954 if (false !== strpos($val, "\r") || false !== strpos($val, "\n")) {
1955 $enquote = true;
1956 $val = preg_replace('#(\r\n|\r|\n)#', "\n", $val); // excel needs \n instead of \r\n
1957 }
1958 if ($enquote) {
1959 $row[$key] = "\"".$val."\"";
1960 }
1961 }
1962 $out = implode($separator, $row);
1963 $out .= "\r\n";
1964 return $out;
1965}
1966function import($file, $ignore_errors = false, $transaction = false, $force_myisam = false, $query_start = false)
1967{
1968 global $db_driver, $db_link, $db_charset;
1969 if ($ignore_errors && $transaction) {
1970 echo '<div>You cannot select both: ignoring errors and transaction</div>';
1971 exit;
1972 }
1973
1974 $count_errors = 0;
1975 set_time_limit(0);
1976 $fp = fopen($file, 'r');
1977 if (!$fp) { exit('fopen('.$file.') failed'); }
1978 flock($fp, 1);
1979 $text = trim(fread($fp, filesize($file)));
1980 flock($fp, 3);
1981 fclose($fp);
1982 if ($db_charset == 'latin2') {
1983 $text = charset_fix($text);
1984 }
1985 if ($force_myisam) {
1986 $text = preg_replace('#TYPE\s*=\s*InnoDB#i', 'TYPE=MyISAM', $text);
1987 }
1988 $text = preg_split("#;(\r\n|\n|\r)#", $text);
1989 $x = 0;
1990 echo '<div>Ignoring errors: <b>'.($ignore_errors?'Yes':'No').'</b></div>';
1991 echo '<div>Transaction: <b>'.($transaction?'Yes':'No').'</b></div>';
1992 echo '<div>Force MyIsam: <b>'.($force_myisam?'Yes':'No').'</b></div>';
1993 echo '<div>Query start: <b>#'.$query_start.'</b></div>';
1994 echo '<div>Queries found: <b>'.count($text).'</b></div>';
1995 echo '<div>Executing ...</div>';
1996 flush();
1997
1998 if ($transaction) {
1999 echo '<div>BEGIN;</div>';
2000 db_begin();
2001 }
2002
2003 $time = time_start();
2004 $query_start = (int) $query_start;
2005 if (!$query_start) {
2006 $query_start = 1;
2007 }
2008 $query_no = 0;
2009
2010 foreach($text as $key => $value)
2011 {
2012 $x++;
2013 $query_no++;
2014 if ($query_start > $query_no) {
2015 continue;
2016 }
2017
2018 if ('mysql' == $db_driver)
2019 {
2020 $result = @mysql_query($value.';', $db_link);
2021 }
2022 if ('pgsql' == $db_driver)
2023 {
2024 $result = @pg_query($db_link, $value.';');
2025 }
2026 if(!$result) {
2027 $x--;
2028 if (!$count_errors) {
2029 echo '<table class="ls" cellspacing="1"><tr><th width="25%">Error</th><th>Query</th></tr>';
2030 }
2031 $count_errors++;
2032 echo '<tr><td>#'.$query_no.' '.db_error() .')'.'</td><td>'.nl2br(html_once($value)).'</td></tr>';
2033 flush();
2034 if (!$ignore_errors) {
2035 echo '</table>';
2036 echo '<div><span style="color: red;"><b>Import failed.</b></span></div>';
2037 echo '<div>Queries executed: <b>'.($x-$query_start+1).'</b>.</div>';
2038 if ($transaction) {
2039 echo '<div>ROLLBACK;</div>';
2040 db_rollback();
2041 }
2042 echo '<br><div><a href="'.$_SERVER['PHP_SELF'].'?import=1"><< go back</a></div>';
2043 exit;
2044 }
2045 }
2046 }
2047 if ($count_errors) {
2048 echo '</table>';
2049 }
2050 if ($transaction) {
2051 echo '<div>COMMIT;</div>';
2052 db_end();
2053 }
2054 echo '<div><span style="color: green;"><b>Import finished.</b></span></div>';
2055 echo '<div>Queries executed: <b>'.($x-$query_start+1).'</b>.</div>';
2056 echo '<div>Time: <b>'.time_end($time).'</b> sec</div>';
2057 echo '<br><div><a href="'.$_SERVER['PHP_SELF'].'?import=1"><< go back</a></div>';
2058}
2059function layout()
2060{
2061 global $sql_area;
2062 ?>
2063 <style>
2064 body,table,input,select,textarea { font-family: tahoma; font-size: 11px; }
2065 body { margin: 1em; padding: 0; margin-top: 0.5em; }
2066 h1, h2 { font-family: arial; margin: 1em 0; }
2067 h1 { font-size: 150%; margin: 0.7em 0; }
2068 h2 { font-size: 125%; }
2069 .ls th { background: #ccc; }
2070 .ls th th { background-color: none; }
2071 .ls td { background: #f5f5f5; }
2072 .ls td td { background-color: none; }
2073 .ls th, .ls td { padding: 0.1em 0.5em; }
2074 .ls th th, .ls td td { padding: 0; }
2075 .ls2 th { text-align: left; vertical-align: top; line-height: 1.7em; background: #e0e0e0; font-weight: normal; }
2076 .ls2 th th { line-height: normal; background-color: none; }
2077 p { margin: 0.8em 0; }
2078 form { margin: 0; }
2079 form th { text-align: left; }
2080 a, a:visited { text-decoration: none; }
2081 a:hover { text-decoration: underline; }
2082 a, a.blue { color: blue; }
2083 a:visited { color: purple; }
2084 a.blue:visited { color: blue; }
2085 form .none td, form .none th { background: none; padding: 0 0.25em; }
2086 label { padding-left: 2px; padding-right: 4px; }
2087 .checkbox { padding-left: 0; margin-left: 0; margin-top: 1px; }
2088 .none, .ls .none { background: none; padding-top: 0.4em; }
2089 .button { cursor: pointer; }
2090 .button_click { background: #e0e0e0; }
2091 .error { background: #ffffd7; padding: 0.5em; border: #ccc 1px solid; margin-bottom: 1em; margin-top: 1em; }
2092 .msg { background: #eee; padding: 0.5em; border: #ccc 1px solid; margin-bottom: 1em; margin-top: 1em; }
2093 .sql_area { <?php echo $sql_area;?> }
2094 div.query { background: #eee; padding: 0.35em; border: #ccc 1px solid; margin-bottom: 1em; margin-top: 1em; }
2095 </style>
2096 <script>
2097 function mark_col(td)
2098 {
2099 }
2100 function popup(url, width, height, more)
2101 {
2102 if (!width) width = 750;
2103 if (!height) height = 500;
2104 var x = (screen.width/2-width/2);
2105 var y = (screen.height/2-height/2);
2106 window.open(url, "", "scrollbars=yes,resizable=yes,width="+width+",height="+height+",screenX="+(x)+",screenY="+y+",left="+x+",top="+y+(more ? ","+more : ""));
2107 }
2108 function is_ie()
2109 {
2110 return navigator.appVersion.indexOf("MSIE") != -1;
2111 }
2112 function event_add(el, event, func)
2113 {
2114 if (is_ie()) {
2115 if (el.attachEvent) {
2116 el.attachEvent("on"+event, func);
2117 }
2118 } else {
2119 if (el.addEventListener) {
2120 el.addEventListener(event, func, false);
2121 } else if (el.attachEvent) {
2122 el.attachEvent("on"+event, func);
2123 } else {
2124 var oldfunc = el["on"+event];
2125 el["on"+event] = function() { oldfunc(); func(); }
2126 }
2127 }
2128 }
2129 function event_target(event)
2130 {
2131 var el;
2132 if (window.event) el = window.event.srcElement;
2133 else if (event) el = event.target;
2134 if (el.nodeType == 3) el = el.parentNode;
2135 return el;
2136 }
2137
2138 function button_init()
2139 {
2140 // dependency: event_add(), event_target()
2141 event_add(window, "load", function() {
2142 for (var i = 0; i < document.forms.length; i++) {
2143 event_add(document.forms[i], "submit", function(event) {
2144 var form = event_target(event);
2145 if (form.tagName != 'FORM') form = this;
2146 for (var k = 0; k < form.elements.length; k++) {
2147 if ("button" == form.elements[k].type || "submit" == form.elements[k].type) {
2148 button_click(form.elements[k], true);
2149 }
2150 }
2151 });
2152 var form = document.forms[i];
2153 for (var j = 0; j < form.elements.length; j++) {
2154 if ("button" == form.elements[j].type || "submit" == form.elements[j].type) {
2155 event_add(form.elements[j], "click", button_click);
2156 }
2157 }
2158 }
2159 var inputs = document.getElementsByTagName('INPUT');
2160 for (var i = 0; i < inputs.length; i++) {
2161 if (('button' == inputs[i].type || 'submit' == inputs[i].type) && !inputs[i].form) {
2162 event_add(inputs[i], 'click', button_click);
2163 }
2164 }
2165 });
2166 }
2167 function button_click(but, calledFromOnSubmit)
2168 {
2169 but = but.nodeName ? but : event_target(but);
2170 if ('button' == this.type || 'submit' == this.type) {
2171 but = this;
2172 }
2173 if (but.getAttribute('button_click') == 1 || but.form && but.form.getAttribute("button_click") == 1) {
2174 return;
2175 }
2176 if (button_click_sess_done(but)) {
2177 return;
2178 }
2179 if ("button" == but.type) {
2180 if (but.getAttribute("wait")) {
2181 button_wait(but);
2182 but.setAttribute("button_click", 1);
2183 if (but.form) {
2184 but.form.setAttribute("button_click", 1); // only when WAIT = other buttons in the form Choose From Pop etc.
2185 }
2186 }
2187 } else if ("submit" == but.type) {
2188 if (but.getAttribute("wait")) {
2189 button_wait(but);
2190 but.setAttribute("button_click", 1);
2191 }
2192 if (but.form) {
2193 but.form.setAttribute("button_click", 1);
2194 }
2195 if (calledFromOnSubmit) {
2196 if (but.getAttribute("block")) {
2197 button_disable(but);
2198 }
2199 } else {
2200 if (!but.form.getAttribute('button_disable_onsubmit'))
2201 {
2202 event_add(but.form, "submit", function(event) {
2203 var form = event_target(event);
2204 if (form.tagName != 'FORM') form = this;
2205 if (!button_disable_sess_done(form)) {
2206 for (var i = 0; i < form.elements.length; i++) {
2207 if (form.elements[i].getAttribute("block")) {
2208 button_disable(form.elements[i]);
2209 }
2210 }
2211 }
2212 });
2213 but.form.setAttribute('button_disable_onsubmit', 1);
2214 }
2215 }
2216 } else {
2217 //return alert("button_click() failed, unknown button type");
2218 }
2219 }
2220 function button_click_sess_done(but)
2221 {
2222 if (but.getAttribute('button_click_sess_done') == 1 || but.form && but.form.getAttribute('button_click_sess_done') == 1) {
2223 if (but.getAttribute('button_click_sess_done') == 1) {
2224 but.setAttribute('button_click_sess_done', 0);
2225 }
2226 if (but.form && but.form.getAttribute('button_click_sess_done') == 1) {
2227 but.form.setAttribute('button_click_sess_done', 0);
2228 }
2229 return true;
2230 }
2231 return false;
2232 }
2233 function button_disable_sess_done(but)
2234 {
2235 if (but.getAttribute('button_disable_sess_done') == 1 || but.form && but.form.getAttribute('button_disable_sess_done') == 1) {
2236 if (but.getAttribute('button_disable_sess_done') == 1) {
2237 but.setAttribute('button_disable_sess_done', 0);
2238 }
2239 if (but.form && but.form.getAttribute('button_disable_sess_done') == 1) {
2240 but.form.setAttribute('button_disable_sess_done', 0);
2241 }
2242 return true;
2243 }
2244 return false;
2245 }
2246 function button_disable(button)
2247 {
2248 button.disabled = true;
2249 if (button.name)
2250 {
2251
2252 var form = button.form;
2253 var input = document.createElement('input');
2254 input.setAttribute('type', 'hidden');
2255 input.setAttribute('name', button.name);
2256 input.setAttribute('value', button.value);
2257 form.appendChild(input);
2258 }
2259 }
2260 function button_wait(but)
2261 {
2262 //but.value += " ..";
2263 but.className = but.className + ' button_click';
2264 }
2265 function button_clear(but)
2266 {
2267 if (but.tagName == 'FORM') {
2268 var form = but;
2269 for (var i = 0; i < form.elements.length; i++) {
2270 button_clear(form.elements[i]);
2271 }
2272 form.setAttribute('button_click', 0);
2273 form.setAttribute('button_click_sess_done', 1);
2274 form.setAttribute('button_disable_sess_done', 1);
2275 } else {
2276 if (but.type == 'submit' || but.type == 'button')
2277 {
2278 if (but.getAttribute('button_click') == 1) {
2279 //but.value = but.value.replace(/[ ]?\.{2,}$/, '');
2280 but.className = but.className.replace('button_click', '');
2281 but.setAttribute('button_click', 0);
2282 but.setAttribute('button_click_sess_done', 1);
2283 but.setAttribute('button_disable_sess_done', 1);
2284 }
2285 if (but.form && but.form.getAttribute('button_click') == 1) {
2286 but.form.setAttribute('button_click', 0);
2287 but.form.setAttribute('button_click_sess_done', 1);
2288 but.form.setAttribute('button_disable_sess_done', 1);
2289 }
2290 }
2291 }
2292 }
2293 button_init();
2294 </script>
2295 <?php
2296}
2297function conn_info()
2298{
2299 global $db_driver, $db_server, $db_name, $db_user, $db_charset, $page_charset, $charset1, $charset2;
2300 $dbs = list_dbs();
2301 $db_name = $db_name;
2302 ?>
2303 <p>
2304 Driver: <b><?php echo $db_driver;?></b>
2305 -
2306 Server: <b><?php echo $db_server;?></b>
2307 -
2308 User: <b><?php echo $db_user;?></b>
2309 -
2310 <a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>?execute_sql=1">Execute SQL</a>
2311 ( open in <a class=blue href="javascript:void(0)" onclick="popup('<?php echo $_SERVER['PHP_SELF'];?>?execute_sql=1&popup=1')">Popup</a> )
2312 -
2313 Database: <select name="db_name" onchange="location='<?php echo $_SERVER['PHP_SELF'];?>?db_name='+this.value"><?php echo options($dbs, $db_name);?></select>
2314 -
2315 Db charset: <select name="db_charset" onchange="location='<?php echo $_SERVER['PHP_SELF'];?>?db_charset='+this.value+'&from=<?php echo urlencode($_SERVER['REQUEST_URI']);?>'">
2316 <option value=""></option><?php echo options($charset1, $db_charset);?></select>
2317 -
2318 Page charset: <select name="page_charset" onchange="location='<?php echo $_SERVER['PHP_SELF'];?>?page_charset='+this.value+'&from=<?php echo urlencode($_SERVER['REQUEST_URI']);?>'">
2319 <option value=""></option><?php echo options($charset2, $page_charset);?></select>
2320 -
2321 <a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>?disconnect=1">Disconnect</a>
2322 </p>
2323 <?php
2324}
2325function size($bytes)
2326{
2327 return number_format(ceil($bytes / 1024),0,'',',').' KB';
2328}
2329function html($s)
2330{
2331 $html = array(
2332 '&' => '&',
2333 '<' => '<',
2334 '>' => '>',
2335 '"' => '"',
2336 '\'' => '''
2337 );
2338 $s = preg_replace('/&#(\d+)/', '@@@@@#$1', $s);
2339 $s = str_replace(array_keys($html), array_values($html), $s);
2340 $s = preg_replace('/@@@@@#(\d+)/', '&#$1', $s);
2341 return trim($s);
2342}
2343function html_undo($s)
2344{
2345 $html = array(
2346 '&' => '&',
2347 '<' => '<',
2348 '>' => '>',
2349 '"' => '"',
2350 '\'' => '''
2351 );
2352 return str_replace(array_values($html), array_keys($html), $s);
2353}
2354function html_once($s)
2355{
2356 $s = str_replace(array('<','>','&lt;','&gt;'),array('<','>','<','>'),$s);
2357 return str_replace(array('<','>','<','>'),array('&lt;','&gt;','<','>'),$s);
2358}
2359function html_tags($s)
2360{
2361 // succession of str_replace array is important! double escape bug..
2362 return str_replace(array('<','>','<','>'), array('&lt;','&gt;','<','>'), $s);
2363}
2364function html_tags_undo($s)
2365{
2366 return str_replace(array('<','>','&lt;', '&gt;'), array('<','>','<','>'), $s);
2367}
2368function html_allow_tags($s, $allow)
2369{
2370 $s = html_once(trim($s));
2371 preg_match_all('#<([a-z]+)>#i', $allow, $match);
2372 foreach ($match[1] as $tag) {
2373 $s = preg_replace('#<'.$tag.'\s+style\s*=\s*"([^"<>]+)"\s*>#i', '<'.$tag.' style="$1">', $s);
2374 $s = str_replace('<'.$tag.'>', '<'.$tag.'>', $s);
2375 $s = str_replace('</'.$tag.'>', '</'.$tag.'>', $s);
2376 }
2377 return $s;
2378}
2379function str_truncate($string, $length, $etc = ' ..', $break_words = true)
2380{
2381 if ($length == 0) {
2382 return '';
2383 }
2384 if (strlen($string) > $length + strlen($etc)) {
2385 if (!$break_words) {
2386 $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
2387 }
2388 return substr($string, 0, $length) . $etc;
2389 }
2390 return $string;
2391}
2392function str_bind($s, $dat = array(), $strict = false, $recur = 0)
2393{
2394 if (!is_array($dat)) {
2395 return trigger_error('str_bind() failed. Second argument expects to be an array.', E_USER_ERROR);
2396 }
2397 if ($strict) {
2398 foreach ($dat as $k => $v) {
2399 if (strpos($s, "%$k%") === false) {
2400 return trigger_error(sprintf('str_bind() failed. Strict mode On. Key not found = %s. String = %s. Data = %s.', $k, $s, print_r($dat, 1)), E_USER_ERROR);
2401 }
2402 $s = str_replace("%$k%", $v, $s);
2403 }
2404 if (preg_match('#%\w+%#', $s, $match)) {
2405 return trigger_error(sprintf('str_bind() failed. Unassigned data for = %s. String = %s.', $match[0], $sBase), E_USER_ERROR);
2406 }
2407 return $s;
2408 }
2409
2410 $sBase = $s;
2411 preg_match_all('#%\w+%#', $s, $match);
2412 $keys = $match[0];
2413 $num = array();
2414
2415 foreach ($keys as $key)
2416 {
2417 $key2 = str_replace('%', '', $key);
2418 if (is_numeric($key2)) $num[$key] = true;
2419 /* ignore!
2420 if (!array_key_exists($key2, $dat)) {
2421 return trigger_error(sprintf('str_bind() failed. No data found for key: %s. String: %s.', $key, $sBase), E_USER_ERROR);
2422 }
2423 */
2424 $val = $dat[$key2];
2425 /* insecure!
2426 if (preg_match('#%\w+%#', $val) && $recur < 5) {
2427 $val = str_bind($val, $dat, $strict, ++$recur);
2428 }
2429 */
2430 $s = str_replace($key, $val, $s);
2431 }
2432 if (count($num)) {
2433 if (count($dat) != count($num)) {
2434 return trigger_error('str_bind() failed. When using numeric data binding you need to use all data passed to the string. You also cannot mix numeric and name binding.', E_USER_ERROR);
2435 }
2436 }
2437
2438 if (preg_match('#%\w+%#', $s, $match)) {
2439 /* ignore! return trigger_error(sprintf('str_bind() failed. Unassigned data for = %s. String = %s. Data = %s.', $match[0], htmlspecialchars(print_r($sBase, true)), print_r($dat, true)), E_USER_ERROR);*/
2440 }
2441
2442 return $s;
2443}
2444function dir_read($dir, $ignore_ext = array(), $allow_ext = array(), $sort = null)
2445{
2446 if (is_null($ignore_ext)) $ignore_ext = array();
2447 if (is_null($allow_ext)) $allow_ext = array();
2448 foreach ($allow_ext as $k => $ext) {
2449 $allow_ext[$k] = str_replace('.', '', $ext);
2450 }
2451
2452 $ret = array();
2453 if ($handle = opendir($dir)) {
2454 while (($file = readdir($handle)) !== false) {
2455 if ($file != '.' && $file != '..') {
2456 $ignore = false;
2457 foreach ($ignore_ext as $ext) {
2458 if (file_ext_has($file, $ext)) {
2459 $ignore = true;
2460 }
2461 }
2462 if (is_array($allow_ext) && count($allow_ext) && !in_array(file_ext($file), $allow_ext)) {
2463 $ignore = true;
2464 }
2465 if (!$ignore) {
2466 $ret[] = array(
2467 'file' => $dir.'/'.$file,
2468 'time' => filemtime($dir.'/'.$file)
2469 );
2470 }
2471 }
2472 }
2473 closedir($handle);
2474 }
2475 if ('date_desc' == $sort) {
2476 $ret = array_sort_desc($ret, 'time');
2477 }
2478 return array_col($ret, 'file');
2479}
2480function array_col($arr, $col)
2481{
2482 $ret = array();
2483 foreach ($arr as $k => $row) {
2484 $ret[] = $row[$col];
2485 }
2486 return $ret;
2487}
2488function array_sort($arr, $col_key)
2489{
2490 if (is_array($col_key)) {
2491 foreach ($arr as $k => $v) {
2492 $arr[$k]['__array_sort'] = '';
2493 foreach ($col_key as $col) {
2494 $arr[$k]['__array_sort'] .= $arr[$k][$col].'_';
2495 }
2496 }
2497 $col_key = '__array_sort';
2498 }
2499 uasort($arr, create_function('$a,$b', 'if (is_null($a["'.$col_key.'"]) && !is_null($b["'.$col_key.'"])) return 1; if (!is_null($a["'.$col_key.'"]) && is_null($b["'.$col_key.'"])) return -1; return strnatcasecmp($a["'.$col_key.'"], $b["'.$col_key.'"]);'));
2500 if ('__array_sort' == $col_key) {
2501 foreach ($arr as $k => $v) {
2502 unset($arr[$k]['__array_sort']);
2503 }
2504 }
2505 return $arr;
2506}
2507function array_sort_desc($arr, $col_key)
2508{
2509 if (is_array($col_key)) {
2510 foreach ($arr as $k => $v) {
2511 $arr[$k]['__array_sort'] = '';
2512 foreach ($col_key as $col) {
2513 $arr[$k]['__array_sort'] .= $arr[$k][$col].'_';
2514 }
2515 }
2516 $col_key = '__array_sort';
2517 }
2518 uasort($arr, create_function('$a,$b', 'return strnatcasecmp($b["'.$col_key.'"], $a["'.$col_key.'"]);'));
2519 if ('__array_sort' == $col_key) {
2520 foreach ($arr as $k => $v) {
2521 unset($arr[$k]['__array_sort']);
2522 }
2523 }
2524 return $arr;
2525}
2526function options($options, $selected = null, $ignore_type = false)
2527{
2528 $ret = '';
2529 foreach ($options as $k => $v) {
2530 //str_replace('"', '\"', $k)
2531 $ret .= '<option value="'.$k.'"';
2532 if ((is_array($selected) && in_array($k, $selected)) || (!is_array($selected) && $k == $selected && $selected !== '' && $selected !== null)) {
2533 if ($ignore_type) {
2534 $ret .= ' selected="selected"';
2535 } else {
2536 if (!(is_numeric($k) xor is_numeric($selected))) {
2537 $ret .= ' selected="selected"';
2538 }
2539 }
2540 }
2541 $ret .= '>'.$v.' </option>';
2542 }
2543 return $ret;
2544}
2545function sql_files()
2546{
2547 $files = dir_read('.', null, array('.sql'));
2548 $files2 = array();
2549 foreach ($files as $file) {
2550 $files2[md5($file)] = $file.sprintf(' (%s)', size(filesize($file)));
2551 }
2552 return $files2;
2553}
2554function sql_files_assoc()
2555{
2556 $files = dir_read('.', null, array('.sql'));
2557 $files2 = array();
2558 foreach ($files as $file) {
2559 $files2[md5($file)] = $file;
2560 }
2561 return $files2;
2562}
2563function file_ext($name)
2564{
2565 $ext = null;
2566 if (($pos = strrpos($name, '.')) !== false) {
2567 $len = strlen($name) - ($pos+1);
2568 $ext = substr($name, -$len);
2569 if (!preg_match('#^[a-z0-9]+$#i', $ext)) {
2570 return null;
2571 }
2572 }
2573 return $ext;
2574}
2575function checked($bool)
2576{
2577 if ($bool) return 'checked="checked"';
2578}
2579function radio_assoc($checked, $assoc, $input_name, $link = false)
2580{
2581 $ret = '<table cellspacing="0" cellpadding="0"><tr>';
2582 foreach ($assoc as $id => $name)
2583 {
2584 $params = array(
2585 'id' => $id,
2586 'name' => $name,
2587 'checked' => checked($checked == $id),
2588 'input_name' => $input_name
2589 );
2590 if ($link) {
2591 if (is_array($link)) {
2592 $params['link'] = $link[$id];
2593 } else {
2594 $params['link'] = sprintf($link, $id, $name);
2595 }
2596 $ret .= str_bind('<td><input class="checkbox" type="radio" name="%input_name%" id="%input_name%_%id%" value="%id%" %checked%></td><td>%link% </td>', $params);
2597 } else {
2598 $ret .= str_bind('<td><input class="checkbox" type="radio" name="%input_name%" id="%input_name%_%id%" value="%id%" %checked%></td><td><label for="%input_name%_%id%">%name%</label> </td>', $params);
2599 }
2600 }
2601 $ret .= '</tr></table>';
2602 return $ret;
2603}
2604function self($cut_query = false)
2605{
2606 $uri = $_SERVER['REQUEST_URI'];
2607 if ($cut_query) {
2608 $before = str_before($uri, '?');
2609 if ($before) {
2610 return $before;
2611 }
2612 }
2613 return $uri;
2614}
2615function url($script, $params = array())
2616{
2617 $query = '';
2618
2619 /* remove from script url, actual params if exist */
2620 foreach ($params as $k => $v) {
2621 $exp = sprintf('#(\?|&)%s=[^&]*#i', $k);
2622 if (preg_match($exp, $script)) {
2623 $script = preg_replace($exp, '', $script);
2624 }
2625 }
2626
2627 /* repair url like 'script.php&id=12&asd=133' */
2628 $exp = '#\?\w+=[^&]*#i';
2629 $exp2 = '#&(\w+=[^&]*)#i';
2630 if (!preg_match($exp, $script) && preg_match($exp2, $script)) {
2631 $script = preg_replace($exp2, '?$1', $script, 1);
2632 }
2633
2634 foreach ($params as $k => $v) {
2635 if (!strlen($v)) continue;
2636 if ($query) { $query .= '&'; }
2637 else {
2638 if (strpos($script, '?') === false) {
2639 $query .= '?';
2640 } else {
2641 $query .= '&';
2642 }
2643 }
2644 if ('%s' != $v) {
2645 $v = urlencode($v);
2646 }
2647 $v = preg_replace('#%25(\w+)%25#i', '%$1%', $v); // %id_news% etc. used in listing
2648 $query .= sprintf('%s=%s', $k, $v);
2649 }
2650 return $script.$query;
2651}
2652function url_offset($offset, $params = array())
2653{
2654 $url = $_SERVER['REQUEST_URI'];
2655 if (preg_match('#&offset=\d+#', $url)) {
2656 $url = preg_replace('#&offset=\d+#', '&offset='.$offset, $url);
2657 } else {
2658 $url .= '&offset='.$offset;
2659 }
2660 return $url;
2661}
2662function str_wrap($s, $width, $break = ' ', $omit_tags = false)
2663{
2664 //$restart = array(' ', "\t", "\r", "\n");
2665 $restart = array();
2666 $cnt = 0;
2667 $ret = '';
2668 $open_tag = false;
2669 $inside_link = false;
2670 for ($i=0; $i<strlen($s); $i++)
2671 {
2672 $char = $s[$i];
2673 $nextchar = isset($s[$i+1]) ? $s[$i+1] : null;
2674 $nextchar2 = isset($s[$i+2]) ? $s[$i+2] : null;
2675
2676 if ($omit_tags)
2677 {
2678 if ($char == '<') {
2679 $open_tag = true;
2680 if ('a' == $nextchar) {
2681 $inside_link = true;
2682 } else if ('/' == $nextchar && 'a' == $nextchar2) {
2683 $inside_link = false;
2684 }
2685 }
2686 if ($char == '>') {
2687 $open_tag = false;
2688 }
2689 if ($open_tag) {
2690 $ret .= $char;
2691 continue;
2692 }
2693 }
2694
2695 if (in_array($char, $restart)) {
2696 $cnt = 0;
2697 } else {
2698 $cnt++;
2699 }
2700 $ret .= $char;
2701 if ($cnt > $width) {
2702 if (!$inside_link) {
2703 // Inside link, do not break it.
2704 $ret .= $break;
2705 $cnt = 0;
2706 }
2707 }
2708 }
2709 return $ret;
2710}
2711function time_micro()
2712{
2713 list($usec, $sec) = explode(" ", microtime());
2714 return ((float)$usec + (float)$sec);
2715}
2716function time_start()
2717{
2718 return time_micro();
2719}
2720function time_end($start)
2721{
2722 $end = time_micro();
2723 $end = round($end - $start, 3);
2724 $end = pad_zeros($end, 3);
2725 return $end;
2726}
2727function str_has($str, $needle, $ignore_case = false)
2728{
2729 if (is_array($needle)) {
2730 foreach ($needle as $n) {
2731 if (!str_has($str, $n, $ignore_case)) {
2732 return false;
2733 }
2734 }
2735 return true;
2736 }
2737 if ($ignore_case) {
2738 $str = str_lower($str);
2739 $needle = str_lower($needle);
2740 }
2741 return strpos($str, $needle) !== false;
2742}
2743function str_has_any($str, $arr_needle, $ignore_case = false)
2744{
2745 if (is_string($arr_needle)) {
2746 $arr_needle = preg_replace('#\s+#', ' ', $arr_needle);
2747 $arr_needle = explode(' ', $arr_needle);
2748 }
2749 foreach ($arr_needle as $needle) {
2750 if (str_has($str, $needle, $ignore_case)) {
2751 return true;
2752 }
2753 }
2754 return false;
2755}
2756function str_before($str, $needle)
2757{
2758 $pos = strpos($str, $needle);
2759 if ($pos !== false) {
2760 $before = substr($str, 0, $pos);
2761 return strlen($before) ? $before : false;
2762 } else {
2763 return false;
2764 }
2765}
2766function pad_zeros($number, $zeros)
2767{
2768 if (str_has($number, '.')) {
2769 preg_match('#\.(\d+)$#', $number, $match);
2770 $number .= str_repeat('0', $zeros-strlen($match[1]));
2771 return $number;
2772 } else {
2773 return $number.'.'.str_repeat('0', $zeros);
2774 }
2775}
2776function charset_fix_invalid($s)
2777{
2778 $fix = 'Ä‚ìÑ¢ûùòôî√';
2779 $s = str_replace(str_array($fix), '', $s);
2780 return $s;
2781}
2782function charset_is_invalid($s)
2783{
2784 $fix = 'Ä‚ìÑ¢ûùòôî√';
2785 $fix = str_array($fix);
2786 foreach ($fix as $char) {
2787 if (str_has($s, $char)) {
2788 return true;
2789 }
2790 }
2791 return false;
2792}
2793function charset_fix($string)
2794{
2795 // UTF-8 && WIN-1250 => ISO-8859-2
2796 // todo: is checking required? redundant computing?
2797 if (charset_win_is($string)) {
2798 $string = charset_win_fix($string);
2799 }
2800 if (charset_utf_is($string)) {
2801 $string = charset_utf_fix($string);
2802 }
2803 return $string;
2804}
2805function charset_win_is($string)
2806{
2807 $win = 'π•Ê∆Í ≥£Ò—Û”úåüèøØ';
2808 $iso = '±°Ê∆Í ≥£Ò—Û”∂¶º¨øØ';
2809 for ($i=0; $i<strlen($win); $i++) {
2810 if ($win{$i} != $iso{$i}) {
2811 if (strstr($string, $win{$i}) !== false) {
2812 return true;
2813 }
2814 }
2815 }
2816 return false;
2817}
2818function charset_win_fix($string)
2819{
2820 $win = 'π•Ê∆Í ≥£Ò—Û”úåüèøØ';
2821 $iso = '±°Ê∆Í ≥£Ò—Û”∂¶º¨øØ';
2822 $srh = array();
2823 $rpl = array();
2824 for ($i = 0; $i < strlen($win); $i++) {
2825 if ($win{$i} != $iso{$i}) {
2826 $srh[] = $win{$i};
2827 $rpl[] = $iso{$i};
2828 }
2829 }
2830 $string = str_replace($srh, $rpl, $string);
2831 return $string;
2832}
2833function charset_utf_is($string)
2834{
2835 $utf_iso = array(
2836 "\xc4\x85" => "\xb1",
2837 "\xc4\x84" => "\xa1",
2838 "\xc4\x87" => "\xe6",
2839 "\xc4\x86" => "\xc6",
2840 "\xc4\x99" => "\xea",
2841 "\xc4\x98" => "\xca",
2842 "\xc5\x82" => "\xb3",
2843 "\xc5\x81" => "\xa3",
2844 "\xc3\xb3" => "\xf3",
2845 "\xc3\x93" => "\xd3",
2846 "\xc5\x9b" => "\xb6",
2847 "\xc5\x9a" => "\xa6",
2848 "\xc5\xba" => "\xbc",
2849 "\xc5\xb9" => "\xac",
2850 "\xc5\xbc" => "\xbf",
2851 "\xc5\xbb" => "\xaf",
2852 "\xc5\x84" => "\xf1",
2853 "\xc5\x83" => "\xd1",
2854 // xmlhttprequest utf-8 encoding
2855 "%u0104" => "\xA1",
2856 "%u0106" => "\xC6",
2857 "%u0118" => "\xCA",
2858 "%u0141" => "\xA3",
2859 "%u0143" => "\xD1",
2860 "%u00D3" => "\xD3",
2861 "%u015A" => "\xA6",
2862 "%u0179" => "\xAC",
2863 "%u017B" => "\xAF",
2864 "%u0105" => "\xB1",
2865 "%u0107" => "\xE6",
2866 "%u0119" => "\xEA",
2867 "%u0142" => "\xB3",
2868 "%u0144" => "\xF1",
2869 "%u00D4" => "\xF3",
2870 "%u015B" => "\xB6",
2871 "%u017A" => "\xBC",
2872 "%u017C" => "\xBF"
2873 );
2874 foreach ($utf_iso as $k => $v) {
2875 if (strpos($string, $k) !== false) {
2876 return true;
2877 }
2878 }
2879 return false;
2880}
2881function charset_utf_fix($string)
2882{
2883 $utf_iso = array(
2884 "\xc4\x85" => "\xb1",
2885 "\xc4\x84" => "\xa1",
2886 "\xc4\x87" => "\xe6",
2887 "\xc4\x86" => "\xc6",
2888 "\xc4\x99" => "\xea",
2889 "\xc4\x98" => "\xca",
2890 "\xc5\x82" => "\xb3",
2891 "\xc5\x81" => "\xa3",
2892 "\xc3\xb3" => "\xf3",
2893 "\xc3\x93" => "\xd3",
2894 "\xc5\x9b" => "\xb6",
2895 "\xc5\x9a" => "\xa6",
2896 "\xc5\xba" => "\xbc",
2897 "\xc5\xb9" => "\xac",
2898 "\xc5\xbc" => "\xbf",
2899 "\xc5\xbb" => "\xaf",
2900 "\xc5\x84" => "\xf1",
2901 "\xc5\x83" => "\xd1",
2902 // xmlhttprequest uses different encoding
2903 "%u0104" => "\xA1",
2904 "%u0106" => "\xC6",
2905 "%u0118" => "\xCA",
2906 "%u0141" => "\xA3",
2907 "%u0143" => "\xD1",
2908 "%u00D3" => "\xD3",
2909 "%u015A" => "\xA6",
2910 "%u0179" => "\xAC",
2911 "%u017B" => "\xAF",
2912 "%u0105" => "\xB1",
2913 "%u0107" => "\xE6",
2914 "%u0119" => "\xEA",
2915 "%u0142" => "\xB3",
2916 "%u0144" => "\xF1",
2917 "%u00D4" => "\xF3",
2918 "%u015B" => "\xB6",
2919 "%u017A" => "\xBC",
2920 "%u017C" => "\xBF"
2921 );
2922 return str_replace(array_keys($utf_iso), array_values($utf_iso), $string);
2923}
2924function str_starts_with($str, $start, $ignore_case = false)
2925{
2926 if ($ignore_case) {
2927 $str = str_upper($str);
2928 $start = str_upper($start);
2929 }
2930 if (!strlen($str) && !strlen($start)) {
2931 return true;
2932 }
2933 if (!strlen($start)) {
2934 trigger_error('str_starts_with() failed, start arg cannot be empty', E_USER_ERROR);
2935 }
2936 if (strlen($start) > strlen($str)) {
2937 return false;
2938 }
2939 for ($i = 0; $i < strlen($start); $i++) {
2940 if ($start{$i} != $str{$i}) {
2941 return false;
2942 }
2943 }
2944 return true;
2945}
2946function str_ends_with($str, $end, $ignore_case = false)
2947{
2948 if ($ignore_case) {
2949 $str = str_upper($str);
2950 $end = str_upper($end);
2951 }
2952 if (!strlen($str) && !strlen($end)) {
2953 return true;
2954 }
2955 if (!strlen($end)) {
2956 trigger_error('str_ends_with() failed, end arg cannot be empty', E_USER_ERROR);
2957 }
2958 if (strlen($end) > strlen($str)) {
2959 return false;
2960 }
2961 return str_starts_with(strrev($str), strrev($end));
2962 return true;
2963}
2964function str_cut_start($str, $start)
2965{
2966 if (str_starts_with($str, $start)) {
2967 $str = substr($str, strlen($start));
2968 }
2969 return $str;
2970}
2971function str_cut_end($str, $end)
2972{
2973 if (str_ends_with($str, $end)) {
2974 $str = substr($str, 0, -strlen($end));
2975 }
2976 return $str;
2977}
2978function file_get($file)
2979{
2980 return file_get_contents($file);
2981}
2982function file_put($file, $s)
2983{
2984 $fp = fopen($file, 'wb') or trigger_error('fopen() failed: '.$file, E_USER_ERROR);
2985 if ($fp) {
2986 fwrite($fp, $s);
2987 fclose($fp);
2988 }
2989}
2990function file_date($file)
2991{
2992 return date('Y-m-d H:i:s', filemtime($file));
2993}
2994function dir_exists($dir)
2995{
2996 return file_exists($dir) && !is_file($dir);
2997}
2998function dir_delete_old_files($dir, $ext = array(), $sec)
2999{
3000 // NOT USED right now.
3001 // older than x seconds
3002 $files = dir_read($dir, null, $ext);
3003 $time = time() - $sec;
3004 foreach ($files as $file) {
3005 if (file_time($file) < $time) {
3006 unlink($file);
3007 }
3008 }
3009}
3010global $_error, $_error_style;
3011$_error = array();
3012$_error_style = '';
3013
3014function error($msg = null)
3015{
3016 if (isset($msg) && func_num_args() > 1) {
3017 $args = func_get_args();
3018 $msg = call_user_func_array('sprintf', $args);
3019 }
3020 global $_error, $_error_style;
3021 if (isset($msg)) {
3022 $_error[] = $msg;
3023 }
3024 if (!count($_error)) {
3025 return null;
3026 }
3027 if (count($_error) == 1) {
3028 return sprintf('<div class="error" style="%s">%s</div>', $_error_style, $_error[0]);
3029 }
3030 $ret = '<div class="error" style="'.$_error_style.'">Following errors appeared:<ul>';
3031 foreach ($_error as $msg) {
3032 $ret .= sprintf('<li>%s</li>', $msg);
3033 }
3034 $ret .= '</ul></div>';
3035 return $ret;
3036}
3037function timestamp($time, $span = true)
3038{
3039 $time_base = $time;
3040 $time = substr($time, 0, 16);
3041 $time2 = substr($time, 0, 10);
3042 $today = date('Y-m-d');
3043 $yesterday = date('Y-m-d', time()-3600*24);
3044 if ($time2 == $today) {
3045 if (substr($time_base, -8) == '00:00:00') {
3046 $time = 'Today';
3047 } else {
3048 $time = 'Today'.substr($time, -6);
3049 }
3050 } else if ($time2 == $yesterday) {
3051 $time = 'Yesterday'.substr($time, -6);
3052 }
3053 return '<span style="white-space: nowrap;">'.$time.'</span>';
3054}
3055function str_lower($str)
3056{
3057 /* strtolower iso-8859-2 compatible */
3058 $lower = str_array(iso_chars_lower());
3059 $upper = str_array(iso_chars_upper());
3060 $str = str_replace($upper, $lower, $str);
3061 $str = strtolower($str);
3062 return $str;
3063}
3064function str_upper($str)
3065{
3066 /* strtoupper iso-8859-2 compatible */
3067 $lower = str_array(iso_chars_lower());
3068 $upper = str_array(iso_chars_upper());
3069 $str = str_replace($lower, $upper, $str);
3070 $str = strtoupper($str);
3071 return $str;
3072}
3073function str_array($str)
3074{
3075 $arr = array();
3076 for ($i = 0; $i < strlen($str); $i++) {
3077 $arr[$i] = $str{$i};
3078 }
3079 return $arr;
3080}
3081function iso_chars()
3082{
3083 return iso_chars_lower().iso_chars_upper();
3084}
3085function iso_chars_lower()
3086{
3087 return '±ÊÍ≥ÒÛ∂ºø';
3088}
3089function iso_chars_upper()
3090{
3091 return '°∆ £—”¶¨Ø';
3092}
3093function array_first_key($arr)
3094{
3095 $arr2 = $arr;
3096 reset($arr);
3097 list($key, $val) = each($arr);
3098 return $key;
3099}
3100function array_first($arr)
3101{
3102 return array_first_value($arr);
3103}
3104function array_first_value($arr)
3105{
3106 $arr2 = $arr;
3107 return array_shift($arr2);
3108}
3109function array_col_values($arr, $col)
3110{
3111 $ret = array();
3112 foreach ($arr as $k => $row) {
3113 $ret[] = $row[$col];
3114 }
3115 return $ret;
3116}
3117function array_col_values_unique($arr, $col)
3118{
3119 return array_unique(array_col_values($arr, $col));
3120}
3121function array_col_match($rows, $col, $pattern)
3122{
3123 if (!count($rows)) {
3124 trigger_error('array_col_match(): array is empty', E_USER_ERROR);
3125 }
3126 $ret = true;
3127 foreach ($rows as $row) {
3128 if (!preg_match($pattern, $row[$col])) {
3129 return false;
3130 }
3131 }
3132 return true;
3133}
3134function array_col_match_unique($rows, $col, $pattern)
3135{
3136 if (!array_col_match($rows, $col, $pattern)) {
3137 return false;
3138 }
3139 return count($rows) == count(array_col_values_unique($rows, $col));
3140}
3141function redirect($url)
3142{
3143 $url = url($url);
3144 header("Location: $url");
3145 exit;
3146}
3147function redirect_notify($url, $msg)
3148{
3149 if (strpos($msg, '<') === false) {
3150 $msg = sprintf('<b>%s</b>', $msg);
3151 }
3152 cookie_set('flash_notify', $msg);
3153 redirect($url);
3154}
3155function redirect_ok($url, $msg)
3156{
3157 if (strpos($msg, '<') === false) {
3158 $msg = sprintf('<b>%s</b>', $msg);
3159 }
3160 cookie_set('flash_ok', $msg);
3161 redirect($url);
3162}
3163function redirect_error($url, $msg)
3164{
3165 if (strpos($msg, '<') === false) {
3166 $msg = sprintf('<b>%s</b>', $msg);
3167 }
3168 cookie_set('flash_error', $msg);
3169 redirect($url);
3170}
3171function flash()
3172{
3173 static $is_style = false;
3174
3175 $flash_error = cookie_get('flash_error');
3176 $flash_ok = cookie_get('flash_ok');
3177 $flash_notify = cookie_get('flash_notify');
3178
3179 $flash_error = filter_allow_tags($flash_error, '<b><i><u><br><span>');
3180 $flash_ok = filter_allow_tags($flash_ok, '<b><i><u><br><span>');
3181 $flash_notify = filter_allow_tags($flash_notify, '<b><i><u><br><span>');
3182
3183 if (!($flash_error || $flash_ok || $flash_notify)) {
3184 return false;
3185 }
3186
3187 ob_start();
3188 ?>
3189
3190 <?php if (!$is_style): ?>
3191 <style type="text/css">
3192 #flash { background: #ffffd7; padding: 0.3em; padding-bottom: 0.15em; border: #ddd 1px solid; margin-bottom: 1em; }
3193 #flash div { padding: 0em 0em; }
3194 #flash table { font-weight: normal; }
3195 #flash td { text-align: left; }
3196 </style>
3197 <?php endif; ?>
3198
3199 <div id="flash" ondblclick="document.getElementById('flash').style.display='none';">
3200 <table width="100%" ondblclick="document.getElementById('flash').style.display='none';"><tr>
3201 <td style="line-height: 14px;"><?php echo $flash_error ? $flash_error : ($flash_ok ? $flash_ok : $flash_notify); ?></td></tr></table>
3202 </div>
3203
3204 <?php
3205 $cont = ob_get_contents();
3206 ob_end_clean();
3207
3208 if ($flash_error) cookie_del('flash_error');
3209 else if ($flash_ok) cookie_del('flash_ok');
3210 else if ($flash_notify) cookie_del('flash_notify');
3211
3212 $is_style = true;
3213
3214 return $cont;
3215}
3216function filter($post, $filters)
3217{
3218 if (is_string($filters))
3219 {
3220 $filter = $filters;
3221 $func = 'filter_'.$filter;
3222 foreach ($post as $key => $val) {
3223 $post[$key] = call_user_func($func, $post[$key]);
3224 }
3225 return $post;
3226 }
3227 foreach ($filters as $key => $filter)
3228 {
3229 if (!array_key_exists($key, $post)) {
3230 return trigger_error(sprintf('filter() failed. Key missing = %s.', $key), E_USER_ERROR);
3231 }
3232 $func = 'filter_'.$filter;
3233 if (!function_exists($func)) {
3234 return trigger_error(sprintf('filter() failed. Filter missing = %s.', $func), E_USER_ERROR);
3235 }
3236 $post[$key] = call_user_func($func, $post[$key]);
3237 }
3238 return $post;
3239}
3240function filter_html($s)
3241{
3242 if (req_gpc_has($s)) {
3243 $s = html_tags_undo($s);
3244 }
3245 return html(trim($s));
3246}
3247function filter_allow_tags($s, $allow)
3248{
3249 if (req_gpc_has($s)) {
3250 $s = html_tags_undo($s);
3251 }
3252 return html_allow_tags($s, $allow);
3253}
3254function filter_allow_html($s)
3255{
3256 global $SafeHtml;
3257 if (!isset($SafeHtml)) {
3258 include_once 'inc/SafeHtml.php';
3259 }
3260 if (req_gpc_has($s)) {
3261 $s = html_tags_undo($s);
3262 }
3263 if (in_array(trim(strtolower($s)), array('<br>', '<p> </p>'))) {
3264 return '';
3265 }
3266 $SafeHtml->clear();
3267 $s = $SafeHtml->parse($s);
3268 return trim($s);
3269}
3270function filter_allow_html_script($s)
3271{
3272 if (in_array(trim(strtolower($s)), array('<br>', '<p> </p>'))) {
3273 return '';
3274 }
3275 if (req_gpc_has($s)) {
3276 $s = html_tags_undo($s);
3277 }
3278 return trim($s);
3279}
3280function filter_editor($s)
3281{
3282 return filter_allow_html($s);
3283}
3284function date_now()
3285{
3286 return date('Y-m-d H:i:s');
3287}
3288function guess_pk($rows)
3289{
3290 if (!count($rows)) {
3291 return false;
3292 }
3293 $patterns = array('#^\d+$#', '#^[^\s]+$#');
3294 $row = array_first($rows);
3295 foreach ($patterns as $pattern)
3296 {
3297 foreach ($row as $col => $v) {
3298 if ($v && preg_match($pattern, $v)) {
3299 if (array_col_match_unique($rows, $col, $pattern)) {
3300 return $col;
3301 }
3302 }
3303 }
3304 }
3305 return false;
3306}
3307function layout_start($title='')
3308{
3309 global $page_charset;
3310 $flash = flash();
3311 ?>
3312
3313 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
3314 <html>
3315 <head>
3316 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $page_charset;?>">
3317 <title><?php echo $title;?></title>
3318 <link rel="shortcut icon" href="<?php echo $_SERVER['PHP_SELF']; ?>?dbkiss_favicon=1">
3319 <script>
3320 function $(id)
3321 {
3322 if (typeof id == 'string') return document.getElementById(id);
3323 return id;
3324 }
3325 </script>
3326 </head>
3327 <body>
3328
3329 <?php layout(); ?>
3330
3331 <?php if ($flash) { echo $flash; } ?>
3332
3333 <?php
3334}
3335function layout_end()
3336{
3337 ?>
3338 <?php powered_by(); ?>
3339 </body>
3340 </html>
3341 <?php
3342}
3343function powered_by()
3344{
3345 ?>
3346 <script>
3347 function link_noreferer(link)
3348 {
3349 // Tested: Chrome, Firefox, Inetrnet Explorer, Opera.
3350 var w = window.open("about:blank", "_blank");
3351 w.document.open();
3352 w.document.write("<"+"!doctype html>");
3353 w.document.write("<"+"html><"+"head>");
3354 w.document.write("<"+"title>Secure redirection</title>");
3355 w.document.write("<"+"style>body { font: 11px Tahoma; }<"+"/style>");
3356 w.document.write("<"+"meta http-equiv=refresh content='10;url="+link+"'>");
3357 // Meta.setAttribute() doesn't work on firefox.
3358 // Firefox: needs document.write('<meta>')
3359 // IE: the firefox workaround doesn't work on ie, but we can use a normal redirection
3360 // as IE is already not sending the referer because it does not do it when using
3361 // open.window, besides the blank url in address bar works fine (about:blank).
3362 // Opera: firefox fix works.
3363 w.document.write("<"+"script>function redirect() { if (navigator.userAgent.indexOf('MSIE') != -1) { location.replace('"+link+"'); } else { document.open(); document.write('<"+"meta http-equiv=refresh content=\"0;"+link+"\">'); document.close(); } }<"+"/script>");
3364 w.document.write("<"+"/head><"+"body>");
3365 w.document.write("<"+"h1>Secure redirection<"+"/h1>");
3366 w.document.write("<"+"p>This is a secure redirection that hides the HTTP REFERER header - using javascript and meta refresh combination.");
3367 w.document.write("<br>The site you are being redirected will not know the location of the dbkiss script on your site.<"+"/p>");
3368 w.document.write("<"+"p>In 10 seconds you will be redirected to the following address: <"+"a href='javascript:void(0)' onclick='redirect()'>"+link+"<"+"/a><br>");
3369 w.document.write("Clicking the link is also secure, so if you do not wish to wait, then click it.<"+"/p>");
3370 w.document.write("<"+"/body><"+"/html>");
3371 w.document.close();
3372 }
3373 </script>
3374 <div style="text-align: center; margin-top: 2em; border-top: #ccc 1px solid; padding-top: 0.5em;">Powered by <a href="javascript:void(0)" onclick="link_noreferer('http://www.gosu.pl/dbkiss/')">dbkiss</a></div>
3375 <?php
3376}
3377
3378?>
3379<?php if (get('import')): ?>
3380
3381 <?php
3382
3383 // ----------------------------------------------------------------
3384 // IMPORT
3385 // ----------------------------------------------------------------
3386
3387 ?>
3388
3389 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
3390 <html>
3391 <head>
3392 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $page_charset;?>">
3393 <title><?php echo $db_name_h1?$db_name_h1:$db_name;?> > Import</title>
3394 <link rel="shortcut icon" href="<?php echo $_SERVER['PHP_SELF']; ?>?dbkiss_favicon=1">
3395 </head>
3396 <body>
3397
3398 <?php layout(); ?>
3399 <h1><a class=blue style="<?php echo $db_name_style;?>" href="<?php echo $_SERVER['PHP_SELF'];?>"><?php echo $db_name_h1?$db_name_h1:$db_name;?></a> > Import</h1>
3400 <?php conn_info(); ?>
3401
3402 <?php $files = sql_files(); ?>
3403
3404 <?php if (count($files)): ?>
3405 <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
3406 <table class="none" cellspacing="0" cellpadding="0">
3407 <tr>
3408 <td>SQL file:</th>
3409 <td><select name="sqlfile"><option value="" selected="selected"></option><?php echo options($files);?></select></td>
3410 <td><input type="checkbox" name="ignore_errors" id="ignore_errors" value="1"></td>
3411 <td><label for="ignore_errors">ignore errors</label></td>
3412 <td><input type="checkbox" name="transaction" id="transaction" value="1"></td>
3413 <td><label for="transaction">transaction</label></td>
3414 <td><input type="checkbox" name="force_myisam" id="force_myisam" value="1"></td>
3415 <td><label for="force_myisam">force myisam</label></td>
3416 <td><input type="text" size="5" name="query_start" value=""></td>
3417 <td>query start</td>
3418 <td><input type="submit" value="Import"></td>
3419 </tr>
3420 </table>
3421 </form>
3422 <br>
3423 <?php else: ?>
3424 No sql files found in current directory.
3425 <?php endif; ?>
3426
3427 <?php powered_by(); ?>
3428
3429 </body></html>
3430
3431<?php exit; endif; ?>
3432<?php if ('editrow' == get('action')): ?>
3433<?php
3434 function dbkiss_filter_id($id)
3435 {
3436 if (preg_match('#^[_a-z][a-z0-9_\-]*$#i', $id)) {
3437 return $id;
3438 }
3439 return false;
3440 }
3441
3442 $get = get(array(
3443 'table' => 'string',
3444 'pk' => 'string',
3445 'id' => 'string'
3446 ));
3447
3448 $get['table'] = html_once($get['table']);
3449 $get['pk'] = html_once($get['pk']);
3450
3451 $title_edit = sprintf('Edit row (%s=%s)', $get['pk'], $get['id']);
3452 $title = ' > '.$get['table'].' > '.$title_edit;
3453
3454 if (!dbkiss_filter_id($get['table'])) {
3455 error('Invalid table name');
3456 }
3457 if (!dbkiss_filter_id($get['pk'])) {
3458 error('Invalid pk');
3459 }
3460
3461 $row = false;
3462
3463 if (!error())
3464 {
3465 $table_enq = quote_table($get['table']);
3466 $test = db_row("SELECT * FROM $table_enq");
3467 if ($test) {
3468 if (!array_key_exists($get['pk'], $test)) {
3469 error('Invalid pk');
3470 }
3471 }
3472 if (!error())
3473 {
3474 $table_enq = quote_table($get['table']);
3475 $query = db_bind("SELECT * FROM $table_enq WHERE {$get['pk']} = %0", $get['id']);
3476 $query = db_limit($query, 0, 2);
3477 $rows = db_list($query);
3478 if (count($rows) > 1) {
3479 error('Invalid pk: found more than one row with given id');
3480 } else if (count($rows) == 0) {
3481 error('Row not found');
3482 } else {
3483 $row = $rows[0];
3484 $row_id = $row[$get['pk']];
3485 }
3486 }
3487 }
3488
3489 if ($row) {
3490 $types = table_types2($get['table']);
3491 }
3492
3493 $edit_actions_assoc = array(
3494 'update' => 'Update',
3495 'update_pk' => 'Overwrite pk',
3496 'insert' => 'Copy row (insert)',
3497 'delete' => 'Delete'
3498 );
3499
3500 $edit_action = post('dbkiss_action');
3501
3502 if ($_ENV['IS_GET'])
3503 {
3504 $edit_action = array_first_key($edit_actions_assoc);
3505 $post = $row;
3506 }
3507
3508 if ($_ENV['IS_POST'])
3509 {
3510 if (!array_key_exists($edit_action, $edit_actions_assoc)) {
3511 $edit_action = '';
3512 error('Invalid action');
3513 }
3514
3515 $post = array();
3516 foreach ($row as $k => $v) {
3517 if (array_key_exists($k, $_POST)) {
3518 $val = (string) $_POST[$k];
3519 if ('null' == $val) {
3520 $val = null;
3521 }
3522 if ('int' == $types[$k]) {
3523 if (!strlen($val)) {
3524 $val = null;
3525 }
3526 if (!(preg_match('#^-?\d+$#', $val) || is_null($val))) {
3527 error('%s: invalid value', $k);
3528 }
3529 }
3530 if ('float' == $types[$k]) {
3531 if (!strlen($val)) {
3532 $val = null;
3533 }
3534 $val = str_replace(',', '.', $val);
3535 if (!(is_numeric($val) || is_null($val))) {
3536 error('%s: invalid value', $k);
3537 }
3538 }
3539 if ('time' == $types[$k]) {
3540 if (!strlen($val)) {
3541 $val = null;
3542 }
3543 if ('now' == $val) {
3544 $val = date_now();
3545 }
3546 }
3547 $post[$k] = $val;
3548 } else {
3549 error('Missing key: %s in POST', $k);
3550 }
3551 }
3552
3553 if ('update' == $edit_action)
3554 {
3555 if ($post[$get['pk']] != $row[$get['pk']]) {
3556 if (count($row) != 1) { // Case: more than 1 column
3557 error('%s: cannot change pk on UPDATE', $get['pk']);
3558 }
3559 }
3560 }
3561 if ('update_pk' == $edit_action)
3562 {
3563 if ($post[$get['pk']] == $row[$get['pk']]) {
3564 error('%s: selected action Overwrite pk, but pk value has not changed', $get['pk']);
3565 }
3566 }
3567 if ('insert' == $edit_action)
3568 {
3569 if (strlen($post[$get['pk']])) {
3570 $table_enq = quote_table($get['table']);
3571 $test = db_row("SELECT * FROM $table_enq WHERE {$get['pk']} = %0", array($post[$get['pk']]));
3572 if ($test) {
3573 error('%s: there is already a record with that id', $get['pk']);
3574 }
3575 }
3576 }
3577
3578 if (!error())
3579 {
3580 $post2 = $post;
3581 if ('update' == $edit_action)
3582 {
3583 if (count($row) != 1) { // Case: more than 1 column
3584 unset($post2[$get['pk']]);
3585 }
3586 db_update($get['table'], $post2, array($get['pk'] => $row_id));
3587 if (db_error()) {
3588 error('<font color="red"><b>DB error</b></font>: '.db_error());
3589 } else {
3590 if (count($row) == 1) { // Case: only 1 column
3591 redirect_ok(url(self(), array('id'=>$post[$get['pk']])), 'Row updated');
3592 } else {
3593 redirect_ok(self(), 'Row updated');
3594 }
3595 }
3596 }
3597 if ('update_pk' == $edit_action)
3598 {
3599 @db_update($get['table'], $post2, array($get['pk'] => $row_id));
3600 if (db_error()) {
3601 error('<font color="red"><b>DB error</b></font>: '.db_error());
3602 } else {
3603 $url = url(self(), array('id' => $post[$get['pk']]));
3604 redirect_ok($url, 'Row updated (pk overwritten)');
3605 }
3606 }
3607 if ('insert' == $edit_action)
3608 {
3609 $new_id = false;
3610 if (!strlen($post2[$get['pk']])) {
3611 unset($post2[$get['pk']]);
3612 } else {
3613 $new_id = $post2[$get['pk']];
3614 }
3615 @db_insert($get['table'], $post2);
3616 if (db_error()) {
3617 error('<font color="red"><b>DB error</b></font>: '.db_error());
3618 } else {
3619 if (!$new_id) {
3620 $new_id = db_insert_id($get['table'], $get['pk']);
3621 }
3622 $url = url(self(), array('id'=>$new_id));
3623 $msg = sprintf('Row inserted (%s=%s)', $get['pk'], $new_id);
3624 redirect_ok($url, $msg);
3625 }
3626 }
3627 if ('delete' == $edit_action)
3628 {
3629 $table_enq = quote_table($get['table']);
3630 @db_exe("DELETE FROM $table_enq WHERE {$get['pk']} = %0", $get['id']);
3631 if (db_error()) {
3632 error('<font color="red"><b>DB error</b></font>: '.db_error());
3633 } else {
3634 redirect_ok(self(), 'Row deleted');
3635 }
3636 }
3637 }
3638 }
3639
3640 ?>
3641<?php layout_start($title_edit); ?>
3642 <h1><span style="<?php echo $db_name_style;?>"><?php echo $db_name_h1?$db_name_h1:$db_name;?></span><?php echo $title;?></h1>
3643
3644 <?php echo error();?>
3645
3646 <?php if ($row): ?>
3647
3648 <form action="<?php echo self();?>" method="post">
3649
3650 <?php echo radio_assoc($edit_action, $edit_actions_assoc, 'dbkiss_action');?></td>
3651 <br>
3652
3653 <table cellspacing="1" class="ls ls2">
3654 <?php foreach ($post as $k => $v): if (is_null($v)) { $v = 'null'; } $v = htmlspecialchars($v); ?>
3655 <tr>
3656 <th><?php echo $k;?>:</th>
3657 <td>
3658 <?php if ('int' == $types[$k]): ?>
3659 <input type="text" name="<?php echo $k;?>" value="<?php echo html_once($v);?>" size="11">
3660 <?php elseif ('char' == $types[$k]): ?>
3661 <input type="text" name="<?php echo $k;?>" value="<?php echo html_once($v);?>" size="50">
3662 <?php elseif (in_array($types[$k], array('text', 'mediumtext', 'longtext')) || str_has($types[$k], 'blob')): ?>
3663 <textarea name="<?php echo $k;?>" cols="80" rows="<?php echo $k=='notes'?10:10;?>"><?php echo html_once($v);?></textarea>
3664 <?php else: ?>
3665 <input type="text" name="<?php echo $k;?>" value="<?php echo html_once($v);?>" size="30">
3666 <?php endif; ?>
3667 </td>
3668 <td valign="top"><?php echo $types[$k];?></td>
3669 </tr>
3670 <?php endforeach; ?>
3671 <tr>
3672 <td colspan="3" class="none">
3673 <input type="submit" wait="1" block="1" class="button" value="Edit">
3674 </td>
3675 </tr>
3676 </table>
3677
3678 </form>
3679
3680 <?php endif; ?>
3681
3682 <?php layout_end(); ?>
3683
3684<?php exit; endif; ?>
3685<?php if (isset($_GET['execute_sql']) && $_GET['execute_sql']): ?>
3686<?php
3687
3688function listing($base_query, $md5_get = false)
3689{
3690 global $db_driver, $db_link;
3691
3692 $md5_i = false;
3693 if ($md5_get) {
3694 preg_match('#_(\d+)$#', $md5_get, $match);
3695 $md5_i = $match[1];
3696 }
3697
3698 $base_query = trim($base_query);
3699 $base_query = str_cut_end($base_query, ';');
3700
3701 $query = $base_query;
3702 $ret = array('msg'=>'', 'error'=>'', 'data_html'=>false);
3703 $limit = 25;
3704 $offset = get('offset','int');
3705 $page = floor($offset / $limit + 1);
3706
3707 if ($query) {
3708 if (is_select($query) && !preg_match('#\s+LIMIT\s+\d+#i', $query) && !preg_match('#into\s+outfile\s+#', $query)) {
3709 $query = db_limit($query, $offset, $limit);
3710 } else {
3711 $limit = false;
3712 }
3713 $time = time_start();
3714 if (!db_is_safe($query, true)) {
3715 $ret['error'] = 'Detected UPDATE/DELETE without WHERE condition (put WHERE 1=1 if you want to execute this query)';
3716 return $ret;
3717 }
3718 $rs = @db_query($query);
3719 if ($rs) {
3720 if ($rs === true) {
3721 if ('mysql' == $db_driver)
3722 {
3723 $affected = mysql_affected_rows($db_link);
3724 $time = time_end($time);
3725 $ret['data_html'] = '<b>'.$affected.'</b> rows affected.<br>Time: <b>'.$time.'</b> sec';
3726 return $ret;
3727 }
3728 } else {
3729 if ('pgsql' == $db_driver)
3730 {
3731 $affected = @pg_affected_rows($rs);
3732 if ($affected || preg_match('#^\s*(DELETE|UPDATE)\s+#i', $query)) {
3733 $time = time_end($time);
3734 $ret['data_html'] = '<p><b>'.$affected.'</b> rows affected. Time: <b>'.$time.'</b> sec</p>';
3735 return $ret;
3736 }
3737 }
3738 }
3739
3740 $rows = array();
3741 while ($row = db_row($rs)) {
3742 $rows[] = $row;
3743 if ($limit) {
3744 if (count($rows) == $limit) { break; }
3745 }
3746 }
3747 db_free($rs);
3748
3749 if (is_select($base_query)) {
3750 $found = @db_one("SELECT COUNT(*) FROM ($base_query) AS sub");
3751 if (!is_numeric($found) || (count($rows) && !$found)) {
3752 global $COUNT_ERROR;
3753 $COUNT_ERROR = ' (COUNT ERROR) ';
3754 $found = count($rows);
3755 }
3756 } else {
3757 if (count($rows)) {
3758 $found = count($rows);
3759 } else {
3760 $found = false;
3761 }
3762 }
3763 if ($limit) {
3764 $pages = ceil($found / $limit);
3765 } else {
3766 $pages = 1;
3767 }
3768 $time = time_end($time);
3769
3770 } else {
3771 $ret['error'] = db_error();
3772 return $ret;
3773 }
3774 } else {
3775 $ret['error'] = 'No query found.';
3776 return $ret;
3777 }
3778
3779 ob_start();
3780?>
3781 <?php if (is_numeric($found)): ?>
3782 <p>
3783 Found: <b><?php echo $found;?></b><?php echo isset($GLOBALS['COUNT_ERROR'])?$GLOBALS['COUNT_ERROR']:'';?>.
3784 Time: <b><?php echo $time;?></b> sec.
3785 <?php
3786 $params = array('md5'=>$md5_get, 'offset'=>get('offset','int'));
3787 if (get('only_marked') || post('only_marked')) { $params['only_marked'] = 1; }
3788 if (get('only_select') || post('only_select')) { $params['only_select'] = 1; }
3789 ?>
3790 / <a href="<?php echo url(self(), $params);?>">Refetch</a>
3791 / Export to CSV:
3792
3793 <a href="<?php echo $_SERVER['PHP_SELF']; ?>?export=csv&separator=<?php echo urlencode('|');?>&query=<?php echo base64_encode($base_query); ?>">pipe</a>
3794 -
3795 <a href="<?php echo $_SERVER['PHP_SELF']; ?>?export=csv&separator=<?php echo urlencode("\t");?>&query=<?php echo base64_encode($base_query); ?>">tab</a>
3796 -
3797 <a href="<?php echo $_SERVER['PHP_SELF']; ?>?export=csv&separator=<?php echo urlencode(',');?>&query=<?php echo base64_encode($base_query); ?>">comma</a>
3798 -
3799 <a href="<?php echo $_SERVER['PHP_SELF']; ?>?export=csv&separator=<?php echo urlencode(';');?>&query=<?php echo base64_encode($base_query); ?>">semicolon</a>
3800 </p>
3801 <?php else: ?>
3802 <p>Result: <b>OK</b>. Time: <b><?php echo $time;?></b> sec</p>
3803 <?php endif; ?>
3804
3805 <?php if (is_numeric($found)): ?>
3806
3807 <?php if ($pages > 1): ?>
3808 <p>
3809 <?php if ($page > 1): ?>
3810 <?php $ofs = ($page-1)*$limit-$limit; ?>
3811 <?php
3812 $params = array('md5'=>$md5_get, 'offset'=>$ofs);
3813 if (get('only_marked') || post('only_marked')) { $params['only_marked'] = 1; }
3814 if (get('only_select') || post('only_select')) { $params['only_select'] = 1; }
3815 ?>
3816 <a href="<?php echo url(self(), $params);?>"><< Prev</a>
3817 <?php endif; ?>
3818 Page <b><?php echo $page;?></b> of <b><?php echo $pages;?></b>
3819 <?php if ($pages > $page): ?>
3820 <?php $ofs = $page*$limit; ?>
3821 <?php
3822 $params = array('md5'=>$md5_get, 'offset'=>$ofs);
3823 if (get('only_marked') || post('only_marked')) { $params['only_marked'] = 1; }
3824 if (get('only_select') || post('only_select')) { $params['only_select'] = 1; }
3825 ?>
3826 <a href="<?php echo url(self(), $params);?>">Next >></a>
3827 <?php endif; ?>
3828 </p>
3829 <?php endif; ?>
3830
3831 <script>
3832 function mark_row(tr)
3833 {
3834 var els = tr.getElementsByTagName('td');
3835 if (tr.marked) {
3836 for (var i = 0; i < els.length; i++) {
3837 els[i].style.backgroundColor = '';
3838 }
3839 tr.marked = false;
3840 } else {
3841 tr.marked = true;
3842 for (var i = 0; i < els.length; i++) {
3843 els[i].style.backgroundColor = '#ddd';
3844 }
3845 }
3846 }
3847 </script>
3848
3849 <?php if ($found): ?>
3850
3851 <?php
3852 $edit_table = table_from_query($base_query);
3853 if ($edit_table) {
3854 $edit_pk = array_first_key($rows[0]);
3855 if (is_numeric($edit_pk)) { $edit_table = false; }
3856 }
3857 if ($edit_table) {
3858 $types = table_types2($edit_table);
3859 if ($types && count($types)) {
3860 if (in_array($edit_pk, array_keys($types))) {
3861 if (!array_col_match_unique($rows, $edit_pk, '#^\d+$#')) {
3862 $edit_pk = guess_pk($rows);
3863 if (!$edit_pk) {
3864 $edit_table = false;
3865 }
3866 }
3867 } else {
3868 $edit_table = false;
3869 }
3870 } else {
3871 $edit_table = false;
3872 }
3873 }
3874 $edit_url = '';
3875 if ($edit_table) {
3876 $edit_url = url(self(true), array('action'=>'editrow', 'table'=>$edit_table, 'pk'=>$edit_pk, 'id'=>'%s'));
3877 }
3878 ?>
3879
3880 <table class="ls" cellspacing="1">
3881 <tr>
3882 <?php if ($edit_url): ?><th>#</th><?php endif; ?>
3883 <?php foreach ($rows[0] as $col => $v): ?>
3884 <th><?php echo $col;?></th>
3885 <?php endforeach; ?>
3886 </tr>
3887 <?php foreach ($rows as $row): ?>
3888 <tr ondblclick="mark_row(this)">
3889 <?php if ($edit_url): ?>
3890 <td><a href="javascript:void(0)" onclick="popup('<?php echo sprintf($edit_url, $row[$edit_pk]);?>', 620, 500)">Edit</a> </td>
3891 <?php endif; ?>
3892 <?php
3893 $count_cols = 0;
3894 foreach ($row as $v) { $count_cols++; }
3895 ?>
3896 <?php foreach ($row as $k => $v): ?>
3897 <?php
3898 if (preg_match('#^\s*<a[^>]+>[^<]+</a>\s*$#iU', $v) && strlen(strip_tags($v)) < 50) {
3899 $v = strip_tags($v, '<a>');
3900 $v = create_links($v);
3901 } else {
3902 $v = strip_tags($v);
3903 $v = str_replace(' ', ' ', $v);
3904 $v = preg_replace('#[ ]+#', ' ', $v);
3905 $v = create_links($v);
3906 if (!get('full_content') && strlen($v) > 50) {
3907 if (1 == $count_cols) {
3908 $v = truncate_html($v, 255);
3909 } else {
3910 $v = truncate_html($v, 50);
3911 }
3912 }
3913 // $v = html_once($v); - create_links() disabling
3914 }
3915 $nl2br = get('nl2br');
3916 if (get('full_content')) {
3917 $v = str_wrap($v, 80, '<br>', true);
3918 }
3919 if (get('nl2br')) {
3920 $v = nl2br($v);
3921 }
3922 //$v = stripslashes(stripslashes($v));
3923 if (@$types[$k] == 'int' && (preg_match('#time#i', $k) || preg_match('#date#i', $k))
3924 && preg_match('#^\d+$#', $v))
3925 {
3926 $tmp = @date('Y-m-d H:i', $v);
3927 if ($tmp) {
3928 $v = $tmp;
3929 }
3930 }
3931 global $post;
3932 if (str_has($post['sql'], '@gethostbyaddr') && (preg_match('#^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $v))) {
3933 $v = $v.'<br>'.@gethostbyaddr($v);
3934 }
3935 ?>
3936 <td onclick="mark_col(this)" <?php echo $nl2br?'valign="top"':'';?> nowrap><?php echo is_null($row[$k])?'-':$v;?></td>
3937 <?php endforeach; ?>
3938 </tr>
3939 <?php endforeach; ?>
3940 </table>
3941
3942 <?php endif; ?>
3943
3944 <?php if ($pages > 1): ?>
3945 <p>
3946 <?php if ($page > 1): ?>
3947 <?php $ofs = ($page-1)*$limit-$limit; ?>
3948 <?php
3949 $params = array('md5'=>$md5_get, 'offset'=>$ofs);
3950 if (get('only_marked') || post('only_marked')) { $params['only_marked'] = 1; }
3951 if (get('only_select') || post('only_select')) { $params['only_select'] = 1; }
3952 ?>
3953 <a href="<?php echo url(self(), $params);?>"><< Prev</a>
3954 <?php endif; ?>
3955 Page <b><?php echo $page;?></b> of <b><?php echo $pages;?></b>
3956 <?php if ($pages > $page): ?>
3957 <?php $ofs = $page*$limit; ?>
3958 <?php
3959 $params = array('md5'=>$md5_get, 'offset'=>$ofs);
3960 if (get('only_marked') || post('only_marked')) { $params['only_marked'] = 1; }
3961 if (get('only_select') || post('only_select')) { $params['only_select'] = 1; }
3962 ?>
3963 <a href="<?php echo url(self(), $params);?>">Next >></a>
3964 <?php endif; ?>
3965 </p>
3966 <?php endif; ?>
3967
3968 <?php endif; ?>
3969
3970<?php
3971 $cont = ob_get_contents();
3972 ob_end_clean();
3973 $ret['data_html'] = $cont;
3974 return $ret;
3975}
3976
3977?>
3978<?php
3979
3980 // ----------------------------------------------------------------
3981 // EXECUTE SQL
3982 // ----------------------------------------------------------------
3983
3984 set_time_limit(0);
3985
3986 $template = get('template');
3987 $msg = '';
3988 $error = '';
3989 $top_html = '';
3990 $data_html = '';
3991
3992 $get = get(array(
3993 'popup'=> 'int',
3994 'md5' => 'string',
3995 'only_marked' => 'bool',
3996 'only_select' => 'bool'
3997 ));
3998 $post = post(array(
3999 'sql' => 'string',
4000 'perform' => 'string',
4001 'only_marked' => 'bool',
4002 'only_select' => 'bool',
4003 'save_as' => 'string',
4004 'load_from' => 'string'
4005 ));
4006
4007 if ($get['md5']) {
4008 $get['only_select'] = true;
4009 $post['only_select'] = true;
4010 }
4011
4012 if ($get['only_marked']) { $post['only_marked'] = 1; }
4013 if ($get['only_select']) { $post['only_select'] = 1; }
4014
4015 $sql_dir = false;
4016 if (defined('DBKISS_SQL_DIR')) {
4017 $sql_dir = DBKISS_SQL_DIR;
4018 }
4019
4020 if ($sql_dir) {
4021 if (!(dir_exists($sql_dir) && is_writable($sql_dir))) {
4022 if (!dir_exists($sql_dir) && is_writable('.')) {
4023 mkdir($sql_dir);
4024 } else {
4025 exit('You must create "'.$sql_dir.'" directory with write permission.');
4026 }
4027 }
4028 if (!file_exists($sql_dir.'/.htaccess')) {
4029 file_put($sql_dir.'/.htaccess', 'deny from all');
4030 }
4031 if (!file_exists($sql_dir.'/index.html')) {
4032 file_put($sql_dir.'/index.html', '');
4033 }
4034 }
4035
4036 if ('GET' == $_SERVER['REQUEST_METHOD']) {
4037 if ($sql_dir)
4038 {
4039 if ($get['md5'] && preg_match('#^(\w{32,32})_(\d+)$#', $get['md5'], $match)) {
4040 $md5_i = $match[2];
4041 $md5_tmp = sprintf($sql_dir.'/zzz_%s.dat', $match[1]);
4042 $post['sql'] = file_get($md5_tmp);
4043 $_SERVER['REQUEST_METHOD'] = 'POST';
4044 $post['perform'] = 'execute';
4045 } else if ($get['md5'] && preg_match('#^(\w{32,32})$#', $get['md5'], $match)) {
4046 $md5_tmp = sprintf($sql_dir.'/zzz_%s.dat', $match[1]);
4047 $post['sql'] = file_get($md5_tmp);
4048 $get['md5'] = '';
4049 } else {
4050 if ($get['md5']) {
4051 trigger_error('invalid md5', E_USER_ERROR);
4052 }
4053 }
4054 }
4055 } else {
4056 $get['md5'] = '';
4057 }
4058
4059 if (str_has($post['sql'], '@nl2br')) {
4060 $_GET['nl2br'] = 1;
4061 }
4062 if (str_has($post['sql'], '@full_content')) {
4063 $_GET['full_content'] = 1;
4064 }
4065
4066 $post['sql'] = trim($post['sql']);
4067 $md5 = md5($post['sql']);
4068 $md5_file = sprintf($sql_dir.'/zzz_%s.dat', $md5);
4069 if ($sql_dir && $post['sql']) {
4070 file_put($md5_file, $post['sql']);
4071 }
4072
4073 if ($sql_dir && 'save' == $post['perform'] && $post['save_as'] && $post['sql'])
4074 {
4075 $post['save_as'] = str_replace('.sql', '', $post['save_as']);
4076 if (preg_match('#^[\w ]+$#', $post['save_as'])) {
4077 $file = $sql_dir.'/'.$post['save_as'].'.sql';
4078 $overwrite = '';
4079 if (file_exists($file)) {
4080 $overwrite = ' - <b>overwritten</b>';
4081 $bak = $sql_dir.'/zzz_'.$post['save_as'].'_'.md5(file_get($file)).'.dat';
4082 copy($file, $bak);
4083 }
4084 $msg .= sprintf('<div>Sql saved: %s %s</div>', basename($file), $overwrite);
4085 file_put($file, $post['sql']);
4086 } else {
4087 error('Saving sql failed: only alphanumeric chars are allowed');
4088 }
4089 }
4090
4091 if ($sql_dir) {
4092 $load_files = dir_read($sql_dir, null, array('.sql'), 'date_desc');
4093 }
4094 $load_assoc = array();
4095 if ($sql_dir) {
4096 foreach ($load_files as $file) {
4097 $file_path = $file;
4098 $file = basename($file);
4099 $load_assoc[$file] = '('.substr(file_date($file_path), 0, 10).')'.' ' .$file;
4100 }
4101 }
4102
4103 if ($sql_dir && 'load' == $post['perform'])
4104 {
4105 $file = $sql_dir.'/'.$post['load_from'];
4106 if (array_key_exists($post['load_from'], $load_assoc) && file_exists($file)) {
4107 $msg .= sprintf('<div>Sql loaded: %s (%s)</div>', basename($file), timestamp(file_date($file)));
4108 $post['sql'] = file_get($file);
4109 $post['save_as'] = basename($file);
4110 $post['save_as'] = str_replace('.sql', '', $post['save_as']);
4111 } else {
4112 error('<div>File not found: %s</div>', $file);
4113 }
4114 }
4115
4116 // after load - md5 may change
4117 $md5 = md5($post['sql']);
4118
4119 if ($sql_dir && 'load' == $post['perform'] && !error()) {
4120 $md5_tmp = sprintf($sql_dir.'/zzz_%s.dat', $md5);
4121 file_put($md5_tmp, $post['sql']);
4122 }
4123
4124 $is_sel = false;
4125
4126 $queries = preg_split("#;(\s*--[ \t\S]*)?(\r\n|\n|\r)#U", $post['sql']);
4127 foreach ($queries as $k => $query) {
4128 $query = query_strip($query);
4129 if (str_starts_with($query, '@')) {
4130 $is_sel = true;
4131 }
4132 $queries[$k] = $query;
4133 if (!trim($query)) { unset($queries[$k]); }
4134 }
4135
4136 $sql_assoc = array();
4137 $sql_selected = false;
4138 $i = 0;
4139
4140 $params = array(
4141 'md5' => $md5,
4142 'only_marked' => $post['only_marked'],
4143 'only_select' => $post['only_select'],
4144 'offset' => ''
4145 );
4146 $sql_main_url = url(self(), $params);
4147
4148 foreach ($queries as $query) {
4149 $i++;
4150 $query = str_cut_start($query, '@');
4151 if (!is_select($query)) {
4152 continue;
4153 }
4154 $query = preg_replace('#\s+#', ' ', $query);
4155 $params = array(
4156 'md5' => $md5.'_'.$i,
4157 'only_marked' => $post['only_marked'],
4158 'only_select' => $post['only_select'],
4159 'offset' => ''
4160 );
4161 $url = url(self(), $params);
4162 if ($get['md5'] && $get['md5'] == $params['md5']) {
4163 $sql_selected = $url;
4164 }
4165 $sql_assoc[$url] = str_truncate(strip_tags($query), 80);
4166 }
4167
4168 if ('POST' == $_SERVER['REQUEST_METHOD'])
4169 {
4170 if (!$post['perform']) {
4171 $error = 'No action selected.';
4172 }
4173 if (!$error)
4174 {
4175 $time = time_start();
4176 switch ($post['perform']) {
4177 case 'execute':
4178 $i = 0;
4179 db_begin();
4180 $commit = true;
4181 foreach ($queries as $query)
4182 {
4183 $i++;
4184 if ($post['only_marked'] && !$is_sel) {
4185 if (!$get['md5']) { continue; }
4186 }
4187 if ($is_sel) {
4188 if (str_starts_with($query, '@')) {
4189 $query = str_cut_start($query, '@');
4190 } else {
4191 if (!$get['md5']) { continue; }
4192 }
4193 }
4194 if ($post['only_select'] && !is_select($query)) {
4195 continue;
4196 }
4197 if ($get['md5'] && $i != $md5_i) {
4198 continue;
4199 }
4200 if ($get['md5'] && $i == $md5_i) {
4201 if (!is_select($query)) {
4202 trigger_error('not select query', E_USER_ERROR);
4203 }
4204 }
4205
4206 $exec = listing($query, $md5.'_'.$i);
4207 $query_trunc = str_truncate(html_once($query), 1000);
4208 $query_trunc = query_color($query_trunc);
4209 $query_trunc = nl2br($query_trunc);
4210 $query_trunc = html_spaces($query_trunc);
4211 if ($exec['error']) {
4212 $exec['error'] = preg_replace('#error:#i', '', $exec['error']);
4213 $top_html .= sprintf('<div style="background: #ffffd7; padding: 0.5em; border: #ccc 1px solid; margin-bottom: 1em; margin-top: 1em;"><b style="color:red">Error</b>: %s<div style="margin-top: 0.25em;"><b>Query %s</b>: %s</div></div>', $exec['error'], $i, $query_trunc);
4214 $commit = false;
4215 break;
4216 } else {
4217 $query_html = sprintf('<div class="query"><b style="font-size: 10px;">Query %s</b>:<div style="'.$sql_font.' margin-top: 0.35em;">%s</div></div>', $i, $query_trunc);
4218 $data_html .= $query_html;
4219 $data_html .= $exec['data_html'];
4220 }
4221 }
4222 if ($commit) {
4223 db_end();
4224 } else {
4225 db_rollback();
4226 }
4227 break;
4228 }
4229 $time = time_end($time);
4230 }
4231 }
4232
4233 if ($post['only_marked'] && !$is_sel) {
4234 error('No queries marked');
4235 }
4236
4237?>
4238<?php layout_start(($db_name_h1?$db_name_h1:$db_name).' > Execute SQL'); ?>
4239 <?php if ($get['popup']): ?>
4240 <h1><span style="<?php echo $db_name_style;?>"><?php echo $db_name_h1?$db_name_h1:$db_name;?></span> > Execute SQL</h1>
4241 <?php else: ?>
4242 <h1><a class=blue style="<?php echo $db_name_style;?>" href="<?php echo $_SERVER['PHP_SELF'];?>"><?php echo $db_name_h1?$db_name_h1:$db_name;?></a> > Execute SQL</h1>
4243 <?php endif; ?>
4244
4245 <?php echo error();?>
4246
4247 <script>
4248 function sql_submit(form)
4249 {
4250 if (form.perform.value.length) {
4251 return true;
4252 }
4253 return false;
4254 }
4255 function sql_execute(form)
4256 {
4257 form.perform.value='execute';
4258 form.submit();
4259 }
4260 function sql_preview(form)
4261 {
4262 form.perform.value='preview';
4263 form.submit();
4264 }
4265 function sql_save(form)
4266 {
4267 form.perform.value='save';
4268 form.submit();
4269 }
4270 function sql_load(form)
4271 {
4272 if (form.load_from.selectedIndex)
4273 {
4274 form.perform.value='load';
4275 form.submit();
4276 return true;
4277 }
4278 button_clear(form);
4279 return false;
4280 }
4281 </script>
4282
4283 <?php if ($msg): ?>
4284 <div class="msg"><?php echo $msg;?></div>
4285 <?php endif; ?>
4286
4287 <?php echo $top_html;?>
4288
4289 <?php if (count($sql_assoc)): ?>
4290 <p>
4291 SELECT queries:
4292 <select name="sql_assoc" onchange="if (this.value.length) location=this.value">
4293 <option value="<?php echo html_once($sql_main_url);?>"></option>
4294 <?php echo options($sql_assoc, $sql_selected);?>
4295 </select>
4296 </p>
4297 <?php endif; ?>
4298
4299 <?php if ($get['md5']): ?>
4300 <?php echo $data_html;?>
4301 <?php endif; ?>
4302
4303 <form action="<?php echo $_SERVER['PHP_SELF'];?>?execute_sql=1&popup=<?php echo $get['popup'];?>" method="post" onsubmit="return sql_submit(this);" style="margin-top: 1em;">
4304 <input type="hidden" name="perform" value="">
4305 <div style="margin-bottom: 0.25em;">
4306 <textarea id="sql_area" name="sql" class="sql_area"><?php echo htmlspecialchars(query_upper($post['sql']));?></textarea>
4307 </div>
4308 <table cellspacing="0" cellpadding="0"><tr>
4309 <td nowrap>
4310 <input type="button" wait="1" class="button" value="Execute" onclick="sql_execute(this.form); ">
4311 </td>
4312 <td nowrap>
4313
4314 <input type="button" wait="1" class="button" value="Preview" onclick="sql_preview(this.form); ">
4315 </td>
4316 <td nowrap>
4317
4318 <input type="checkbox" name="only_marked" id="only_marked" value="1" <?php echo checked($post['only_marked'] || $get['only_marked']);?>>
4319 </td>
4320 <td nowrap>
4321 <label for="only_marked">only marked</label>
4322 </td>
4323 <td nowrap>
4324
4325 <input type="checkbox" name="only_select" id="only_select" value="1" <?php echo checked($post['only_select'] || $get['only_select']);?>>
4326 </td>
4327 <td nowrap>
4328 <label for="only_select">only SELECT</label>
4329
4330 </td>
4331 <td nowrap>
4332 <input type="text" name="save_as" value="<?php echo html_once($post['save_as']);?>">
4333
4334 </td>
4335 <td nowrap>
4336 <input type="button" wait="1" class="button" value="Save" onclick="sql_save(this.form); ">
4337
4338 </td>
4339 <td nowrap>
4340 <select name="load_from" style="width: 140px;"><option value=""></option><?php echo options($load_assoc);?></select>
4341
4342 </td>
4343 <td nowrap>
4344 <input type="button" wait="1" class="button" value="Load" onclick="return sql_load(this.form);">
4345 </td>
4346 </tr></table>
4347 </form>
4348
4349 <?php
4350
4351 if ('preview' == $post['perform'])
4352 {
4353 echo '<h2>Preview</h2>';
4354 $i = 0;
4355 foreach ($queries as $query)
4356 {
4357 $i++;
4358 $query = str_cut_start($query, '@');
4359 $query = html_once($query);
4360 $query = query_color($query);
4361 $query = nl2br($query);
4362 $query = html_spaces($query);
4363 printf('<div class="query"><b style="font-size: 10px;">Query %s</b>:<div style="'.$sql_font.' margin-top: 0.35em;">%s</div></div>', $i, $query);
4364 }
4365 }
4366
4367 ?>
4368
4369 <?php if (!$get['md5']): ?>
4370 <script>$('sql_area').focus();</script>
4371 <?php echo $data_html;?>
4372 <?php endif; ?>
4373
4374 <?php layout_end(); ?>
4375
4376<?php exit; endif; ?>
4377<?php if (isset($_GET['viewtable']) && $_GET['viewtable']): ?>
4378
4379 <?php
4380
4381 set_time_limit(0);
4382
4383 // ----------------------------------------------------------------
4384 // VIEW TABLE
4385 // ----------------------------------------------------------------
4386
4387 $table = $_GET['viewtable'];
4388 $table_enq = quote_table($table);
4389 $count = db_one("SELECT COUNT(*) FROM $table_enq");
4390
4391 $types = table_types2($table);
4392 $columns = table_columns($table);
4393 if (!count($columns)) {
4394 $columns = array_assoc(array_keys($types));
4395 }
4396 $columns2 = $columns;
4397
4398 foreach ($columns2 as $k => $v) {
4399 $columns2[$k] = $v.' ('.$types[$k].')';
4400 }
4401 $types_group = table_types_group($types);
4402 $_GET['search'] = get('search');
4403
4404 $where = '';
4405 $found = $count;
4406 if ($_GET['search']) {
4407 $search = $_GET['search'];
4408 $cols2 = array();
4409
4410 if (get('column')) {
4411 $cols2[] = $_GET['column'];
4412 } else {
4413 $cols2 = $columns;
4414 }
4415 $where = '';
4416 $search = db_escape($search);
4417
4418 $column_type = '';
4419 if (!get('column')) {
4420 $column_type = get('column_type');
4421 } else {
4422 $_GET['column_type'] = '';
4423 }
4424
4425 $ignore_int = false;
4426 $ignore_time = false;
4427
4428 foreach ($columns as $col)
4429 {
4430 if (!get('column') && $column_type) {
4431 if ($types[$col] != $column_type) {
4432 continue;
4433 }
4434 }
4435 if (!$column_type && !is_numeric($search) && str_has($types[$col], 'int')) {
4436 $ignore_int = true;
4437 continue;
4438 }
4439 if (!$column_type && is_numeric($search) && str_has($types[$col], 'time')) {
4440 $ignore_time = true;
4441 continue;
4442 }
4443 if (get('column') && $col != $_GET['column']) {
4444 continue;
4445 }
4446 if ($where) { $where .= ' OR '; }
4447 if (is_numeric($search)) {
4448 $where .= "$col = '$search'";
4449 } else {
4450 if ('mysql' == $db_driver) {
4451 $where .= "$col LIKE '%$search%'";
4452 } else if ('pgsql' == $db_driver) {
4453 $where .= "$col ILIKE '%$search%'";
4454 } else {
4455 trigger_error('db_driver not implemented');
4456 }
4457 }
4458 }
4459 if (($ignore_int || $ignore_time) && !$where) {
4460 $where .= ' 1=2 ';
4461 }
4462 $where = 'WHERE '.$where;
4463 }
4464
4465 if ($where) {
4466 $table_enq = quote_table($table);
4467 $found = db_one("SELECT COUNT(*) FROM $table_enq $where");
4468 }
4469
4470 $limit = 50;
4471 $offset = get('offset','int');
4472 $page = floor($offset / $limit + 1);
4473 $pages = ceil($found / $limit);
4474
4475 $pk = table_pk($table);
4476
4477 $order = "ORDER BY";
4478 if (get('order_by')) {
4479 $order .= ' '.$_GET['order_by'];
4480 } else {
4481 if ($pk) {
4482 if (IsTableAView($table)) {
4483 $order = '';
4484 } else {
4485 $order .= ' '.$pk;
4486 }
4487 } else {
4488 $order = '';
4489 }
4490 }
4491 if (get('order_desc')) { $order .= ' DESC'; }
4492
4493 $table_enq = quote_table($table);
4494 $base_query = "SELECT * FROM $table_enq $where $order";
4495 $rs = db_query(db_limit($base_query, $offset, $limit));
4496
4497 if ($count && $rs) {
4498 $rows = array();
4499 while ($row = db_row($rs)) {
4500 $rows[] = $row;
4501 }
4502 db_free($rs);
4503 if (count($rows) && !array_col_match_unique($rows, $pk, '#^\d+$#')) {
4504 $pk = guess_pk($rows);
4505 }
4506 }
4507
4508 function indenthead($str)
4509 {
4510 if (is_array($str)) {
4511 $str2 = '';
4512 foreach ($str as $k => $v) {
4513 $str2 .= sprintf('%s: %s'."\r\n", $k, $v);
4514 }
4515 $str = $str2;
4516 }
4517 $lines = explode("\n", $str);
4518 $max_len = 0;
4519 foreach ($lines as $k => $line) {
4520 $lines[$k] = trim($line);
4521 if (preg_match('#^[^:]+:#', $line, $match)) {
4522 if ($max_len < strlen($match[0])) {
4523 $max_len = strlen($match[0]);
4524 }
4525 }
4526 }
4527 foreach ($lines as $k => $line) {
4528 if (preg_match('#^[^:]+:#', $line, $match)) {
4529 $lines[$k] = str_replace($match[0], $match[0].str_repeat(' ', $max_len - strlen($match[0])), $line);
4530 }
4531 }
4532 return implode("\r\n", $lines);
4533 }
4534
4535 if (get('indenthead')) {
4536 echo '<pre>';
4537 echo 'Table: '.get('viewtable')."\r\n";
4538 echo str_repeat('-', 80)."\r\n";
4539 foreach ($rows as $row) {
4540 echo indenthead($row);
4541 echo str_repeat('-', 80)."\r\n";
4542 }
4543 echo '</pre>';
4544 exit;
4545 }
4546 ?>
4547
4548<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4549<html>
4550<head>
4551 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $page_charset;?>">
4552 <title><?php echo $db_name_h1?$db_name_h1:$db_name;?> > Table: <?php echo $table;?></title>
4553 <link rel="shortcut icon" href="<?php echo $_SERVER['PHP_SELF']; ?>?dbkiss_favicon=1">
4554</head>
4555<body>
4556
4557 <?php layout(); ?>
4558
4559 <h1><a class=blue style="<?php echo $db_name_style;?>" href="<?php echo $_SERVER['PHP_SELF'];?>"><?php echo $db_name_h1?$db_name_h1:$db_name;?></a> > Table: <?php echo $table;?></h1>
4560
4561 <?php conn_info(); ?>
4562
4563 <p>
4564 <a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>">All tables</a>
4565 >
4566 <a href="<?php echo $_SERVER['PHP_SELF'];?>?viewtable=<?php echo $table;?>"><b><?php echo $table;?></b></a> (<?php echo $count;?>)
4567 /
4568
4569 Export to CSV:
4570
4571 <a href="<?php echo $_SERVER['PHP_SELF']; ?>?export=csv&separator=<?php echo urlencode('|');?>&query=<?php echo base64_encode($base_query); ?>">pipe</a>
4572 -
4573 <a href="<?php echo $_SERVER['PHP_SELF']; ?>?export=csv&separator=<?php echo urlencode("\t");?>&query=<?php echo base64_encode($base_query); ?>">tab</a>
4574 -
4575 <a href="<?php echo $_SERVER['PHP_SELF']; ?>?export=csv&separator=<?php echo urlencode(',');?>&query=<?php echo base64_encode($base_query); ?>">comma</a>
4576 -
4577 <a href="<?php echo $_SERVER['PHP_SELF']; ?>?export=csv&separator=<?php echo urlencode(';');?>&query=<?php echo base64_encode($base_query); ?>">semicolon</a>
4578
4579 /
4580 Functions:
4581 <a href="<?php echo $_SERVER['PHP_SELF'];?>?viewtable=<?php echo $table;?>&indenthead=1">indenthead()</a>
4582 </p>
4583
4584 <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="get" style="margin-bottom: 1em;">
4585 <input type="hidden" name="viewtable" value="<?php echo $table;?>">
4586 <table class="ls" cellspacing="1">
4587 <tr>
4588 <td><input type="text" name="search" value="<?php echo html_once(get('search'));?>"></td>
4589 <td><select name="column"><option value=""></option><?php echo options($columns2, get('column'));?></select></td>
4590 <td><select name="column_type"><option value=""></option><?php echo options($types_group, get('column_type'));?></select></td>
4591 <td><input type="submit" value="Search"></td>
4592 <td>
4593 order by:
4594 <select name="order_by"><option value=""></option><?php echo options($columns, get('order_by'));?></select>
4595 <input type="checkbox" name="order_desc" id="order_desc" value="1" <?php echo checked(get('order_desc'));?>>
4596 <label for="order_desc">desc</label>
4597 </td>
4598 <td>
4599 <input type="checkbox" name="full_content" id="full_content" <?php echo checked(get('full_content'));?>>
4600 <label for="full_content">full content</label>
4601 </td>
4602 <td>
4603 <input type="checkbox" name="nl2br" id="nl2br" <?php echo checked(get('nl2br'));?>>
4604 <label for="nl2br">nl2br</label>
4605 </td>
4606 </tr>
4607 </table>
4608 </form>
4609
4610 <?php if ($count): ?>
4611
4612 <?php if ($count && $count != $found): ?>
4613 <p>Found: <b><?php echo $found;?></b></p>
4614 <?php endif; ?>
4615
4616 <?php if ($found): ?>
4617
4618 <?php if ($pages > 1): ?>
4619 <p>
4620 <?php if ($page > 1): ?>
4621 <a href="<?php echo url_offset(($page-1)*$limit-$limit);?>"><< Prev</a>
4622 <?php endif; ?>
4623 Page <b><?php echo $page;?></b> of <b><?php echo $pages;?></b>
4624 <?php if ($pages > $page): ?>
4625 <a href="<?php echo url_offset($page*$limit);?>">Next >></a>
4626 <?php endif; ?>
4627 </p>
4628 <?php endif; ?>
4629
4630 <script>
4631 function mark_row(tr)
4632 {
4633 var els = tr.getElementsByTagName('td');
4634 if (tr.marked) {
4635 for (var i = 0; i < els.length; i++) {
4636 els[i].style.backgroundColor = '';
4637 }
4638 tr.marked = false;
4639 } else {
4640 tr.marked = true;
4641 for (var i = 0; i < els.length; i++) {
4642 els[i].style.backgroundColor = '#ddd';
4643 }
4644 }
4645 }
4646 </script>
4647
4648 <table class="ls" cellspacing="1">
4649 <tr>
4650 <?php if ($pk): ?><th>#</th><?php endif; ?>
4651 <?php foreach ($columns as $col): ?>
4652 <?php
4653 $params = array('order_by'=>$col);
4654 $params['order_desc'] = 0;
4655 if (get('order_by') == $col) {
4656 $params['order_desc'] = get('order_desc') ? 0 : 1;
4657 }
4658 ?>
4659 <th><a style="color: #000;" href="<?php echo url(self(), $params);?>"><?php echo $col;?></a></th>
4660 <?php endforeach; ?>
4661 </tr>
4662 <?php
4663 $get_full_content = get('full_content');
4664 $get_nl2br = get('nl2br');
4665 $get_search = get('search');
4666 ?>
4667 <?php
4668 $edit_url_tpl = url(self(true), array('action'=>'editrow', 'table'=>$table, 'pk'=>$pk, 'id'=>'%s'));
4669 ?>
4670 <?php foreach ($rows as $row): ?>
4671 <tr ondblclick="mark_row(this)">
4672 <?php if ($pk): ?>
4673 <?php $edit_url = sprintf($edit_url_tpl, $row[$pk]); ?>
4674 <td><a href="javascript:void(0)" onclick="popup('<?php echo $edit_url;?>', 620, 500)">Edit</a> </td>
4675 <?php endif; ?>
4676 <?php foreach ($row as $k => $v): ?>
4677 <?php
4678 $v = strip_tags($v);
4679 $v = create_links($v);
4680 if (!$get_full_content) {
4681 $v = truncate_html($v, 50);
4682 }
4683 //$v = html_once($v);
4684 //$v = htmlspecialchars($v); -- create_links() disabling
4685 $nl2br = $get_nl2br;
4686 if ($get_full_content) {
4687 $v = str_wrap($v, 80, '<br>', true);
4688 }
4689 if ($get_nl2br) {
4690 $v = nl2br($v);
4691 }
4692 //$v = stripslashes(stripslashes($v));
4693 if ($get_search) {
4694 $search = $_GET['search'];
4695 $search_quote = preg_quote($search);
4696 $v = preg_replace('#('.$search_quote.')#i', '<span style="background: yellow;">$1</span>', $v);
4697 }
4698 if ($types[$k] == 'int' && (preg_match('#time#i', $k) || preg_match('#date#i', $k))
4699 && preg_match('#^\d+$#', $v))
4700 {
4701 $tmp = @date('Y-m-d H:i', $v);
4702 if ($tmp) {
4703 $v = $tmp;
4704 }
4705 }
4706 ?>
4707 <td onclick="mark_col(this)" <?php echo $nl2br?'valign="top"':'';?> nowrap><?php echo is_null($row[$k])?'-':$v;?></td>
4708 <?php endforeach; ?>
4709 </tr>
4710 <?php endforeach; ?>
4711 </table>
4712
4713 <?php if ($pages > 1): ?>
4714 <p>
4715 <?php if ($page > 1): ?>
4716 <a href="<?php echo url_offset(($page-1)*$limit-$limit);?>"><< Prev</a>
4717 <?php endif; ?>
4718 Page <b><?php echo $page;?></b> of <b><?php echo $pages;?></b>
4719 <?php if ($pages > $page): ?>
4720 <a href="<?php echo url_offset($page*$limit);?>">Next >></a>
4721 <?php endif; ?>
4722 </p>
4723 <?php endif; ?>
4724
4725 <?php endif; ?>
4726
4727 <?php endif; ?>
4728
4729<?php powered_by(); ?>
4730</body>
4731</html>
4732<?php exit; endif; ?>
4733<?php if (get('searchdb')): ?>
4734<?php
4735
4736 // ----------------------------------------------------------------
4737 // SEARCH DB
4738 // ----------------------------------------------------------------
4739
4740 $get = get(array(
4741 'types' => 'array',
4742 'search' => 'string',
4743 'md5' => 'bool',
4744 'table_filter' => 'string'
4745 ));
4746 $get['search'] = trim($get['search']);
4747
4748 $tables = list_tables();
4749
4750 if ($get['table_filter']) {
4751 foreach ($tables as $k => $table) {
4752 if (!str_has_any($table, $get['table_filter'], $ignore_case = true)) {
4753 unset($tables[$k]);
4754 }
4755 }
4756 }
4757
4758 $all_types = array();
4759 $columns = array();
4760 foreach ($tables as $table) {
4761 $types = table_types2($table);
4762 $columns[$table] = $types;
4763 $types = array_values($types);
4764 $all_types = array_merge($all_types, $types);
4765 }
4766 $all_types = array_unique($all_types);
4767
4768 if ($get['search'] && $get['md5']) {
4769 $get['search'] = md5($get['search']);
4770 }
4771
4772?>
4773<?php layout_start(sprintf('%s > Search', $db_name)); ?>
4774 <h1><a class=blue style="<?php echo $db_name_style;?>" href="<?php echo $_SERVER['PHP_SELF'];?>"><?php echo $db_name_h1?$db_name_h1:$db_name;?></a> > Search</h1>
4775 <?php conn_info(); ?>
4776
4777 <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="get">
4778 <input type="hidden" name="searchdb" value="1">
4779 <table class="ls" cellspacing="1">
4780 <tr>
4781 <th>Search:</th>
4782 <td>
4783 <input type="text" name="search" value="<?php echo html_once($get['search']);?>" size="40">
4784 <?php if ($get['search'] && $get['md5']): ?>
4785 md5(<?php echo html_once(get('search'));?>)
4786 <?php endif; ?>
4787 <input type="checkbox" name="md5" id="md5_label" value="1">
4788 <label for="md5_label">md5</label>
4789 </td>
4790 </tr>
4791 <tr>
4792 <th>Table filter:</th>
4793 <td><input type="text" name="table_filter" value="<?php echo html_once($get['table_filter']);?>">
4794 </tr>
4795 <tr>
4796 <th>Columns:</th>
4797 <td>
4798 <?php foreach ($all_types as $type): ?>
4799 <input type="checkbox" id="type_<?php echo $type;?>" name="types[<?php echo $type;?>]" value="1" <?php echo checked(isset($get['types'][$type]));?>>
4800 <label for="type_<?php echo $type;?>"><?php echo $type;?></label>
4801 <?php endforeach; ?>
4802 </td>
4803 </tr>
4804 <tr>
4805 <td colspan="2" class="none">
4806 <input type="submit" value="Search">
4807 </td>
4808 </tr>
4809 </table>
4810 </form>
4811
4812 <?php if ($get['search'] && !count($get['types'])): ?>
4813 <p>No columns selected.</p>
4814 <?php endif; ?>
4815
4816 <?php if ($get['search'] && count($get['types'])): ?>
4817
4818 <p>Searching <b><?php echo count($tables);?></b> tables for: <b><?php echo html_once($get['search']);?></b></p>
4819
4820 <?php $found_any = false; ?>
4821
4822 <?php set_time_limit(0); ?>
4823
4824 <?php foreach ($tables as $table): ?>
4825 <?php
4826
4827 $where = '';
4828 $cols2 = array();
4829
4830 $where = '';
4831 $search = db_escape($get['search']);
4832
4833 foreach ($columns[$table] as $col => $type)
4834 {
4835 if (!in_array($type, array_keys($get['types']))) {
4836 continue;
4837 }
4838 if ($where) {
4839 $where .= ' OR ';
4840 }
4841 if (is_numeric($search)) {
4842 $where .= "$col = '$search'";
4843 } else {
4844 if ('mysql' == $db_driver) {
4845 $where .= "$col LIKE '%$search%'";
4846 } else if ('pgsql' == $db_driver) {
4847 $where .= "$col ILIKE '%$search%'";
4848 } else {
4849 trigger_error('db_driver not implemented');
4850 }
4851 }
4852 }
4853
4854 $found = false;
4855
4856 if ($where) {
4857 $where = 'WHERE '.$where;
4858 $table_enq = quote_table($table);
4859 $found = db_one("SELECT COUNT(*) FROM $table_enq $where");
4860 }
4861
4862 if ($found) {
4863 $found_any = true;
4864 }
4865
4866 ?>
4867
4868 <?php
4869 if ($where && $found) {
4870 $limit = 10;
4871 $offset = 0;
4872 $pk = table_pk($table);
4873
4874 $order = "ORDER BY $pk";
4875 $table_enq = quote_table($table);
4876 $rs = db_query(db_limit("SELECT * FROM $table_enq $where $order", $offset, $limit));
4877
4878 $rows = array();
4879 while ($row = db_row($rs)) {
4880 $rows[] = $row;
4881 }
4882 db_free($rs);
4883 if (count($rows) && !array_col_match_unique($rows, $pk, '#^\d+$#')) {
4884 $pk = guess_pk($rows);
4885 }
4886 }
4887 ?>
4888
4889 <?php if ($where && $found): ?>
4890
4891 <p>
4892 Table: <a href="<?php echo $_SERVER['PHP_SELF'];?>?viewtable=<?php echo $table;?>&search=<?php echo urlencode($get['search']);?>"><b><?php echo $table;?></b></a><br>
4893 Found: <b><?php echo $found;?></b>
4894 <?php if ($found > $limit): ?>
4895 <a href="<?php echo $_SERVER['PHP_SELF'];?>?viewtable=<?php echo $table;?>&search=<?php echo urlencode($get['search']);?>">show all >></a>
4896 <?php endif; ?>
4897 </p>
4898
4899 <table class="ls" cellspacing="1">
4900 <tr>
4901 <?php if ($pk): ?><th>#</th><?php endif; ?>
4902 <?php foreach ($columns[$table] as $col => $type): ?>
4903 <th><?php echo $col;?></th>
4904 <?php endforeach; ?>
4905 </tr>
4906 <?php foreach ($rows as $row): ?>
4907 <tr>
4908 <?php if ($pk): ?>
4909 <?php $edit_url = url(self(true), array('action'=>'editrow', 'table'=>$table, 'pk'=>$pk, 'id'=>$row[$pk])); ?>
4910 <td><a href="javascript:void(0)" onclick="popup('<?php echo $edit_url;?>', 620, 500)">Edit</a> </td>
4911 <?php endif; ?>
4912 <?php foreach ($row as $k => $v): ?>
4913 <?php
4914 $v = str_truncate($v, 50);
4915 $v = html_once($v);
4916 //$v = stripslashes(stripslashes($v));
4917 $search = $get['search'];
4918 $search_quote = preg_quote($search);
4919 if ($columns[$table][$k] == 'int' && (preg_match('#time#i', $k) || preg_match('#date#i', $k)) && preg_match('#^\d+$#', $v)) {
4920 $tmp = @date('Y-m-d H:i', $v);
4921 if ($tmp) {
4922 $v = $tmp;
4923 }
4924 }
4925 $v = preg_replace('#('.$search_quote.')#i', '<span style="background: yellow;">$1</span>', $v);
4926 ?>
4927 <td nowrap><?php echo $v;?></td>
4928 <?php endforeach; ?>
4929 </tr>
4930 <?php endforeach; ?>
4931 </table>
4932
4933 <?php endif; ?>
4934
4935 <?php endforeach; ?>
4936
4937 <?php if (!$found_any): ?>
4938 <p>No rows found.</p>
4939 <?php endif; ?>
4940
4941 <?php endif; ?>
4942
4943 <?php layout_end(); ?>
4944<?php exit; endif; ?>
4945
4946<?php
4947
4948// ----------------------------------------------------------------
4949// LIST TABLES
4950// ----------------------------------------------------------------
4951
4952$get = get(array('table_filter'=>'string'));
4953
4954?>
4955
4956<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4957<html>
4958<head>
4959 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $page_charset;?>">
4960 <title><?php echo $db_name_h1?$db_name_h1:$db_name;?></title>
4961 <link rel="shortcut icon" href="<?php echo $_SERVER['PHP_SELF']; ?>?dbkiss_favicon=1">
4962</head>
4963<body>
4964
4965<?php layout(); ?>
4966<h1 style="<?php echo $db_name_style;?>"><?php echo $db_name_h1?$db_name_h1:$db_name;?></h1>
4967
4968<?php conn_info(); ?>
4969
4970<?php $tables = list_tables(); ?>
4971<?php $status = table_status(); ?>
4972<?php $views = list_tables(true); ?>
4973
4974<p>
4975 Tables: <b><?php echo count($tables);?></b>
4976 -
4977 Total size: <b><?php echo number_format(ceil($status['total_size']/1024),0,'',',').' KB';?></b>
4978 -
4979 Views: <b><?php echo count($views);?></b>
4980 -
4981
4982 <a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>?searchdb=1&table_filter=<?php echo html_once($get['table_filter']);?>">Search</a>
4983 -
4984 <a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>?import=1">Import</a>
4985 -
4986 Export all:
4987
4988 <?php if ('pgsql' == $db_driver): ?>
4989 <a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>?dump_all=2&table_filter=<?php echo urlencode(html_once($get['table_filter']));?>">Data only</a>
4990 <?php else: ?>
4991 <a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>?dump_all=1&table_filter=<?php echo urlencode(html_once($get['table_filter']));?>">Structure</a> ,
4992 <a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>?dump_all=2&table_filter=<?php echo urlencode(html_once($get['table_filter']));?>">Data & structure</a>
4993 <?php endif; ?>
4994</p>
4995
4996<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="get" name=table_filter_form style="margin-bottom: 0.5em;">
4997<table cellspacing="0" cellpadding="0"><tr>
4998<td style="padding-right: 3px;">Table or View:</td>
4999<td style="padding-right: 3px;"><input type="text" name="table_filter" id=table_filter value="<?php echo html_once($get['table_filter']);?>"></td>
5000<td style="padding-right: 3px;"><input type="submit" class="button" wait="1" value="Filter"> <a href="javascript:void(0)" onclick="alert('You just start typing on the page and the Input will be focused automatically. ALT+R will Reset the Input and submit the form.')">[?]</a></td>
5001</tr></table>
5002</form>
5003
5004<script>
5005function table_filter_keydown(e)
5006{
5007 if (!e) { e = window.event; }
5008 if (e.keyCode == 27 || e.keyCode == 33 || e.keyCode == 34 || e.keyCode == 38 || e.keyCode == 40) {
5009 document.getElementById('table_filter').blur();
5010 return;
5011 }
5012 // alt + r - reset filter input
5013 if (e.keyCode == 82 && e.altKey) {
5014 document.getElementById('table_filter').value = "";
5015 document.forms["table_filter_form"].submit();
5016 return;
5017 }
5018 // 0-9
5019 if (e.keyCode >= 48 && e.keyCode <= 57 && !e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey) {
5020 document.getElementById('table_filter').focus();
5021 }
5022 // a-z
5023 if (e.keyCode >= 65 && e.keyCode <= 90 && !e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey) {
5024 document.getElementById('table_filter').focus();
5025 }
5026}
5027document.onkeydown = table_filter_keydown;
5028</script>
5029
5030<div style="float: left;">
5031
5032 <?php
5033 $tables = table_filter($tables, $get['table_filter']);
5034 ?>
5035
5036 <?php if ($get['table_filter']): ?>
5037 <p>Tables found: <b><?php echo count($tables);?></b></p>
5038 <?php endif; ?>
5039
5040 <table class="ls" cellspacing="1">
5041 <tr>
5042 <th>Table</th>
5043 <th>Count</th>
5044 <th>Size</th>
5045 <th>Options</th>
5046 </tr>
5047 <?php foreach ($tables as $table): ?>
5048 <tr>
5049 <td><a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>?viewtable=<?php echo $table;?>"><?php echo $table;?></a></td>
5050 <?php
5051 if ('mysql' == $db_driver) {
5052 // $table_enq = quote_table($table);
5053 // $count = db_one("SELECT COUNT(*) FROM $table_enq");
5054 $count = $status[$table]['count'];
5055 }
5056 if ('pgsql' == $db_driver) {
5057 $count = $status[$table]['count'];
5058 if (!$count) {
5059 $table_enq = quote_table($table);
5060 $count = db_one("SELECT COUNT(*) FROM $table_enq");
5061 }
5062 }
5063 ?>
5064 <td align="right"><?php echo number_format($count,0,'',',');?></td>
5065 <td align="right"><?php echo number_format(ceil($status[$table]['size']/1024),0,'',',').' KB';?></td>
5066 <td>
5067 <a href="<?php echo $_SERVER['PHP_SELF'];?>?dump_table=<?php echo $table;?>">Export</a>
5068 -
5069 <?php $table_enq = quote_table($table); ?>
5070 <form action="<?php echo $_SERVER['PHP_SELF'];?>" name="drop_<?php echo $table;?>" method="post" style="display: inline;"><input type="hidden" name="drop_table" value="<?php echo $table;?>"></form>
5071 <a href="javascript:void(0)" onclick="if (confirm('DROP TABLE <?php echo $table;?> ?')) document.forms['drop_<?php echo $table;?>'].submit();">Drop</a>
5072 </td>
5073 </tr>
5074 <?php endforeach; ?>
5075 </table>
5076 <?php unset($table); ?>
5077
5078</div>
5079
5080<?php if (views_supported() && count($views)): ?>
5081<div style="float: left; margin-left: 2em;">
5082
5083 <?php
5084 $views = table_filter($views, $get['table_filter']);
5085 ?>
5086
5087 <?php if ($get['table_filter']): ?>
5088 <p>Views found: <b><?php echo count($views);?></b></p>
5089 <?php endif; ?>
5090
5091 <table class="ls" cellspacing="1">
5092 <tr>
5093 <th>View</th>
5094 <th><a class=blue href="<?php echo $_SERVER['PHP_SELF']; ?>?table_filter=<?php echo urlencode($get['table_filter']);?>&views_count=<?php echo (isset($_GET['views_count']) && $_GET['views_count']) ? 0 : 1; ?>" style="color: #000; text-decoration: underline;" title="Click to enable/disable counting in Views">Count</a></th>
5095 <th>Options</th>
5096 </tr>
5097 <?php foreach ($views as $view): ?>
5098 <?php $view_enq = quote_table($view); ?>
5099 <tr>
5100 <td><a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>?viewtable=<?php echo $view;?>"><?php echo $view;?></a></td>
5101 <?php
5102 if (isset($_GET['views_count']) && $_GET['views_count']) {
5103 $count = db_one("SELECT COUNT(*) FROM $view_enq");
5104 } else {
5105 $count = null;
5106 }
5107 ?>
5108 <td align=right><?php echo isset($count) ? $count : '-'; ?></td>
5109 <td>
5110 <a href="<?php echo $_SERVER['PHP_SELF'];?>?dump_table=<?php echo $view;?>">Export</a>
5111 -
5112 <form action="<?php echo $_SERVER['PHP_SELF'];?>" name="drop_<?php echo $view;?>" method="post" style="display: inline;">
5113 <input type="hidden" name="drop_view" value="<?php echo $view;?>"></form>
5114 <a href="javascript:void(0)" onclick="if (confirm('DROP VIEW <?php echo $view;?> ?')) document.forms['drop_<?php echo $view;?>'].submit();">Drop</a>
5115 </td>
5116 </tr>
5117 <?php endforeach; ?>
5118 </table>
5119
5120</div>
5121<?php endif; ?>
5122
5123<div style="clear: both;"></div>
5124
5125<?php powered_by(); ?>
5126</body>
5127</html>