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