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> | |
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).' '.substr($string, $i+1); | |
1779 | $i += strlen(' ')-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"><< 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"><< 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 | - | |
2306 | Server: <b><?php echo $db_server;?></b> | |
2307 | - | |
2308 | User: <b><?php echo $db_user;?></b> | |
2309 | - | |
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 | - | |
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 | - | |
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 | - | |
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 | - | |
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 | '&' => '&', | |
2333 | '<' => '<', | |
2334 | '>' => '>', | |
2335 | '"' => '"', | |
2336 | '\'' => ''' | |
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 | '&' => '&', | |
2347 | '<' => '<', | |
2348 | '>' => '>', | |
2349 | '"' => '"', | |
2350 | '\'' => ''' | |
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;'),array('<','>','<','>'),$s); | |
2357 | return str_replace(array('<','>','<','>'),array('&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('<','>','<','>'), array('&lt;','&gt;','<','>'), $s); | |
2363 | } | |
2364 | function html_tags_undo($s) | |
2365 | { | |
2366 | return str_replace(array('<','>','&lt;', '&gt;'), array('<','>','<','>'), $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('#<'.$tag.'\s+style\s*=\s*"([^"<>]+)"\s*>#i', '<'.$tag.' style="$1">', $s); | |
2374 | $s = str_replace('<'.$tag.'>', '<'.$tag.'>', $s); | |
2375 | $s = str_replace('</'.$tag.'>', '</'.$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% </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> </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> </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> </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;?> > 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> > 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 = ' > '.$get['table'].' > '.$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: | |
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);?>"><< Prev</a> | |
3817 | <?php endif; ?> | |
3818 | Page <b><?php echo $page;?></b> of <b><?php echo $pages;?></b> | |
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 >></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> </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(' ', ' ', $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);?>"><< Prev</a> | |
3954 | <?php endif; ?> | |
3955 | Page <b><?php echo $page;?></b> of <b><?php echo $pages;?></b> | |
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 >></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).' > 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> > 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> > 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 | | |
4314 | <input type="button" wait="1" class="button" value="Preview" onclick="sql_preview(this.form); "> | |
4315 | </td> | |
4316 | <td nowrap> | |
4317 | | |
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 | | |
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 | | |
4330 | </td> | |
4331 | <td nowrap> | |
4332 | <input type="text" name="save_as" value="<?php echo html_once($post['save_as']);?>"> | |
4333 | | |
4334 | </td> | |
4335 | <td nowrap> | |
4336 | <input type="button" wait="1" class="button" value="Save" onclick="sql_save(this.form); "> | |
4337 | | |
4338 | </td> | |
4339 | <td nowrap> | |
4340 | <select name="load_from" style="width: 140px;"><option value=""></option><?php echo options($load_assoc);?></select> | |
4341 | | |
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(' ', $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;?> > 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> > 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 | > | |
4566 | <a href="<?php echo $_SERVER['PHP_SELF'];?>?viewtable=<?php echo $table;?>"><b><?php echo $table;?></b></a> (<?php echo $count;?>) | |
4567 | / | |
4568 | ||
4569 | Export to CSV: | |
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 | / | |
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);?>"><< Prev</a> | |
4622 | <?php endif; ?> | |
4623 | Page <b><?php echo $page;?></b> of <b><?php echo $pages;?></b> | |
4624 | <?php if ($pages > $page): ?> | |
4625 | <a href="<?php echo url_offset($page*$limit);?>">Next >></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> </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);?>"><< Prev</a> | |
4717 | <?php endif; ?> | |
4718 | Page <b><?php echo $page;?></b> of <b><?php echo $pages;?></b> | |
4719 | <?php if ($pages > $page): ?> | |
4720 | <a href="<?php echo url_offset($page*$limit);?>">Next >></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 > 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> > 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 | <a href="<?php echo $_SERVER['PHP_SELF'];?>?viewtable=<?php echo $table;?>&search=<?php echo urlencode($get['search']);?>">show all >></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> </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 | - | |
4977 | Total size: <b><?php echo number_format(ceil($status['total_size']/1024),0,'',',').' KB';?></b> | |
4978 | - | |
4979 | Views: <b><?php echo count($views);?></b> | |
4980 | - | |
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 | - | |
4984 | <a class=blue href="<?php echo $_SERVER['PHP_SELF'];?>?import=1">Import</a> | |
4985 | - | |
4986 | Export all: | |
4987 | ||
4988 | <?php if ('pgsql' == $db_driver): ?> | |
4989 | <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 | <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 | - | |
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 | - | |
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> |