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