PageRenderTime 49ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/backoffice/connection/ez_sql_core.php

https://bitbucket.org/jjay-kotchakorn/kpnclick
PHP | 600 lines | 359 code | 116 blank | 125 comment | 93 complexity | dbbfda850f3745594da8e8c4c369061f MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, Unlicense
  1. <?php
  2. /* * ********************************************************************
  3. * Author: Justin Vincent (jv@vip.ie)
  4. * Web...: http://justinvincent.com
  5. * Name..: ezSQL
  6. * Desc..: ezSQL Core module - database abstraction library to make
  7. * it very easy to deal with databases. ezSQLcore can not be used by
  8. * itself (it is designed for use by database specific modules).
  9. *
  10. */
  11. /* * ********************************************************************
  12. * ezSQL Constants
  13. */
  14. define('EZSQL_VERSION', '2.17');
  15. define('OBJECT', 'OBJECT', true);
  16. define('ARRAY_A', 'ARRAY_A', true);
  17. define('ARRAY_N', 'ARRAY_N', true);
  18. /* * ********************************************************************
  19. * Core class containg common functions to manipulate query result
  20. * sets once returned
  21. */
  22. class ezSQLcore {
  23. var $trace = false; // same as $debug_all
  24. var $debug_all = false; // same as $trace
  25. var $debug_called = false;
  26. var $vardump_called = false;
  27. var $show_errors = true;
  28. var $num_queries = 0;
  29. var $last_query = null;
  30. var $last_error = null;
  31. var $col_info = null;
  32. var $captured_errors = array();
  33. var $cache_dir = false;
  34. var $cache_queries = false;
  35. var $cache_inserts = false;
  36. var $use_disk_cache = false;
  37. var $cache_timeout = 24; // hours
  38. var $timers = array();
  39. var $total_query_time = 0;
  40. var $db_connect_time = 0;
  41. var $trace_log = array();
  42. var $use_trace_log = false;
  43. var $sql_log_file = false;
  44. var $do_profile = false;
  45. var $profile_times = array();
  46. // == TJH == default now needed for echo of debug function
  47. var $debug_echo_is_on = true;
  48. /* * ********************************************************************
  49. * Constructor
  50. */
  51. function ezSQLcore() {
  52. }
  53. /* * ********************************************************************
  54. * Print SQL/DB error - over-ridden by specific DB class
  55. */
  56. function register_error($err_str) {
  57. // Keep track of last error
  58. $this->last_error = $err_str;
  59. // Capture all errors to an error array no matter what happens
  60. $this->captured_errors[] = array
  61. (
  62. 'error_str' => $err_str,
  63. 'query' => $this->last_query
  64. );
  65. }
  66. /* * ********************************************************************
  67. * Turn error handling on or off..
  68. */
  69. function show_errors() {
  70. $this->show_errors = true;
  71. }
  72. function hide_errors() {
  73. $this->show_errors = false;
  74. }
  75. /* * ********************************************************************
  76. * Kill cached query results
  77. */
  78. function flush() {
  79. // Get rid of these
  80. $this->last_result = null;
  81. $this->col_info = null;
  82. $this->last_query = null;
  83. $this->from_disk_cache = false;
  84. }
  85. /* * ********************************************************************
  86. * Get one variable from the DB - see docs for more detail
  87. */
  88. function get_var($query = null, $x = 0, $y = 0) {
  89. // Log how the function was called
  90. $this->func_call = "\$db->get_var(\"$query\",$x,$y)";
  91. // If there is a query then perform it if not then use cached results..
  92. if ($query) {
  93. $this->query($query);
  94. }
  95. // Extract var out of cached results based x,y vals
  96. if ($this->last_result[$y]) {
  97. $values = array_values(get_object_vars($this->last_result[$y]));
  98. }
  99. // If there is a value return it else return null
  100. return (isset($values[$x]) && $values[$x] !== '') ? $values[$x] : null;
  101. }
  102. /* * ********************************************************************
  103. * Get one row from the DB - see docs for more detail
  104. */
  105. function get_row($query = null, $output = OBJECT, $y = 0) {
  106. // Log how the function was called
  107. $this->func_call = "\$db->get_row(\"$query\",$output,$y)";
  108. // If there is a query then perform it if not then use cached results..
  109. if ($query) {
  110. $this->query($query);
  111. }
  112. // If the output is an object then return object using the row offset..
  113. if ($output == OBJECT) {
  114. return $this->last_result[$y] ? $this->last_result[$y] : null;
  115. }
  116. // If the output is an associative array then return row as such..
  117. elseif ($output == ARRAY_A) {
  118. return $this->last_result[$y] ? get_object_vars($this->last_result[$y]) : null;
  119. }
  120. // If the output is an numerical array then return row as such..
  121. elseif ($output == ARRAY_N) {
  122. return $this->last_result[$y] ? array_values(get_object_vars($this->last_result[$y])) : null;
  123. }
  124. // If invalid output type was specified..
  125. else {
  126. $this->show_errors ? trigger_error(" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N", E_USER_WARNING) : null;
  127. }
  128. }
  129. /* * ********************************************************************
  130. * Function to get 1 column from the cached result set based in X index
  131. * see docs for usage and info
  132. */
  133. function get_col($query = null, $x = 0) {
  134. $new_array = array();
  135. // If there is a query then perform it if not then use cached results..
  136. if ($query) {
  137. $this->query($query);
  138. }
  139. // Extract the column values
  140. for ($i = 0; $i < count($this->last_result); $i++) {
  141. $new_array[$i] = $this->get_var(null, $x, $i);
  142. }
  143. return $new_array;
  144. }
  145. /* * ********************************************************************
  146. * Return the the query as a result set - see docs for more details
  147. */
  148. function get_results($query = null, $output = OBJECT) {
  149. // Log how the function was called
  150. $this->func_call = "\$db->get_results(\"$query\", $output)";
  151. // If there is a query then perform it if not then use cached results..
  152. if ($query) {
  153. $this->query($query);
  154. }
  155. // Send back array of objects. Each row is an object
  156. if ($output == OBJECT) {
  157. return $this->last_result;
  158. } elseif ($output == ARRAY_A || $output == ARRAY_N) {
  159. if ($this->last_result) {
  160. $i = 0;
  161. foreach ($this->last_result as $row) {
  162. $new_array[$i] = get_object_vars($row);
  163. if ($output == ARRAY_N) {
  164. $new_array[$i] = array_values($new_array[$i]);
  165. }
  166. $i++;
  167. }
  168. return $new_array;
  169. } else {
  170. return null;
  171. }
  172. }
  173. }
  174. /* * ********************************************************************
  175. * Function to get column meta data info pertaining to the last query
  176. * see docs for more info and usage
  177. */
  178. function get_col_info($info_type = "name", $col_offset = -1) {
  179. if ($this->col_info) {
  180. if ($col_offset == -1) {
  181. $i = 0;
  182. foreach ($this->col_info as $col) {
  183. $new_array[$i] = $col->{$info_type};
  184. $i++;
  185. }
  186. return $new_array;
  187. } else {
  188. return $this->col_info[$col_offset]->{$info_type};
  189. }
  190. }
  191. }
  192. /* * ********************************************************************
  193. * store_cache
  194. */
  195. function store_cache($query, $is_insert) {
  196. // The would be cache file for this query
  197. $cache_file = $this->cache_dir . '/' . md5($query);
  198. // disk caching of queries
  199. if ($this->use_disk_cache && ( $this->cache_queries && !$is_insert ) || ( $this->cache_inserts && $is_insert )) {
  200. if (!is_dir($this->cache_dir)) {
  201. $this->register_error("Could not open cache dir: $this->cache_dir");
  202. $this->show_errors ? trigger_error("Could not open cache dir: $this->cache_dir", E_USER_WARNING) : null;
  203. } else {
  204. // Cache all result values
  205. $result_cache = array
  206. (
  207. 'col_info' => $this->col_info,
  208. 'last_result' => $this->last_result,
  209. 'num_rows' => $this->num_rows,
  210. 'return_value' => $this->num_rows,
  211. );
  212. file_put_contents($cache_file, serialize($result_cache));
  213. if (file_exists($cache_file . ".updating"))
  214. unlink($cache_file . ".updating");
  215. }
  216. }
  217. }
  218. /* * ********************************************************************
  219. * get_cache
  220. */
  221. function get_cache($query) {
  222. // The would be cache file for this query
  223. $cache_file = $this->cache_dir . '/' . md5($query);
  224. // Try to get previously cached version
  225. if ($this->use_disk_cache && file_exists($cache_file)) {
  226. // Only use this cache file if less than 'cache_timeout' (hours)
  227. if ((time() - filemtime($cache_file)) > ($this->cache_timeout * 3600) &&
  228. !(file_exists($cache_file . ".updating") && (time() - filemtime($cache_file . ".updating") < 60))) {
  229. touch($cache_file . ".updating"); // Show that we in the process of updating the cache
  230. } else {
  231. $result_cache = unserialize(file_get_contents($cache_file));
  232. $this->col_info = $result_cache['col_info'];
  233. $this->last_result = $result_cache['last_result'];
  234. $this->num_rows = $result_cache['num_rows'];
  235. $this->from_disk_cache = true;
  236. // If debug ALL queries
  237. $this->trace || $this->debug_all ? $this->debug() : null;
  238. return $result_cache['return_value'];
  239. }
  240. }
  241. }
  242. /* * ********************************************************************
  243. * Dumps the contents of any input variable to screen in a nicely
  244. * formatted and easy to understand way - any type: Object, Var or Array
  245. */
  246. function vardump($mixed = '') {
  247. // Start outup buffering
  248. ob_start();
  249. echo "<p><table><tr><td bgcolor=ffffff><blockquote><font color=000090>";
  250. echo "<pre><font face=arial>";
  251. if (!$this->vardump_called) {
  252. echo "<font color=800080><b>ezSQL</b> (v" . EZSQL_VERSION . ") <b>Variable Dump..</b></font>\n\n";
  253. }
  254. $var_type = gettype($mixed);
  255. print_r(($mixed ? $mixed : "<font color=red>No Value / False</font>"));
  256. echo "\n\n<b>Type:</b> " . ucfirst($var_type) . "\n";
  257. echo "<b>Last Query</b> [$this->num_queries]<b>:</b> " . ($this->last_query ? $this->last_query : "NULL") . "\n";
  258. echo "<b>Last Function Call:</b> " . ($this->func_call ? $this->func_call : "None") . "\n";
  259. echo "<b>Last Rows Returned:</b> " . count($this->last_result) . "\n";
  260. echo "</font></pre></font></blockquote></td></tr></table>" . $this->donation();
  261. echo "\n<hr size=1 noshade color=dddddd>";
  262. // Stop output buffering and capture debug HTML
  263. $html = ob_get_contents();
  264. ob_end_clean();
  265. // Only echo output if it is turned on
  266. if ($this->debug_echo_is_on) {
  267. echo $html;
  268. }
  269. $this->vardump_called = true;
  270. return $html;
  271. }
  272. /* * ********************************************************************
  273. * Alias for the above function
  274. */
  275. function dumpvar($mixed) {
  276. $this->vardump($mixed);
  277. }
  278. /* * ********************************************************************
  279. * Displays the last query string that was sent to the database & a
  280. * table listing results (if there were any).
  281. * (abstracted into a seperate file to save server overhead).
  282. */
  283. function debug($print_to_screen = true) {
  284. // Start outup buffering
  285. ob_start();
  286. echo "<blockquote>";
  287. // Only show ezSQL credits once..
  288. if (!$this->debug_called) {
  289. echo "<font color=800080 face=arial size=2><b>ezSQL</b> (v" . EZSQL_VERSION . ") <b>Debug..</b></font><p>\n";
  290. }
  291. if ($this->last_error) {
  292. echo "<font face=arial size=2 color=000099><b>Last Error --</b> [<font color=000000><b>$this->last_error</b></font>]<p>";
  293. }
  294. if ($this->from_disk_cache) {
  295. echo "<font face=arial size=2 color=000099><b>Results retrieved from disk cache</b></font><p>";
  296. }
  297. echo "<font face=arial size=2 color=000099><b>Query</b> [$this->num_queries] <b>--</b> ";
  298. echo "[<font color=000000><b>$this->last_query</b></font>]</font><p>";
  299. echo "<font face=arial size=2 color=000099><b>Query Result..</b></font>";
  300. echo "<blockquote>";
  301. if ($this->col_info) {
  302. // =====================================================
  303. // Results top rows
  304. echo "<table cellpadding=5 cellspacing=1 bgcolor=555555>";
  305. echo "<tr bgcolor=eeeeee><td nowrap valign=bottom><font color=555599 face=arial size=2><b>(row)</b></font></td>";
  306. for ($i = 0; $i < count($this->col_info); $i++) {
  307. echo "<td nowrap align=left valign=top><font size=1 color=555599 face=arial>{$this->col_info[$i]->type} {$this->col_info[$i]->max_length}</font><br><span style='font-family: arial; font-size: 10pt; font-weight: bold;'>{$this->col_info[$i]->name}</span></td>";
  308. }
  309. echo "</tr>";
  310. // ======================================================
  311. // print main results
  312. if ($this->last_result) {
  313. $i = 0;
  314. foreach ($this->get_results(null, ARRAY_N) as $one_row) {
  315. $i++;
  316. echo "<tr bgcolor=ffffff><td bgcolor=eeeeee nowrap align=middle><font size=2 color=555599 face=arial>$i</font></td>";
  317. foreach ($one_row as $item) {
  318. echo "<td nowrap><font face=arial size=2>$item</font></td>";
  319. }
  320. echo "</tr>";
  321. }
  322. } // if last result
  323. else {
  324. echo "<tr bgcolor=ffffff><td colspan=" . (count($this->col_info) + 1) . "><font face=arial size=2>No Results</font></td></tr>";
  325. }
  326. echo "</table>";
  327. } // if col_info
  328. else {
  329. echo "<font face=arial size=2>No Results</font>";
  330. }
  331. echo "</blockquote></blockquote>" . $this->donation() . "<hr noshade color=dddddd size=1>";
  332. // Stop output buffering and capture debug HTML
  333. $html = ob_get_contents();
  334. ob_end_clean();
  335. // Only echo output if it is turned on
  336. if ($this->debug_echo_is_on && $print_to_screen) {
  337. echo $html;
  338. }
  339. $this->debug_called = true;
  340. return $html;
  341. }
  342. /* * ********************************************************************
  343. * Naughty little function to ask for some remuniration!
  344. */
  345. function donation() {
  346. return "<font size=1 face=arial color=000000>If ezSQL has helped <a href=\"https://www.paypal.com/xclick/business=justin%40justinvincent.com&item_name=ezSQL&no_note=1&tax=0\" style=\"color: 0000CC;\">make a donation!?</a> &nbsp;&nbsp;<!--[ go on! you know you want to! ]--></font>";
  347. }
  348. /* * ********************************************************************
  349. * Timer related functions
  350. */
  351. function timer_get_cur() {
  352. list($usec, $sec) = explode(" ", microtime());
  353. return ((float) $usec + (float) $sec);
  354. }
  355. function timer_start($timer_name) {
  356. $this->timers[$timer_name] = $this->timer_get_cur();
  357. }
  358. function timer_elapsed($timer_name) {
  359. return round($this->timer_get_cur() - $this->timers[$timer_name], 2);
  360. }
  361. function timer_update_global($timer_name) {
  362. if ($this->do_profile) {
  363. $this->profile_times[] = array
  364. (
  365. 'query' => $this->last_query,
  366. 'time' => $this->timer_elapsed($timer_name)
  367. );
  368. }
  369. $this->total_query_time += $this->timer_elapsed($timer_name);
  370. }
  371. /* * ********************************************************************
  372. * Creates a SET nvp sql string from an associative array (and escapes all values)
  373. *
  374. * Usage:
  375. *
  376. * $db_data = array('login'=>'jv','email'=>'jv@vip.ie', 'user_id' => 1, 'created' => 'NOW()');
  377. *
  378. * $db->query("INSERT INTO users SET ".$db->get_set($db_data));
  379. *
  380. * ...OR...
  381. *
  382. * $db->query("UPDATE users SET ".$db->get_set($db_data)." WHERE user_id = 1");
  383. *
  384. * Output:
  385. *
  386. * login = 'jv', email = 'jv@vip.ie', user_id = 1, created = NOW()
  387. */
  388. function get_set($parms) {
  389. $sql = '';
  390. foreach ($parms as $field => $val) {
  391. if ($val == "NULL") {
  392. $val = "NULL";
  393. } else if ($val === 'true')
  394. $val = 1;
  395. else if ($val === 'false')
  396. $val = 0;
  397. if ($val == "NULL") {
  398. $sql .= "$field = " . $this->escape($val) . ", ";
  399. } else if ($val == 'NOW()') {
  400. $sql .= "$field = " . $this->escape($val) . ", ";
  401. } else {
  402. $sql .= "$field = '" . $this->escape($val) . "', ";
  403. }
  404. }
  405. return substr($sql, 0, -2);
  406. }
  407. //function set($parms, $ckNews = false, $debug = true) {
  408. function set($parms, $ckNews = false, $debug = false) {
  409. $table = $parms["table"] ? $parms["table"] : "";
  410. unset($parms["table"]);
  411. //array('key'=>'M_ID', 'value'=>$_POST["M_ID"]);
  412. if(is_array($parms["id"])){
  413. $key_id = $parms["id"]['key'];
  414. $id = $parms["id"]['value'] ? $parms["id"]['value'] : "";
  415. }else{
  416. $id = $parms["id"] ? $parms["id"] : "";
  417. if($id) $key_id = $table."_id";
  418. }
  419. unset($parms["id"]);
  420. if (!$table)
  421. die("No Table Name");
  422. $sql = "";
  423. $list = "";
  424. if ($id) {
  425. foreach ($parms as $field => $val) {
  426. if ($val == "NULL") {
  427. $val = "NULL";
  428. } else if ($val === 'true')
  429. $val = 1;
  430. else if ($val === 'false')
  431. $val = 0;
  432. if ($val == "NULL") {
  433. $sql .= "$field = " . $this->escape($val) . ", ";
  434. } else if ($val == 'NOW()') {
  435. $sql .= "$field = " . $this->escape($val) . ", ";
  436. } else {
  437. $sql .= "$field = '" . $this->escape($val) . "', ";
  438. }
  439. if ($ckNews == true) {
  440. $list .= "$field ,";
  441. }
  442. }
  443. if ($ckNews == true) {
  444. $q = "select " . substr($list, 0, -2) . " from $table where " . $key_id. " = $id";
  445. $args_tmp = $this->get_row($q, "ARRAY_A");
  446. }
  447. $q = "UPDATE $table SET " . substr($sql, 0, -2) . " WHERE " . $key_id. " = $id";
  448. if($debug) echo $q;
  449. $r = $this->query($q);
  450. if ($r !== false && $ckNews == true) {
  451. $q = "select " . substr($list, 0, -2) . " from $table where " . $key_id . " = $id";
  452. $aR = $this->get_row($q, "ARRAY_A");
  453. foreach ($aR as $field => $value) {
  454. if ($args_tmp[$field] != $value) {
  455. $ret = true;
  456. break;
  457. }
  458. }
  459. if (!$ret)
  460. $ret = false;
  461. }
  462. }else {
  463. $q = "INSERT INTO $table SET ".$this->get_set($parms);
  464. if($debug) echo $q;
  465. $this->query($q);
  466. $ret = $this->insert_id;
  467. }
  468. return $ret;
  469. }
  470. function rows($query = "", $y = 0) {
  471. return $this->get_row($query, "ARRAY_A", $y);
  472. }
  473. function data($query = "", $x = 0, $y = 0) {
  474. return $this->get_var($query, $x, $y);
  475. }
  476. function get($query = "") {
  477. return $this->get_results($query, "ARRAY_A");
  478. }
  479. function set_update($sql) {
  480. if($debug) echo $sql;
  481. $ret = $this->query($sql);
  482. return $ret;
  483. }
  484. }