Guest User

Untitled

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