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