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