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