PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/libs/extensions/ezSQL/mysql/ez_sql_mysql.php

https://gitlab.com/fork/hotarucms
PHP | 413 lines | 236 code | 82 blank | 95 comment | 37 complexity | a5146766a2a4033cbff036d27a86c77c MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**********************************************************************
  3. * Author: Justin Vincent (jv@jvmultimedia.com)
  4. * Web...: http://twitter.com/justinvincent
  5. * Name..: ezSQL_mysql
  6. * Desc..: mySQL component (part of ezSQL databse abstraction library)
  7. *
  8. */
  9. /**********************************************************************
  10. * ezSQL error strings - mySQL
  11. */
  12. $ezsql_mysql_str = array
  13. (
  14. 1 => 'Require $dbuser and $dbpassword to connect to a database server',
  15. 2 => 'Error establishing mySQL database connection. Correct user/password? Correct hostname? Database server running?',
  16. 3 => 'Require $dbname to select a database',
  17. 4 => 'mySQL database connection is not active',
  18. 5 => 'Unexpected error while trying to select database'
  19. );
  20. /**********************************************************************
  21. * ezSQL Database specific class - mySQL
  22. */
  23. if ( ! function_exists ('mysql_connect') ) die('<b>Fatal Error:</b> ezSQL_mysql requires mySQL Lib to be compiled and or linked in to the PHP engine');
  24. if ( ! class_exists ('ezSQLcore') ) die('<b>Fatal Error:</b> ezSQL_mysql requires ezSQLcore (ez_sql_core.php) to be included/loaded before it can be used');
  25. class ezSQL_mysql extends ezSQLcore
  26. {
  27. var $dbuser = false;
  28. var $dbpassword = false;
  29. var $dbname = false;
  30. var $dbhost = false;
  31. var $encoding = false;
  32. /**********************************************************************
  33. * Constructor - allow the user to perform a qucik connect at the
  34. * same time as initialising the ezSQL_mysql class
  35. */
  36. function ezSQL_mysql($dbuser='', $dbpassword='', $dbname='', $dbhost='localhost', $encoding='')
  37. {
  38. $this->dbuser = $dbuser;
  39. $this->dbpassword = $dbpassword;
  40. $this->dbname = $dbname;
  41. $this->dbhost = $dbhost;
  42. $this->encoding = $encoding;
  43. }
  44. /**********************************************************************
  45. * Set $h - global Hotaru object
  46. */
  47. function setHotaru($h)
  48. {
  49. $this->h = $h;
  50. $h->vars['debug']['db_driver'] = 'mysql';
  51. }
  52. /**********************************************************************
  53. * Short hand way to connect to mySQL database server
  54. * and select a mySQL database at the same time
  55. */
  56. function quick_connect($dbuser='', $dbpassword='', $dbname='', $dbhost='localhost', $encoding='')
  57. {
  58. $return_val = false;
  59. if ( ! $this->connect($dbuser, $dbpassword, $dbhost,true) ) ;
  60. else if ( ! $this->selectDB($dbname,$encoding) ) ;
  61. else $return_val = true;
  62. return $return_val;
  63. }
  64. /**********************************************************************
  65. * Try to connect to mySQL database server
  66. */
  67. function connect($dbuser='', $dbpassword='', $dbhost='localhost')
  68. {
  69. global $ezsql_mysql_str; $return_val = false;
  70. // Keep track of how long the DB takes to connect
  71. $this->timer_start('db_connect_time');
  72. // Must have a user and a password
  73. if ( ! $dbuser )
  74. {
  75. $this->register_error($ezsql_mysql_str[1].' in '.__FILE__.' on line '.__LINE__);
  76. $this->show_errors ? trigger_error($ezsql_mysql_str[1],E_USER_WARNING) : null;
  77. }
  78. // Try to establish the server database handle
  79. else if ( ! $this->dbh = @mysql_connect($dbhost,$dbuser,$dbpassword,true,131074) )
  80. {
  81. $this->register_error($ezsql_mysql_str[2].' in '.__FILE__.' on line '.__LINE__);
  82. $this->show_errors ? trigger_error($ezsql_mysql_str[2],E_USER_WARNING) : null;
  83. }
  84. else
  85. {
  86. $this->dbuser = $dbuser;
  87. $this->dbpassword = $dbpassword;
  88. $this->dbhost = $dbhost;
  89. $return_val = true;
  90. }
  91. return $return_val;
  92. }
  93. /**********************************************************************
  94. * Try to select a mySQL database
  95. */
  96. function selectDB($dbname='', $encoding='')
  97. {
  98. global $ezsql_mysql_str; $return_val = false;
  99. // Must have a database name
  100. if ( ! $dbname )
  101. {
  102. $this->register_error($ezsql_mysql_str[3].' in '.__FILE__.' on line '.__LINE__);
  103. $this->show_errors ? trigger_error($ezsql_mysql_str[3],E_USER_WARNING) : null;
  104. }
  105. // Must have an active database connection
  106. else if ( ! $this->dbh )
  107. {
  108. $this->register_error($ezsql_mysql_str[4].' in '.__FILE__.' on line '.__LINE__);
  109. $this->show_errors ? trigger_error($ezsql_mysql_str[4],E_USER_WARNING) : null;
  110. }
  111. // Try to connect to the database
  112. else if ( !@mysql_select_db($dbname,$this->dbh) )
  113. {
  114. // Try to get error supplied by mysql if not use our own
  115. if ( !$str = @mysql_error($this->dbh))
  116. $str = $ezsql_mysql_str[5];
  117. $this->register_error($str.' in '.__FILE__.' on line '.__LINE__);
  118. $this->show_errors ? trigger_error($str,E_USER_WARNING) : null;
  119. }
  120. else
  121. {
  122. $this->dbname = $dbname;
  123. if($encoding!='')
  124. {
  125. $encoding = strtolower(str_replace("-","",$encoding));
  126. $charsets = array();
  127. $result = mysql_query("SHOW CHARACTER SET");
  128. while($row = mysql_fetch_array($result,MYSQL_ASSOC))
  129. {
  130. $charsets[] = $row["Charset"];
  131. }
  132. if(in_array($encoding,$charsets)){
  133. mysql_query("SET NAMES '".$encoding."'");
  134. }
  135. }
  136. $return_val = true;
  137. }
  138. return $return_val;
  139. }
  140. /**********************************************************************
  141. * Format a mySQL string correctly for safe mySQL insert
  142. * (no mater if magic quotes are on or not)
  143. */
  144. function escape($str)
  145. {
  146. // If there is no existing database connection then try to connect
  147. if ( ! isset($this->dbh) || ! $this->dbh )
  148. {
  149. $this->connect($this->dbuser, $this->dbpassword, $this->dbhost);
  150. $this->selectDB($this->dbname, $this->encoding);
  151. }
  152. return mysql_real_escape_string(stripslashes($str));
  153. }
  154. /**********************************************************************
  155. * Return mySQL specific system date syntax
  156. * i.e. Oracle: SYSDATE Mysql: NOW()
  157. */
  158. function sysdate()
  159. {
  160. return 'NOW()';
  161. }
  162. /**********************************************************************
  163. * Perform mySQL query and try to detirmin result value
  164. */
  165. function query($query)
  166. {
  167. // This keeps the connection alive for very long running scripts
  168. if ( $this->num_queries >= 500 )
  169. {
  170. $this->disconnect();
  171. $this->quick_connect($this->dbuser,$this->dbpassword,$this->dbname,$this->dbhost,$this->encoding);
  172. }
  173. // Initialise return
  174. $return_val = 0;
  175. // Flush cached values..
  176. $this->flush();
  177. // For reg expressions
  178. $query = trim($query);
  179. // Log how the function was called
  180. $this->func_call = "\$db->query(\"$query\")";
  181. // Keep track of the last query for debug..
  182. $this->last_query = $query;
  183. // Count how many queries there have been
  184. $this->num_queries++;
  185. // Start timer
  186. $this->timer_start($this->num_queries);
  187. // Use core file cache function
  188. if ( $cache = $this->get_cache($query) )
  189. {
  190. // Keep tack of how long all queries have taken
  191. $this->timer_update_global($this->num_queries);
  192. // Trace all queries
  193. if ( $this->use_trace_log )
  194. {
  195. $this->trace_log[] = $this->debug(false);
  196. }
  197. return $cache;
  198. }
  199. // If there is no existing database connection then try to connect
  200. if ( ! isset($this->dbh) || ! $this->dbh )
  201. {
  202. $this->connect($this->dbuser, $this->dbpassword, $this->dbhost);
  203. $this->selectDB($this->dbname,$this->encoding);
  204. }
  205. // Perform the query via std mysql_query function..
  206. $this->result = @mysql_query($query,$this->dbh);
  207. // If there is an error then take note of it..
  208. if ( $str = @mysql_error($this->dbh) )
  209. {
  210. if (defined('DEBUG') && (DEBUG == 'true')) {
  211. $subject = SITE_NAME . " Database Error";
  212. $body = SITE_NAME . " Database Error\r\n\r\n";
  213. $body .= "Date: " . date('d M Y H:i:s') . " (timezone: " . date_default_timezone_get() . ")\r\n\r\n";
  214. $body .= "SQL query:\r\n";
  215. $body .= $query . "\r\n\r\n";
  216. $body .= "PHP error log:\r\n";
  217. $body .= $str . "\r\n\r\n";
  218. if(isset($this->h)) {
  219. $body .= "Current User: " . $this->h->currentUser->name . " (id: " . $this->h->currentUser->id .")\r\n";
  220. $body .= "User Role: " . $this->h->currentUser->role . "\r\n";
  221. $body .= "Page Name: " . $this->h->pageName . "\r\n";
  222. $body .= "Sub Page: " . $this->h->subPage . "\r\n";
  223. $body .= "Plugin: " . $this->h->plugin->folder . "\r\n\r\n";
  224. }
  225. $body .= "If you need help, visit the forums at http://forums.hotarucms.org\r\n";
  226. // we can avoid using the $h object (which we might not have) by calling EmailFunctions directly.
  227. require_once(LIBS . 'EmailFunctions.php');
  228. $emailFunctions = new EmailFunctions();
  229. $emailFunctions->subject = $subject;
  230. $emailFunctions->body = $body;
  231. $emailFunctions->doEmail();
  232. }
  233. $is_insert = true;
  234. $this->register_error($str);
  235. $this->show_errors ? trigger_error($str,E_USER_WARNING) : null;
  236. return false;
  237. }
  238. // Query was an insert, delete, update, replace
  239. $is_insert = false;
  240. if ( preg_match("/^(insert|delete|update|replace|truncate|drop|create|alter|set)\s+/i",$query) )
  241. {
  242. $this->rows_affected = @mysql_affected_rows($this->dbh);
  243. // Take note of the insert_id
  244. if ( preg_match("/^(insert|replace)\s+/i",$query) )
  245. {
  246. $this->insert_id = @mysql_insert_id($this->dbh);
  247. }
  248. // Return number fo rows affected
  249. $return_val = $this->rows_affected;
  250. }
  251. // Query was a select
  252. else
  253. {
  254. // Take note of column info
  255. $i=0;
  256. while ($i < @mysql_num_fields($this->result))
  257. {
  258. $this->col_info[$i] = @mysql_fetch_field($this->result);
  259. $i++;
  260. }
  261. // Store Query Results
  262. $num_rows=0;
  263. while ( $row = @mysql_fetch_object($this->result) )
  264. {
  265. // Store relults as an objects within main array
  266. $this->last_result[$num_rows] = $row;
  267. $num_rows++;
  268. }
  269. @mysql_free_result($this->result);
  270. // Log number of rows the query returned
  271. $this->num_rows = $num_rows;
  272. // Return number of rows selected
  273. $return_val = $this->num_rows;
  274. }
  275. // disk caching of queries
  276. $this->store_cache($query,$is_insert);
  277. // If debug ALL queries
  278. $this->trace || $this->debug_all ? $this->debug() : null ;
  279. // Keep tack of how long all queries have taken
  280. $this->timer_update_global($this->num_queries);
  281. // Trace all queries
  282. if ( $this->use_trace_log )
  283. {
  284. $this->trace_log[] = $this->debug(false);
  285. }
  286. return $return_val;
  287. }
  288. /**********************************************************************
  289. * Close the active mySQL connection
  290. */
  291. function disconnect()
  292. {
  293. @mysql_close($this->dbh);
  294. }
  295. /**********************************************************************
  296. * Prepares a SQL query for safe use, using sprintf() syntax.
  297. *
  298. * Added for Hotaru
  299. *
  300. * @link http://php.net/sprintf See for syntax to use for query string.
  301. * @since 2.3.0
  302. *
  303. * @param null|string $args If string, first parameter must be query statement
  304. * @param mixed $args, If additional parameters, they will be set inserted into the query.
  305. * @return null|string Sanitized query string
  306. */
  307. function escape_by_ref(&$s)
  308. {
  309. $s = $this->escape($s);
  310. }
  311. function prepare($args=null)
  312. {
  313. if (is_null( $args ))
  314. return;
  315. $args = func_get_args();
  316. // This is a Hotaru hack, enabling args to be built on the fly.
  317. if(is_array($args[0]))
  318. {
  319. // See Submit plugin: class.post.php get_posts() for an example.
  320. $args = $args[0];
  321. }
  322. $query = array_shift($args);
  323. // in case someone mistakenly already singlequoted it
  324. $query = str_replace("'%s'", '%s', $query);
  325. $query = str_replace('"%s"', '%s', $query); // doublequote unquoting
  326. $query = str_replace('%s', "'%s'", $query); // quote the strings
  327. array_walk($args, array(&$this, 'escape_by_ref'));
  328. return @vsprintf($query, $args);
  329. }
  330. }
  331. ?>