PageRenderTime 56ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-includes/wp-db.php

https://github.com/gplsek/competitor-mu
PHP | 1097 lines | 462 code | 123 blank | 512 comment | 106 complexity | 1853be20fff397693727a108eea5410c MD5 | raw file
Possible License(s): LGPL-3.0
  1. <?php
  2. /**
  3. * WordPress DB Class
  4. *
  5. * Original code from {@link http://php.justinvincent.com Justin Vincent (justin@visunet.ie)}
  6. *
  7. * @package WordPress
  8. * @subpackage Database
  9. * @since 0.71
  10. */
  11. /**
  12. * @since 0.71
  13. */
  14. define('EZSQL_VERSION', 'WP1.25');
  15. /**
  16. * @since 0.71
  17. */
  18. define('OBJECT', 'OBJECT', true);
  19. /**
  20. * @since {@internal Version Unknown}}
  21. */
  22. define('OBJECT_K', 'OBJECT_K', false);
  23. /**
  24. * @since 0.71
  25. */
  26. define('ARRAY_A', 'ARRAY_A', false);
  27. /**
  28. * @since 0.71
  29. */
  30. define('ARRAY_N', 'ARRAY_N', false);
  31. /**
  32. * WordPress Database Access Abstraction Object
  33. *
  34. * It is possible to replace this class with your own
  35. * by setting the $wpdb global variable in wp-content/db.php
  36. * file with your class. You can name it wpdb also, since
  37. * this file will not be included, if the other file is
  38. * available.
  39. *
  40. * @link http://codex.wordpress.org/Function_Reference/wpdb_Class
  41. *
  42. * @package WordPress
  43. * @subpackage Database
  44. * @since 0.71
  45. * @final
  46. */
  47. class wpdb {
  48. /**
  49. * Whether to show SQL/DB errors
  50. *
  51. * @since 0.71
  52. * @access private
  53. * @var bool
  54. */
  55. var $show_errors = false;
  56. /**
  57. * Whether to suppress errors during the DB bootstrapping.
  58. *
  59. * @access private
  60. * @since {@internal Version Unknown}}
  61. * @var bool
  62. */
  63. var $suppress_errors = false;
  64. /**
  65. * The last error during query.
  66. *
  67. * @since {@internal Version Unknown}}
  68. * @var string
  69. */
  70. var $last_error = '';
  71. /**
  72. * Amount of queries made
  73. *
  74. * @since 1.2.0
  75. * @access private
  76. * @var int
  77. */
  78. var $num_queries = 0;
  79. /**
  80. * Saved result of the last query made
  81. *
  82. * @since 1.2.0
  83. * @access private
  84. * @var array
  85. */
  86. var $last_query;
  87. /**
  88. * Saved info on the table column
  89. *
  90. * @since 1.2.0
  91. * @access private
  92. * @var array
  93. */
  94. var $col_info;
  95. /**
  96. * Saved queries that were executed
  97. *
  98. * @since 1.5.0
  99. * @access private
  100. * @var array
  101. */
  102. var $queries;
  103. /**
  104. * WordPress table prefix
  105. *
  106. * You can set this to have multiple WordPress installations
  107. * in a single database. The second reason is for possible
  108. * security precautions.
  109. *
  110. * @since 0.71
  111. * @access private
  112. * @var string
  113. */
  114. var $prefix = '';
  115. /**
  116. * Whether the database queries are ready to start executing.
  117. *
  118. * @since 2.5.0
  119. * @access private
  120. * @var bool
  121. */
  122. var $ready = false;
  123. var $blogid = 0;
  124. var $siteid = 0;
  125. var $blogs;
  126. var $signups;
  127. var $site;
  128. var $sitemeta;
  129. var $sitecategories;
  130. var $global_tables = array('blogs', 'signups', 'site', 'sitemeta', 'users', 'usermeta', 'sitecategories', 'registration_log', 'blog_versions');
  131. /**
  132. * WordPress Posts table
  133. *
  134. * @since 1.5.0
  135. * @access public
  136. * @var string
  137. */
  138. var $posts;
  139. /**
  140. * WordPress Users table
  141. *
  142. * @since 1.5.0
  143. * @access public
  144. * @var string
  145. */
  146. var $users;
  147. /**
  148. * WordPress Categories table
  149. *
  150. * @since 1.5.0
  151. * @access public
  152. * @var string
  153. */
  154. var $categories;
  155. /**
  156. * WordPress Post to Category table
  157. *
  158. * @since 1.5.0
  159. * @access public
  160. * @var string
  161. */
  162. var $post2cat;
  163. /**
  164. * WordPress Comments table
  165. *
  166. * @since 1.5.0
  167. * @access public
  168. * @var string
  169. */
  170. var $comments;
  171. /**
  172. * WordPress Links table
  173. *
  174. * @since 1.5.0
  175. * @access public
  176. * @var string
  177. */
  178. var $links;
  179. /**
  180. * WordPress Options table
  181. *
  182. * @since 1.5.0
  183. * @access public
  184. * @var string
  185. */
  186. var $options;
  187. /**
  188. * WordPress Post Metadata table
  189. *
  190. * @since {@internal Version Unknown}}
  191. * @access public
  192. * @var string
  193. */
  194. var $postmeta;
  195. /**
  196. * WordPress User Metadata table
  197. *
  198. * @since 2.3.0
  199. * @access public
  200. * @var string
  201. */
  202. var $usermeta;
  203. /**
  204. * WordPress Terms table
  205. *
  206. * @since 2.3.0
  207. * @access public
  208. * @var string
  209. */
  210. var $terms;
  211. /**
  212. * WordPress Term Taxonomy table
  213. *
  214. * @since 2.3.0
  215. * @access public
  216. * @var string
  217. */
  218. var $term_taxonomy;
  219. /**
  220. * WordPress Term Relationships table
  221. *
  222. * @since 2.3.0
  223. * @access public
  224. * @var string
  225. */
  226. var $term_relationships;
  227. /**
  228. * List of WordPress tables
  229. *
  230. * @since {@internal Version Unknown}}
  231. * @access private
  232. * @var array
  233. */
  234. var $blog_tables = array('posts', 'categories', 'post2cat', 'comments', 'links', 'link2cat', 'options',
  235. 'postmeta', 'terms', 'term_taxonomy', 'term_relationships');
  236. /**
  237. * Database table columns charset
  238. *
  239. * @since 2.2.0
  240. * @access public
  241. * @var string
  242. */
  243. var $charset;
  244. /**
  245. * Database table columns collate
  246. *
  247. * @since 2.2.0
  248. * @access public
  249. * @var string
  250. */
  251. var $collate;
  252. /**
  253. * Connects to the database server and selects a database
  254. *
  255. * PHP4 compatibility layer for calling the PHP5 constructor.
  256. *
  257. * @uses wpdb::__construct() Passes parameters and returns result
  258. * @since 0.71
  259. *
  260. * @param string $dbuser MySQL database user
  261. * @param string $dbpassword MySQL database password
  262. * @param string $dbname MySQL database name
  263. * @param string $dbhost MySQL database host
  264. */
  265. function wpdb($dbuser, $dbpassword, $dbname, $dbhost) {
  266. if( defined( "WP_USE_MULTIPLE_DB" ) && CONSTANT( "WP_USE_MULTIPLE_DB" ) == true )
  267. $this->db_connect();
  268. return $this->__construct($dbuser, $dbpassword, $dbname, $dbhost);
  269. }
  270. /**
  271. * Connects to the database server and selects a database
  272. *
  273. * PHP5 style constructor for compatibility with PHP5. Does
  274. * the actual setting up of the class properties and connection
  275. * to the database.
  276. *
  277. * @since 2.0.8
  278. *
  279. * @param string $dbuser MySQL database user
  280. * @param string $dbpassword MySQL database password
  281. * @param string $dbname MySQL database name
  282. * @param string $dbhost MySQL database host
  283. */
  284. function __construct($dbuser, $dbpassword, $dbname, $dbhost) {
  285. register_shutdown_function(array(&$this, "__destruct"));
  286. if ( defined('WP_DEBUG') and WP_DEBUG == true )
  287. $this->show_errors();
  288. $this->charset = 'utf8';
  289. if( defined( 'DB_COLLATE' ) && constant( 'DB_COLLATE' ) != '' ) {
  290. $this->collate = constant( 'DB_COLLATE' );
  291. } else {
  292. $this->collate = 'utf8_general_ci';
  293. }
  294. if ( defined('DB_CHARSET') )
  295. $this->charset = DB_CHARSET;
  296. if ( defined('DB_COLLATE') )
  297. $this->collate = DB_COLLATE;
  298. $this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword, true);
  299. if (!$this->dbh) {
  300. $this->bail(sprintf(/*WP_I18N_DB_CONN_ERROR*/"
  301. <h1>Error establishing a database connection</h1>
  302. <p>This either means that the username and password information in your <code>wp-config.php</code> file is incorrect or we can't contact the database server at <code>%s</code>. This could mean your host's database server is down.</p>
  303. <ul>
  304. <li>Are you sure you have the correct username and password?</li>
  305. <li>Are you sure that you have typed the correct hostname?</li>
  306. <li>Are you sure that the database server is running?</li>
  307. </ul>
  308. <p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='http://wordpress.org/support/'>WordPress Support Forums</a>.</p>
  309. "/*/WP_I18N_DB_CONN_ERROR*/, $dbhost));
  310. return;
  311. }
  312. $this->ready = true;
  313. if ( $this->has_cap( 'collation' ) ) {
  314. $collation_query = '';
  315. if ( !empty($this->charset) ) {
  316. $collation_query = "SET NAMES '{$this->charset}'";
  317. if (!empty($this->collate) )
  318. $collation_query .= " COLLATE '{$this->collate}'";
  319. }
  320. if ( !empty($collation_query) )
  321. $this->query($collation_query);
  322. }
  323. $this->select($dbname, $this->dbh);
  324. }
  325. /**
  326. * PHP5 style destructor and will run when database object is destroyed.
  327. *
  328. * @since 2.0.8
  329. *
  330. * @return bool Always true
  331. */
  332. function __destruct() {
  333. return true;
  334. }
  335. /**
  336. * Sets the table prefix for the WordPress tables.
  337. *
  338. * Also allows for the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE to
  339. * override the WordPress users and usersmeta tables.
  340. *
  341. * @since 2.5.0
  342. *
  343. * @param string $prefix Alphanumeric name for the new prefix.
  344. * @return string Old prefix
  345. */
  346. function set_prefix($prefix) {
  347. if ( preg_match('|[^a-z0-9_]|i', $prefix) )
  348. return new WP_Error('invalid_db_prefix', /*WP_I18N_DB_BAD_PREFIX*/'Invalid database prefix'/*/WP_I18N_DB_BAD_PREFIX*/);
  349. $old_prefix = '';
  350. if( isset( $this->base_prefix ) )
  351. $old_prefix = $this->base_prefix;
  352. $this->base_prefix = $prefix;
  353. foreach ( $this->global_tables as $table )
  354. $this->$table = $prefix . $table;
  355. if ( empty($this->blogid) )
  356. return $old_prefix;
  357. $this->prefix = $this->base_prefix . $this->blogid . '_';
  358. foreach ( $this->blog_tables as $table )
  359. $this->$table = $this->prefix . $table;
  360. if ( defined('CUSTOM_USER_TABLE') )
  361. $this->users = CUSTOM_USER_TABLE;
  362. if ( defined('CUSTOM_USER_META_TABLE') )
  363. $this->usermeta = CUSTOM_USER_META_TABLE;
  364. return $old_prefix;
  365. }
  366. function set_blog_id($blog_id, $site_id = '') {
  367. if ( !empty($site_id) )
  368. $this->siteid = $site_id;
  369. $old_blog_id = $this->blogid;
  370. $this->blogid = $blog_id;
  371. $this->prefix = $this->base_prefix . $this->blogid . '_';
  372. foreach ( $this->blog_tables as $table )
  373. $this->$table = $this->prefix . $table;
  374. return $old_blog_id;
  375. }
  376. /**
  377. * Selects a database using the current database connection.
  378. *
  379. * The database name will be changed based on the current database
  380. * connection. On failure, the execution will bail and display an DB error.
  381. *
  382. * @since 0.71
  383. *
  384. * @param string $db MySQL database name
  385. * @return null Always null.
  386. */
  387. function select($db, &$dbh) {
  388. if (!@mysql_select_db($db, $dbh)) {
  389. $this->ready = false;
  390. $this->bail(sprintf(/*WP_I18N_DB_SELECT_DB*/'
  391. <h1>Can&#8217;t select database</h1>
  392. <p>We were able to connect to the database server (which means your username and password is okay) but not able to select the <code>%1$s</code> database.</p>
  393. <ul>
  394. <li>Are you sure it exists?</li>
  395. <li>Does the user <code>%2$s</code> have permission to use the <code>%1$s</code> database?</li>
  396. <li>On some systems the name of your database is prefixed with your username, so it would be like <code>username_%1$s</code>. Could that be the problem?</li>
  397. </ul>
  398. <p>If you don\'t know how to setup a database you should <strong>contact your host</strong>. If all else fails you may find help at the <a href="http://wordpress.org/support/">WordPress Support Forums</a>.</p>'/*/WP_I18N_DB_SELECT_DB*/, $db, DB_USER));
  399. return;
  400. }
  401. }
  402. /**
  403. * Escapes content for insertion into the database, for security
  404. *
  405. * @since 0.71
  406. *
  407. * @param string $string
  408. * @return string query safe string
  409. */
  410. function escape($string) {
  411. return addslashes( $string );
  412. // Disable rest for now, causing problems
  413. /*
  414. if( !$this->dbh || version_compare( phpversion(), '4.3.0' ) == '-1' )
  415. return mysql_escape_string( $string );
  416. else
  417. return mysql_real_escape_string( $string, $this->dbh );
  418. */
  419. }
  420. /**
  421. * Escapes content by reference for insertion into the database, for security
  422. *
  423. * @since 2.3.0
  424. *
  425. * @param string $s
  426. */
  427. function escape_by_ref(&$s) {
  428. $s = $this->escape($s);
  429. }
  430. /**
  431. * Prepares a SQL query for safe use, using sprintf() syntax.
  432. *
  433. * @link http://php.net/sprintf See for syntax to use for query string.
  434. * @since 2.3.0
  435. *
  436. * @param null|string $args If string, first parameter must be query statement
  437. * @param mixed $args,... If additional parameters, they will be set inserted into the query.
  438. * @return null|string Sanitized query string
  439. */
  440. function prepare($args=null) {
  441. if ( is_null( $args ) )
  442. return;
  443. $args = func_get_args();
  444. $query = array_shift($args);
  445. $query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
  446. $query = str_replace('"%s"', '%s', $query); // doublequote unquoting
  447. $query = str_replace('%s', "'%s'", $query); // quote the strings
  448. array_walk($args, array(&$this, 'escape_by_ref'));
  449. return @vsprintf($query, $args);
  450. }
  451. /**
  452. * Print SQL/DB error.
  453. *
  454. * @since 0.71
  455. * @global array $EZSQL_ERROR Stores error information of query and error string
  456. *
  457. * @param string $str The error to display
  458. * @return bool False if the showing of errors is disabled.
  459. */
  460. function print_error($str = '') {
  461. global $EZSQL_ERROR;
  462. if (!$str) $str = mysql_error($this->dbh);
  463. $EZSQL_ERROR[] = array ('query' => $this->last_query, 'error_str' => $str);
  464. if ( $this->suppress_errors )
  465. return false;
  466. if ( $caller = $this->get_caller() )
  467. $error_str = sprintf(/*WP_I18N_DB_QUERY_ERROR_FULL*/'WordPress database error %1$s for query %2$s made by %3$s'/*/WP_I18N_DB_QUERY_ERROR_FULL*/, $str, $this->last_query, $caller);
  468. else
  469. $error_str = sprintf(/*WP_I18N_DB_QUERY_ERROR*/'WordPress database error %1$s for query %2$s'/*/WP_I18N_DB_QUERY_ERROR*/, $str, $this->last_query);
  470. $log_error = true;
  471. if ( ! function_exists('error_log') )
  472. $log_error = false;
  473. $log_file = @ini_get('error_log');
  474. if ( !empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file) )
  475. $log_error = false;
  476. if ( $log_error )
  477. @error_log($error_str, 0);
  478. // Is error output turned on or not..
  479. if ( !$this->show_errors )
  480. return false;
  481. // If there is an error then take note of it
  482. $msg = "WordPress database error: [$str]\n{$this->query}\n";
  483. if( defined( 'ERRORLOGFILE' ) )
  484. error_log( $msg, 3, CONSTANT( 'ERRORLOGFILE' ) );
  485. if( defined( 'DIEONDBERROR' ) )
  486. die( $msg );
  487. }
  488. /**
  489. * Enables showing of database errors.
  490. *
  491. * This function should be used only to enable showing of errors.
  492. * wpdb::hide_errors() should be used instead for hiding of errors. However,
  493. * this function can be used to enable and disable showing of database
  494. * errors.
  495. *
  496. * @since 0.71
  497. *
  498. * @param bool $show Whether to show or hide errors
  499. * @return bool Old value for showing errors.
  500. */
  501. function show_errors( $show = true ) {
  502. $errors = $this->show_errors;
  503. $this->show_errors = $show;
  504. return $errors;
  505. }
  506. /**
  507. * Disables showing of database errors.
  508. *
  509. * @since 0.71
  510. *
  511. * @return bool Whether showing of errors was active or not
  512. */
  513. function hide_errors() {
  514. $show = $this->show_errors;
  515. $this->show_errors = false;
  516. return $show;
  517. }
  518. /**
  519. * Whether to suppress database errors.
  520. *
  521. * @param unknown_type $suppress
  522. * @return unknown
  523. */
  524. function suppress_errors( $suppress = true ) {
  525. $errors = $this->suppress_errors;
  526. $this->suppress_errors = $suppress;
  527. return $errors;
  528. }
  529. /**
  530. * Kill cached query results.
  531. *
  532. * @since 0.71
  533. */
  534. function flush() {
  535. $this->last_result = array();
  536. $this->col_info = null;
  537. $this->last_query = null;
  538. }
  539. function db_connect( $query = "SELECT" ) {
  540. global $db_list, $global_db_list;
  541. if( is_array( $db_list ) == false )
  542. return true;
  543. if( $this->blogs != '' && preg_match("/(" . $this->blogs . "|" . $this->users . "|" . $this->usermeta . "|" . $this->site . "|" . $this->sitemeta . "|" . $this->sitecategories . ")/i",$query) ) {
  544. $action = 'global';
  545. $details = $global_db_list[ mt_rand( 0, count( $global_db_list ) -1 ) ];
  546. $this->db_global = $details;
  547. } elseif ( preg_match("/^\\s*(alter table|create|insert|delete|update|replace) /i",$query) ) {
  548. $action = 'write';
  549. $details = $db_list[ 'write' ][ mt_rand( 0, count( $db_list[ 'write' ] ) -1 ) ];
  550. $this->db_write = $details;
  551. } else {
  552. $action = '';
  553. $details = $db_list[ 'read' ][ mt_rand( 0, count( $db_list[ 'read' ] ) -1 ) ];
  554. $this->db_read = $details;
  555. }
  556. $dbhname = "dbh" . $action;
  557. $this->$dbhname = @mysql_connect( $details[ 'db_host' ], $details[ 'db_user' ], $details[ 'db_password' ] );
  558. if (!$this->$dbhname ) {
  559. $this->bail("
  560. <h1>Error establishing a database connection</h1>
  561. <p>This either means that the username and password information in your <code>wp-config.php</code> file is incorrect or we can't contact the database server at <code>$dbhost</code>. This could mean your host's database server is down.</p>
  562. <ul>
  563. <li>Are you sure you have the correct username and password?</li>
  564. <li>Are you sure that you have typed the correct hostname?</li>
  565. <li>Are you sure that the database server is running?</li>
  566. </ul>
  567. <p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='http://wordpress.org/support/'>WordPress Support Forums</a>.</p>
  568. ");
  569. }
  570. $this->select( $details[ 'db_name' ], $this->$dbhname );
  571. }
  572. /**
  573. * Perform a MySQL database query, using current database connection.
  574. *
  575. * More information can be found on the codex page.
  576. *
  577. * @since 0.71
  578. *
  579. * @param string $query
  580. * @return unknown
  581. */
  582. function query($query) {
  583. if ( ! $this->ready )
  584. return false;
  585. // filter the query, if filters are available
  586. // NOTE: some queries are made before the plugins have been loaded, and thus cannot be filtered with this method
  587. if ( function_exists('apply_filters') )
  588. $query = apply_filters('query', $query);
  589. // initialise return
  590. $return_val = 0;
  591. $this->flush();
  592. // Log how the function was called
  593. $this->func_call = "\$db->query(\"$query\")";
  594. // Keep track of the last query for debug..
  595. $this->last_query = $query;
  596. // Perform the query via std mysql_query function..
  597. if ( defined('SAVEQUERIES') && SAVEQUERIES )
  598. $this->timer_start();
  599. // use $this->dbh for read ops, and $this->dbhwrite for write ops
  600. // use $this->dbhglobal for gloal table ops
  601. unset( $dbh );
  602. if( defined( "WP_USE_MULTIPLE_DB" ) && CONSTANT( "WP_USE_MULTIPLE_DB" ) == true ) {
  603. if( $this->blogs != '' && preg_match("/(" . $this->blogs . "|" . $this->users . "|" . $this->usermeta . "|" . $this->site . "|" . $this->sitemeta . "|" . $this->sitecategories . ")/i",$query) ) {
  604. if( false == isset( $this->dbhglobal ) ) {
  605. $this->db_connect( $query );
  606. }
  607. $dbh =& $this->dbhglobal;
  608. $this->last_db_used = "global";
  609. } elseif ( preg_match("/^\\s*(alter table|create|insert|delete|update|replace) /i",$query) ) {
  610. if( false == isset( $this->dbhwrite ) ) {
  611. $this->db_connect( $query );
  612. }
  613. $dbh =& $this->dbhwrite;
  614. $this->last_db_used = "write";
  615. } else {
  616. $dbh =& $this->dbh;
  617. $this->last_db_used = "read";
  618. }
  619. } else {
  620. $dbh =& $this->dbh;
  621. $this->last_db_used = "other/read";
  622. }
  623. $this->result = @mysql_query($query, $dbh);
  624. ++$this->num_queries;
  625. if ( defined('SAVEQUERIES') && SAVEQUERIES )
  626. $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
  627. // If there is an error then take note of it..
  628. if( $dbh ) {
  629. if ( mysql_error( $dbh ) ) {
  630. $this->print_error( mysql_error( $dbh ));
  631. return false;
  632. }
  633. }
  634. if ( preg_match("/^\\s*(insert|delete|update|replace|alter) /i",$query) ) {
  635. $this->rows_affected = mysql_affected_rows($dbh);
  636. // Take note of the insert_id
  637. if ( preg_match("/^\\s*(insert|replace) /i",$query) ) {
  638. $this->insert_id = mysql_insert_id($dbh);
  639. }
  640. // Return number of rows affected
  641. $return_val = $this->rows_affected;
  642. } else {
  643. $i = 0;
  644. while ($i < @mysql_num_fields($this->result)) {
  645. $this->col_info[$i] = @mysql_fetch_field($this->result);
  646. $i++;
  647. }
  648. $num_rows = 0;
  649. while ( $row = @mysql_fetch_object($this->result) ) {
  650. $this->last_result[$num_rows] = $row;
  651. $num_rows++;
  652. }
  653. @mysql_free_result($this->result);
  654. // Log number of rows the query returned
  655. $this->num_rows = $num_rows;
  656. // Return number of rows selected
  657. $return_val = $this->num_rows;
  658. }
  659. return $return_val;
  660. }
  661. /**
  662. * Insert an array of data into a table.
  663. *
  664. * @since 2.5.0
  665. *
  666. * @param string $table WARNING: not sanitized!
  667. * @param array $data Should not already be SQL-escaped
  668. * @return mixed Results of $this->query()
  669. */
  670. function insert($table, $data) {
  671. $data = add_magic_quotes($data);
  672. $fields = array_keys($data);
  673. return $this->query("INSERT INTO $table (`" . implode('`,`',$fields) . "`) VALUES ('".implode("','",$data)."')");
  674. }
  675. /**
  676. * Update a row in the table with an array of data.
  677. *
  678. * @since 2.5.0
  679. *
  680. * @param string $table WARNING: not sanitized!
  681. * @param array $data Should not already be SQL-escaped
  682. * @param array $where A named array of WHERE column => value relationships. Multiple member pairs will be joined with ANDs. WARNING: the column names are not currently sanitized!
  683. * @return mixed Results of $this->query()
  684. */
  685. function update($table, $data, $where){
  686. $data = add_magic_quotes($data);
  687. $bits = $wheres = array();
  688. foreach ( (array) array_keys($data) as $k )
  689. $bits[] = "`$k` = '$data[$k]'";
  690. if ( is_array( $where ) )
  691. foreach ( $where as $c => $v )
  692. $wheres[] = "$c = '" . $this->escape( $v ) . "'";
  693. else
  694. return false;
  695. return $this->query( "UPDATE $table SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres ) );
  696. }
  697. /**
  698. * Retrieve one variable from the database.
  699. *
  700. * This combines the functionality of wpdb::get_row() and wpdb::get_col(),
  701. * so both the column and row can be picked.
  702. *
  703. * It is possible to use this function without executing more queries. If
  704. * you already made a query, you can set the $query to 'null' value and just
  705. * retrieve either the column and row of the last query result.
  706. *
  707. * @since 0.71
  708. *
  709. * @param string $query Can be null as well, for caching
  710. * @param int $x Column num to return
  711. * @param int $y Row num to return
  712. * @return mixed Database query results
  713. */
  714. function get_var($query=null, $x = 0, $y = 0) {
  715. $this->func_call = "\$db->get_var(\"$query\",$x,$y)";
  716. if ( $query )
  717. $this->query($query);
  718. // Extract var out of cached results based x,y vals
  719. if ( !empty( $this->last_result[$y] ) ) {
  720. $values = array_values(get_object_vars($this->last_result[$y]));
  721. }
  722. // If there is a value return it else return null
  723. return (isset($values[$x]) && $values[$x]!=='') ? $values[$x] : null;
  724. }
  725. /**
  726. * Retrieve one row from the database.
  727. *
  728. * @since 0.71
  729. *
  730. * @param string $query SQL query
  731. * @param string $output ARRAY_A | ARRAY_N | OBJECT
  732. * @param int $y Row num to return
  733. * @return mixed Database query results
  734. */
  735. function get_row($query = null, $output = OBJECT, $y = 0) {
  736. $this->func_call = "\$db->get_row(\"$query\",$output,$y)";
  737. if ( $query )
  738. $this->query($query);
  739. else
  740. return null;
  741. if ( !isset($this->last_result[$y]) )
  742. return null;
  743. if ( $output == OBJECT ) {
  744. return $this->last_result[$y] ? $this->last_result[$y] : null;
  745. } elseif ( $output == ARRAY_A ) {
  746. return $this->last_result[$y] ? get_object_vars($this->last_result[$y]) : null;
  747. } elseif ( $output == ARRAY_N ) {
  748. return $this->last_result[$y] ? array_values(get_object_vars($this->last_result[$y])) : null;
  749. } else {
  750. $this->print_error(/*WP_I18N_DB_GETROW_ERROR*/" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N"/*/WP_I18N_DB_GETROW_ERROR*/);
  751. }
  752. }
  753. /**
  754. * Retrieve one column from the database.
  755. *
  756. * @since 0.71
  757. *
  758. * @param string $query Can be null as well, for caching
  759. * @param int $x Col num to return. Starts from 0.
  760. * @return array Column results
  761. */
  762. function get_col($query = null , $x = 0) {
  763. if ( $query )
  764. $this->query($query);
  765. $new_array = array();
  766. // Extract the column values
  767. for ( $i=0; $i < count($this->last_result); $i++ ) {
  768. $new_array[$i] = $this->get_var(null, $x, $i);
  769. }
  770. return $new_array;
  771. }
  772. /**
  773. * Retrieve an entire result set from the database.
  774. *
  775. * @since 0.71
  776. *
  777. * @param string|null $query Can also be null to pull from the cache
  778. * @param string $output ARRAY_A | ARRAY_N | OBJECT_K | OBJECT
  779. * @return mixed Database query results
  780. */
  781. function get_results($query = null, $output = OBJECT) {
  782. $this->func_call = "\$db->get_results(\"$query\", $output)";
  783. if ( $query )
  784. $this->query($query);
  785. else
  786. return null;
  787. if ( $output == OBJECT ) {
  788. // Return an integer-keyed array of row objects
  789. return $this->last_result;
  790. } elseif ( $output == OBJECT_K ) {
  791. // Return an array of row objects with keys from column 1
  792. // (Duplicates are discarded)
  793. foreach ( $this->last_result as $row ) {
  794. $key = array_shift( get_object_vars( $row ) );
  795. if ( !isset( $new_array[ $key ] ) )
  796. $new_array[ $key ] = $row;
  797. }
  798. return $new_array;
  799. } elseif ( $output == ARRAY_A || $output == ARRAY_N ) {
  800. // Return an integer-keyed array of...
  801. if ( $this->last_result ) {
  802. $i = 0;
  803. foreach( (array) $this->last_result as $row ) {
  804. if ( $output == ARRAY_N ) {
  805. // ...integer-keyed row arrays
  806. $new_array[$i] = array_values( get_object_vars( $row ) );
  807. } else {
  808. // ...column name-keyed row arrays
  809. $new_array[$i] = get_object_vars( $row );
  810. }
  811. ++$i;
  812. }
  813. return $new_array;
  814. }
  815. }
  816. }
  817. /**
  818. * Retrieve column metadata from the last query.
  819. *
  820. * @since 0.71
  821. *
  822. * @param string $info_type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill
  823. * @param int $col_offset 0: col name. 1: which table the col's in. 2: col's max length. 3: if the col is numeric. 4: col's type
  824. * @return mixed Column Results
  825. */
  826. function get_col_info($info_type = 'name', $col_offset = -1) {
  827. if ( $this->col_info ) {
  828. if ( $col_offset == -1 ) {
  829. $i = 0;
  830. foreach( (array) $this->col_info as $col ) {
  831. $new_array[$i] = $col->{$info_type};
  832. $i++;
  833. }
  834. return $new_array;
  835. } else {
  836. return $this->col_info[$col_offset]->{$info_type};
  837. }
  838. }
  839. }
  840. /**
  841. * Starts the timer, for debugging purposes.
  842. *
  843. * @since 1.5.0
  844. *
  845. * @return bool Always returns true
  846. */
  847. function timer_start() {
  848. $mtime = microtime();
  849. $mtime = explode(' ', $mtime);
  850. $this->time_start = $mtime[1] + $mtime[0];
  851. return true;
  852. }
  853. /**
  854. * Stops the debugging timer.
  855. *
  856. * @since 1.5.0
  857. *
  858. * @return int Total time spent on the query, in milliseconds
  859. */
  860. function timer_stop() {
  861. $mtime = microtime();
  862. $mtime = explode(' ', $mtime);
  863. $time_end = $mtime[1] + $mtime[0];
  864. $time_total = $time_end - $this->time_start;
  865. return $time_total;
  866. }
  867. /**
  868. * Wraps fatal errors in a nice header and footer and dies.
  869. *
  870. * @since 1.5.0
  871. *
  872. * @param string $message
  873. * @return unknown
  874. */
  875. function bail($message) {
  876. if ( !$this->show_errors ) {
  877. if ( class_exists('WP_Error') )
  878. $this->error = new WP_Error('500', $message);
  879. else
  880. $this->error = $message;
  881. return false;
  882. }
  883. wp_die($message);
  884. }
  885. /**
  886. * Whether or not MySQL database is minimal required version.
  887. *
  888. * @since 2.5.0
  889. * @uses $wp_version
  890. *
  891. * @return WP_Error
  892. */
  893. function check_database_version()
  894. {
  895. global $wp_version;
  896. // Make sure the server has MySQL 4.0
  897. if ( version_compare($this->db_version(), '4.0.0', '<') )
  898. return new WP_Error('database_version',sprintf(__('<strong>ERROR</strong>: WordPress %s requires MySQL 4.0.0 or higher'), $wp_version));
  899. }
  900. /**
  901. * Whether of not the database version supports collation.
  902. *
  903. * Called when WordPress is generating the table scheme.
  904. *
  905. * @since 2.5.0
  906. *
  907. * @return bool True if collation is supported, false if version does not
  908. */
  909. function supports_collation()
  910. {
  911. return $this->has_cap( 'collation' );
  912. }
  913. /**
  914. * Generic function to determine if a database supports a particular feature
  915. * @param string $db_cap the feature
  916. * @param false|string|resource $dbh_or_table the databaese (the current database, the database housing the specified table, or the database of the mysql resource)
  917. * @return bool
  918. */
  919. function has_cap( $db_cap ) {
  920. $version = $this->db_version();
  921. switch ( strtolower( $db_cap ) ) :
  922. case 'collation' : // @since 2.5.0
  923. case 'group_concat' : // @since 2.7
  924. case 'subqueries' : // @since 2.7
  925. return version_compare($version, '4.1', '>=');
  926. break;
  927. endswitch;
  928. return false;
  929. }
  930. /**
  931. * Retrieve the name of the function that called wpdb.
  932. *
  933. * Requires PHP 4.3 and searches up the list of functions until it reaches
  934. * the one that would most logically had called this method.
  935. *
  936. * @since 2.5.0
  937. *
  938. * @return string The name of the calling function
  939. */
  940. function get_caller() {
  941. // requires PHP 4.3+
  942. if ( !is_callable('debug_backtrace') )
  943. return '';
  944. $bt = debug_backtrace();
  945. $caller = array();
  946. $bt = array_reverse( $bt );
  947. foreach ( (array) $bt as $call ) {
  948. if ( @$call['class'] == __CLASS__ )
  949. continue;
  950. $function = $call['function'];
  951. if ( isset( $call['class'] ) )
  952. $function = $call['class'] . "->$function";
  953. $caller[] = $function;
  954. }
  955. $caller = join( ', ', $caller );
  956. return $caller;
  957. }
  958. /**
  959. * The database version number
  960. * @return false|string false on failure, version number on success
  961. */
  962. function db_version() {
  963. return preg_replace('/[^0-9.].*/', '', mysql_get_server_info( $this->dbh ));
  964. }
  965. }
  966. if ( ! isset($wpdb) ) {
  967. /**
  968. * WordPress Database Object, if it isn't set already in wp-content/db.php
  969. * @global object $wpdb Creates a new wpdb object based on wp-config.php Constants for the database
  970. * @since 0.71
  971. */
  972. $wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
  973. }
  974. ?>