PageRenderTime 63ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-includes/wp-db.php

https://github.com/webgefrickel/frckl-init-wordpress
PHP | 1752 lines | 612 code | 180 blank | 960 comment | 128 complexity | 7e04d01aed426dc3c0c7340bf14ecbfe MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, GPL-2.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 2.5.0
  21. */
  22. define( 'OBJECT_K', 'OBJECT_K' );
  23. /**
  24. * @since 0.71
  25. */
  26. define( 'ARRAY_A', 'ARRAY_A' );
  27. /**
  28. * @since 0.71
  29. */
  30. define( 'ARRAY_N', 'ARRAY_N' );
  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 to your class. The wpdb class will still be included,
  37. * so you can extend it or simply use your own.
  38. *
  39. * @link http://codex.wordpress.org/Function_Reference/wpdb_Class
  40. *
  41. * @package WordPress
  42. * @subpackage Database
  43. * @since 0.71
  44. */
  45. class wpdb {
  46. /**
  47. * Whether to show SQL/DB errors
  48. *
  49. * @since 0.71
  50. * @access private
  51. * @var bool
  52. */
  53. var $show_errors = false;
  54. /**
  55. * Whether to suppress errors during the DB bootstrapping.
  56. *
  57. * @access private
  58. * @since 2.5.0
  59. * @var bool
  60. */
  61. var $suppress_errors = false;
  62. /**
  63. * The last error during query.
  64. *
  65. * @since 2.5.0
  66. * @var string
  67. */
  68. var $last_error = '';
  69. /**
  70. * Amount of queries made
  71. *
  72. * @since 1.2.0
  73. * @access private
  74. * @var int
  75. */
  76. var $num_queries = 0;
  77. /**
  78. * Count of rows returned by previous query
  79. *
  80. * @since 0.71
  81. * @access private
  82. * @var int
  83. */
  84. var $num_rows = 0;
  85. /**
  86. * Count of affected rows by previous query
  87. *
  88. * @since 0.71
  89. * @access private
  90. * @var int
  91. */
  92. var $rows_affected = 0;
  93. /**
  94. * The ID generated for an AUTO_INCREMENT column by the previous query (usually INSERT).
  95. *
  96. * @since 0.71
  97. * @access public
  98. * @var int
  99. */
  100. var $insert_id = 0;
  101. /**
  102. * Last query made
  103. *
  104. * @since 0.71
  105. * @access private
  106. * @var array
  107. */
  108. var $last_query;
  109. /**
  110. * Results of the last query made
  111. *
  112. * @since 0.71
  113. * @access private
  114. * @var array|null
  115. */
  116. var $last_result;
  117. /**
  118. * MySQL result, which is either a resource or boolean.
  119. *
  120. * @since 0.71
  121. * @access protected
  122. * @var mixed
  123. */
  124. protected $result;
  125. /**
  126. * Saved info on the table column
  127. *
  128. * @since 0.71
  129. * @access protected
  130. * @var array
  131. */
  132. protected $col_info;
  133. /**
  134. * Saved queries that were executed
  135. *
  136. * @since 1.5.0
  137. * @access private
  138. * @var array
  139. */
  140. var $queries;
  141. /**
  142. * WordPress table prefix
  143. *
  144. * You can set this to have multiple WordPress installations
  145. * in a single database. The second reason is for possible
  146. * security precautions.
  147. *
  148. * @since 2.5.0
  149. * @access private
  150. * @var string
  151. */
  152. var $prefix = '';
  153. /**
  154. * Whether the database queries are ready to start executing.
  155. *
  156. * @since 2.3.2
  157. * @access private
  158. * @var bool
  159. */
  160. var $ready = false;
  161. /**
  162. * {@internal Missing Description}}
  163. *
  164. * @since 3.0.0
  165. * @access public
  166. * @var int
  167. */
  168. var $blogid = 0;
  169. /**
  170. * {@internal Missing Description}}
  171. *
  172. * @since 3.0.0
  173. * @access public
  174. * @var int
  175. */
  176. var $siteid = 0;
  177. /**
  178. * List of WordPress per-blog tables
  179. *
  180. * @since 2.5.0
  181. * @access private
  182. * @see wpdb::tables()
  183. * @var array
  184. */
  185. var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta',
  186. 'terms', 'term_taxonomy', 'term_relationships', 'commentmeta' );
  187. /**
  188. * List of deprecated WordPress tables
  189. *
  190. * categories, post2cat, and link2cat were deprecated in 2.3.0, db version 5539
  191. *
  192. * @since 2.9.0
  193. * @access private
  194. * @see wpdb::tables()
  195. * @var array
  196. */
  197. var $old_tables = array( 'categories', 'post2cat', 'link2cat' );
  198. /**
  199. * List of WordPress global tables
  200. *
  201. * @since 3.0.0
  202. * @access private
  203. * @see wpdb::tables()
  204. * @var array
  205. */
  206. var $global_tables = array( 'users', 'usermeta' );
  207. /**
  208. * List of Multisite global tables
  209. *
  210. * @since 3.0.0
  211. * @access private
  212. * @see wpdb::tables()
  213. * @var array
  214. */
  215. var $ms_global_tables = array( 'blogs', 'signups', 'site', 'sitemeta',
  216. 'sitecategories', 'registration_log', 'blog_versions' );
  217. /**
  218. * WordPress Comments table
  219. *
  220. * @since 1.5.0
  221. * @access public
  222. * @var string
  223. */
  224. var $comments;
  225. /**
  226. * WordPress Comment Metadata table
  227. *
  228. * @since 2.9.0
  229. * @access public
  230. * @var string
  231. */
  232. var $commentmeta;
  233. /**
  234. * WordPress Links table
  235. *
  236. * @since 1.5.0
  237. * @access public
  238. * @var string
  239. */
  240. var $links;
  241. /**
  242. * WordPress Options table
  243. *
  244. * @since 1.5.0
  245. * @access public
  246. * @var string
  247. */
  248. var $options;
  249. /**
  250. * WordPress Post Metadata table
  251. *
  252. * @since 1.5.0
  253. * @access public
  254. * @var string
  255. */
  256. var $postmeta;
  257. /**
  258. * WordPress Posts table
  259. *
  260. * @since 1.5.0
  261. * @access public
  262. * @var string
  263. */
  264. var $posts;
  265. /**
  266. * WordPress Terms table
  267. *
  268. * @since 2.3.0
  269. * @access public
  270. * @var string
  271. */
  272. var $terms;
  273. /**
  274. * WordPress Term Relationships table
  275. *
  276. * @since 2.3.0
  277. * @access public
  278. * @var string
  279. */
  280. var $term_relationships;
  281. /**
  282. * WordPress Term Taxonomy table
  283. *
  284. * @since 2.3.0
  285. * @access public
  286. * @var string
  287. */
  288. var $term_taxonomy;
  289. /*
  290. * Global and Multisite tables
  291. */
  292. /**
  293. * WordPress User Metadata table
  294. *
  295. * @since 2.3.0
  296. * @access public
  297. * @var string
  298. */
  299. var $usermeta;
  300. /**
  301. * WordPress Users table
  302. *
  303. * @since 1.5.0
  304. * @access public
  305. * @var string
  306. */
  307. var $users;
  308. /**
  309. * Multisite Blogs table
  310. *
  311. * @since 3.0.0
  312. * @access public
  313. * @var string
  314. */
  315. var $blogs;
  316. /**
  317. * Multisite Blog Versions table
  318. *
  319. * @since 3.0.0
  320. * @access public
  321. * @var string
  322. */
  323. var $blog_versions;
  324. /**
  325. * Multisite Registration Log table
  326. *
  327. * @since 3.0.0
  328. * @access public
  329. * @var string
  330. */
  331. var $registration_log;
  332. /**
  333. * Multisite Signups table
  334. *
  335. * @since 3.0.0
  336. * @access public
  337. * @var string
  338. */
  339. var $signups;
  340. /**
  341. * Multisite Sites table
  342. *
  343. * @since 3.0.0
  344. * @access public
  345. * @var string
  346. */
  347. var $site;
  348. /**
  349. * Multisite Sitewide Terms table
  350. *
  351. * @since 3.0.0
  352. * @access public
  353. * @var string
  354. */
  355. var $sitecategories;
  356. /**
  357. * Multisite Site Metadata table
  358. *
  359. * @since 3.0.0
  360. * @access public
  361. * @var string
  362. */
  363. var $sitemeta;
  364. /**
  365. * Format specifiers for DB columns. Columns not listed here default to %s. Initialized during WP load.
  366. *
  367. * Keys are column names, values are format types: 'ID' => '%d'
  368. *
  369. * @since 2.8.0
  370. * @see wpdb::prepare()
  371. * @see wpdb::insert()
  372. * @see wpdb::update()
  373. * @see wpdb::delete()
  374. * @see wp_set_wpdb_vars()
  375. * @access public
  376. * @var array
  377. */
  378. var $field_types = array();
  379. /**
  380. * Database table columns charset
  381. *
  382. * @since 2.2.0
  383. * @access public
  384. * @var string
  385. */
  386. var $charset;
  387. /**
  388. * Database table columns collate
  389. *
  390. * @since 2.2.0
  391. * @access public
  392. * @var string
  393. */
  394. var $collate;
  395. /**
  396. * Database Username
  397. *
  398. * @since 2.9.0
  399. * @access protected
  400. * @var string
  401. */
  402. protected $dbuser;
  403. /**
  404. * Database Password
  405. *
  406. * @since 3.1.0
  407. * @access protected
  408. * @var string
  409. */
  410. protected $dbpassword;
  411. /**
  412. * Database Name
  413. *
  414. * @since 3.1.0
  415. * @access protected
  416. * @var string
  417. */
  418. protected $dbname;
  419. /**
  420. * Database Host
  421. *
  422. * @since 3.1.0
  423. * @access protected
  424. * @var string
  425. */
  426. protected $dbhost;
  427. /**
  428. * Database Handle
  429. *
  430. * @since 0.71
  431. * @access protected
  432. * @var string
  433. */
  434. protected $dbh;
  435. /**
  436. * A textual description of the last query/get_row/get_var call
  437. *
  438. * @since 3.0.0
  439. * @access public
  440. * @var string
  441. */
  442. var $func_call;
  443. /**
  444. * Whether MySQL is used as the database engine.
  445. *
  446. * Set in WPDB::db_connect() to true, by default. This is used when checking
  447. * against the required MySQL version for WordPress. Normally, a replacement
  448. * database drop-in (db.php) will skip these checks, but setting this to true
  449. * will force the checks to occur.
  450. *
  451. * @since 3.3.0
  452. * @access public
  453. * @var bool
  454. */
  455. public $is_mysql = null;
  456. /**
  457. * Connects to the database server and selects a database
  458. *
  459. * PHP5 style constructor for compatibility with PHP5. Does
  460. * the actual setting up of the class properties and connection
  461. * to the database.
  462. *
  463. * @link http://core.trac.wordpress.org/ticket/3354
  464. * @since 2.0.8
  465. *
  466. * @param string $dbuser MySQL database user
  467. * @param string $dbpassword MySQL database password
  468. * @param string $dbname MySQL database name
  469. * @param string $dbhost MySQL database host
  470. */
  471. function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
  472. register_shutdown_function( array( $this, '__destruct' ) );
  473. if ( WP_DEBUG && WP_DEBUG_DISPLAY )
  474. $this->show_errors();
  475. $this->init_charset();
  476. $this->dbuser = $dbuser;
  477. $this->dbpassword = $dbpassword;
  478. $this->dbname = $dbname;
  479. $this->dbhost = $dbhost;
  480. $this->db_connect();
  481. }
  482. /**
  483. * PHP5 style destructor and will run when database object is destroyed.
  484. *
  485. * @see wpdb::__construct()
  486. * @since 2.0.8
  487. * @return bool true
  488. */
  489. function __destruct() {
  490. return true;
  491. }
  492. /**
  493. * PHP5 style magic getter, used to lazy-load expensive data.
  494. *
  495. * @since 3.5.0
  496. *
  497. * @param string $name The private member to get, and optionally process
  498. * @return mixed The private member
  499. */
  500. function __get( $name ) {
  501. if ( 'col_info' == $name )
  502. $this->load_col_info();
  503. return $this->$name;
  504. }
  505. /**
  506. * Magic function, for backwards compatibility
  507. *
  508. * @since 3.5.0
  509. *
  510. * @param string $name The private member to set
  511. * @param mixed $value The value to set
  512. */
  513. function __set( $name, $value ) {
  514. $this->$name = $value;
  515. }
  516. /**
  517. * Magic function, for backwards compatibility
  518. *
  519. * @since 3.5.0
  520. *
  521. * @param string $name The private member to check
  522. *
  523. * @return bool If the member is set or not
  524. */
  525. function __isset( $name ) {
  526. return isset( $this->$name );
  527. }
  528. /**
  529. * Magic function, for backwards compatibility
  530. *
  531. * @since 3.5.0
  532. *
  533. * @param string $name The private member to unset
  534. */
  535. function __unset( $name ) {
  536. unset( $this->$name );
  537. }
  538. /**
  539. * Set $this->charset and $this->collate
  540. *
  541. * @since 3.1.0
  542. */
  543. function init_charset() {
  544. if ( function_exists('is_multisite') && is_multisite() ) {
  545. $this->charset = 'utf8';
  546. if ( defined( 'DB_COLLATE' ) && DB_COLLATE )
  547. $this->collate = DB_COLLATE;
  548. else
  549. $this->collate = 'utf8_general_ci';
  550. } elseif ( defined( 'DB_COLLATE' ) ) {
  551. $this->collate = DB_COLLATE;
  552. }
  553. if ( defined( 'DB_CHARSET' ) )
  554. $this->charset = DB_CHARSET;
  555. }
  556. /**
  557. * Sets the connection's character set.
  558. *
  559. * @since 3.1.0
  560. *
  561. * @param resource $dbh The resource given by mysql_connect
  562. * @param string $charset The character set (optional)
  563. * @param string $collate The collation (optional)
  564. */
  565. function set_charset( $dbh, $charset = null, $collate = null ) {
  566. if ( ! isset( $charset ) )
  567. $charset = $this->charset;
  568. if ( ! isset( $collate ) )
  569. $collate = $this->collate;
  570. if ( $this->has_cap( 'collation' ) && ! empty( $charset ) ) {
  571. if ( function_exists( 'mysql_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
  572. mysql_set_charset( $charset, $dbh );
  573. } else {
  574. $query = $this->prepare( 'SET NAMES %s', $charset );
  575. if ( ! empty( $collate ) )
  576. $query .= $this->prepare( ' COLLATE %s', $collate );
  577. mysql_query( $query, $dbh );
  578. }
  579. }
  580. }
  581. /**
  582. * Sets the table prefix for the WordPress tables.
  583. *
  584. * @since 2.5.0
  585. *
  586. * @param string $prefix Alphanumeric name for the new prefix.
  587. * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not.
  588. * @return string|WP_Error Old prefix or WP_Error on error
  589. */
  590. function set_prefix( $prefix, $set_table_names = true ) {
  591. if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
  592. return new WP_Error('invalid_db_prefix', 'Invalid database prefix' );
  593. $old_prefix = is_multisite() ? '' : $prefix;
  594. if ( isset( $this->base_prefix ) )
  595. $old_prefix = $this->base_prefix;
  596. $this->base_prefix = $prefix;
  597. if ( $set_table_names ) {
  598. foreach ( $this->tables( 'global' ) as $table => $prefixed_table )
  599. $this->$table = $prefixed_table;
  600. if ( is_multisite() && empty( $this->blogid ) )
  601. return $old_prefix;
  602. $this->prefix = $this->get_blog_prefix();
  603. foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
  604. $this->$table = $prefixed_table;
  605. foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
  606. $this->$table = $prefixed_table;
  607. }
  608. return $old_prefix;
  609. }
  610. /**
  611. * Sets blog id.
  612. *
  613. * @since 3.0.0
  614. * @access public
  615. * @param int $blog_id
  616. * @param int $site_id Optional.
  617. * @return string previous blog id
  618. */
  619. function set_blog_id( $blog_id, $site_id = 0 ) {
  620. if ( ! empty( $site_id ) )
  621. $this->siteid = $site_id;
  622. $old_blog_id = $this->blogid;
  623. $this->blogid = $blog_id;
  624. $this->prefix = $this->get_blog_prefix();
  625. foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
  626. $this->$table = $prefixed_table;
  627. foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
  628. $this->$table = $prefixed_table;
  629. return $old_blog_id;
  630. }
  631. /**
  632. * Gets blog prefix.
  633. *
  634. * @uses is_multisite()
  635. * @since 3.0.0
  636. * @param int $blog_id Optional.
  637. * @return string Blog prefix.
  638. */
  639. function get_blog_prefix( $blog_id = null ) {
  640. if ( is_multisite() ) {
  641. if ( null === $blog_id )
  642. $blog_id = $this->blogid;
  643. $blog_id = (int) $blog_id;
  644. if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) )
  645. return $this->base_prefix;
  646. else
  647. return $this->base_prefix . $blog_id . '_';
  648. } else {
  649. return $this->base_prefix;
  650. }
  651. }
  652. /**
  653. * Returns an array of WordPress tables.
  654. *
  655. * Also allows for the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE to
  656. * override the WordPress users and usermeta tables that would otherwise
  657. * be determined by the prefix.
  658. *
  659. * The scope argument can take one of the following:
  660. *
  661. * 'all' - returns 'all' and 'global' tables. No old tables are returned.
  662. * 'blog' - returns the blog-level tables for the queried blog.
  663. * 'global' - returns the global tables for the installation, returning multisite tables only if running multisite.
  664. * 'ms_global' - returns the multisite global tables, regardless if current installation is multisite.
  665. * 'old' - returns tables which are deprecated.
  666. *
  667. * @since 3.0.0
  668. * @uses wpdb::$tables
  669. * @uses wpdb::$old_tables
  670. * @uses wpdb::$global_tables
  671. * @uses wpdb::$ms_global_tables
  672. * @uses is_multisite()
  673. *
  674. * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all.
  675. * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog
  676. * prefix is requested, then the custom users and usermeta tables will be mapped.
  677. * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested.
  678. * @return array Table names. When a prefix is requested, the key is the unprefixed table name.
  679. */
  680. function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) {
  681. switch ( $scope ) {
  682. case 'all' :
  683. $tables = array_merge( $this->global_tables, $this->tables );
  684. if ( is_multisite() )
  685. $tables = array_merge( $tables, $this->ms_global_tables );
  686. break;
  687. case 'blog' :
  688. $tables = $this->tables;
  689. break;
  690. case 'global' :
  691. $tables = $this->global_tables;
  692. if ( is_multisite() )
  693. $tables = array_merge( $tables, $this->ms_global_tables );
  694. break;
  695. case 'ms_global' :
  696. $tables = $this->ms_global_tables;
  697. break;
  698. case 'old' :
  699. $tables = $this->old_tables;
  700. break;
  701. default :
  702. return array();
  703. break;
  704. }
  705. if ( $prefix ) {
  706. if ( ! $blog_id )
  707. $blog_id = $this->blogid;
  708. $blog_prefix = $this->get_blog_prefix( $blog_id );
  709. $base_prefix = $this->base_prefix;
  710. $global_tables = array_merge( $this->global_tables, $this->ms_global_tables );
  711. foreach ( $tables as $k => $table ) {
  712. if ( in_array( $table, $global_tables ) )
  713. $tables[ $table ] = $base_prefix . $table;
  714. else
  715. $tables[ $table ] = $blog_prefix . $table;
  716. unset( $tables[ $k ] );
  717. }
  718. if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) )
  719. $tables['users'] = CUSTOM_USER_TABLE;
  720. if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) )
  721. $tables['usermeta'] = CUSTOM_USER_META_TABLE;
  722. }
  723. return $tables;
  724. }
  725. /**
  726. * Selects a database using the current database connection.
  727. *
  728. * The database name will be changed based on the current database
  729. * connection. On failure, the execution will bail and display an DB error.
  730. *
  731. * @since 0.71
  732. *
  733. * @param string $db MySQL database name
  734. * @param resource $dbh Optional link identifier.
  735. * @return null Always null.
  736. */
  737. function select( $db, $dbh = null ) {
  738. if ( is_null($dbh) )
  739. $dbh = $this->dbh;
  740. if ( !@mysql_select_db( $db, $dbh ) ) {
  741. $this->ready = false;
  742. wp_load_translations_early();
  743. $this->bail( sprintf( __( '<h1>Can&#8217;t select database</h1>
  744. <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>
  745. <ul>
  746. <li>Are you sure it exists?</li>
  747. <li>Does the user <code>%2$s</code> have permission to use the <code>%1$s</code> database?</li>
  748. <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>
  749. </ul>
  750. <p>If you don\'t know how to set up 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>' ), htmlspecialchars( $db, ENT_QUOTES ), htmlspecialchars( $this->dbuser, ENT_QUOTES ) ), 'db_select_fail' );
  751. return;
  752. }
  753. }
  754. /**
  755. * Do not use, deprecated.
  756. *
  757. * Use esc_sql() or wpdb::prepare() instead.
  758. *
  759. * @since 2.8.0
  760. * @deprecated 3.6.0
  761. * @see wpdb::prepare
  762. * @see esc_sql()
  763. * @access private
  764. *
  765. * @param string $string
  766. * @return string
  767. */
  768. function _weak_escape( $string ) {
  769. if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) )
  770. _deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' );
  771. return addslashes( $string );
  772. }
  773. /**
  774. * Real escape, using mysql_real_escape_string()
  775. *
  776. * @see mysql_real_escape_string()
  777. * @since 2.8.0
  778. * @access private
  779. *
  780. * @param string $string to escape
  781. * @return string escaped
  782. */
  783. function _real_escape( $string ) {
  784. if ( $this->dbh )
  785. return mysql_real_escape_string( $string, $this->dbh );
  786. $class = get_class( $this );
  787. _doing_it_wrong( $class, "$class must set a database connection for use with escaping.", E_USER_NOTICE );
  788. return addslashes( $string );
  789. }
  790. /**
  791. * Escape data. Works on arrays.
  792. *
  793. * @uses wpdb::_real_escape()
  794. * @since 2.8.0
  795. * @access private
  796. *
  797. * @param string|array $data
  798. * @return string|array escaped
  799. */
  800. function _escape( $data ) {
  801. if ( is_array( $data ) ) {
  802. foreach ( $data as $k => $v ) {
  803. if ( is_array($v) )
  804. $data[$k] = $this->_escape( $v );
  805. else
  806. $data[$k] = $this->_real_escape( $v );
  807. }
  808. } else {
  809. $data = $this->_real_escape( $data );
  810. }
  811. return $data;
  812. }
  813. /**
  814. * Do not use, deprecated.
  815. *
  816. * Use esc_sql() or wpdb::prepare() instead.
  817. *
  818. * @since 0.71
  819. * @deprecated 3.6.0
  820. * @see wpdb::prepare()
  821. * @see esc_sql()
  822. *
  823. * @param mixed $data
  824. * @return mixed
  825. */
  826. function escape( $data ) {
  827. if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) )
  828. _deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' );
  829. if ( is_array( $data ) ) {
  830. foreach ( $data as $k => $v ) {
  831. if ( is_array( $v ) )
  832. $data[$k] = $this->escape( $v, 'recursive' );
  833. else
  834. $data[$k] = $this->_weak_escape( $v, 'internal' );
  835. }
  836. } else {
  837. $data = $this->_weak_escape( $data, 'internal' );
  838. }
  839. return $data;
  840. }
  841. /**
  842. * Escapes content by reference for insertion into the database, for security
  843. *
  844. * @uses wpdb::_real_escape()
  845. * @since 2.3.0
  846. * @param string $string to escape
  847. * @return void
  848. */
  849. function escape_by_ref( &$string ) {
  850. if ( ! is_float( $string ) )
  851. $string = $this->_real_escape( $string );
  852. }
  853. /**
  854. * Prepares a SQL query for safe execution. Uses sprintf()-like syntax.
  855. *
  856. * The following directives can be used in the query format string:
  857. * %d (integer)
  858. * %f (float)
  859. * %s (string)
  860. * %% (literal percentage sign - no argument needed)
  861. *
  862. * All of %d, %f, and %s are to be left unquoted in the query string and they need an argument passed for them.
  863. * Literals (%) as parts of the query must be properly written as %%.
  864. *
  865. * This function only supports a small subset of the sprintf syntax; it only supports %d (integer), %f (float), and %s (string).
  866. * Does not support sign, padding, alignment, width or precision specifiers.
  867. * Does not support argument numbering/swapping.
  868. *
  869. * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
  870. *
  871. * Both %d and %s should be left unquoted in the query string.
  872. *
  873. * <code>
  874. * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", 'foo', 1337 )
  875. * wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
  876. * </code>
  877. *
  878. * @link http://php.net/sprintf Description of syntax.
  879. * @since 2.3.0
  880. *
  881. * @param string $query Query statement with sprintf()-like placeholders
  882. * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like
  883. * {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if
  884. * being called like {@link http://php.net/sprintf sprintf()}.
  885. * @param mixed $args,... further variables to substitute into the query's placeholders if being called like
  886. * {@link http://php.net/sprintf sprintf()}.
  887. * @return null|false|string Sanitized query string, null if there is no query, false if there is an error and string
  888. * if there was something to prepare
  889. */
  890. function prepare( $query, $args ) {
  891. if ( is_null( $query ) )
  892. return;
  893. $args = func_get_args();
  894. array_shift( $args );
  895. // If args were passed as an array (as in vsprintf), move them up
  896. if ( isset( $args[0] ) && is_array($args[0]) )
  897. $args = $args[0];
  898. $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
  899. $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
  900. $query = preg_replace( '|(?<!%)%f|' , '%F', $query ); // Force floats to be locale unaware
  901. $query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s
  902. array_walk( $args, array( $this, 'escape_by_ref' ) );
  903. return @vsprintf( $query, $args );
  904. }
  905. /**
  906. * Print SQL/DB error.
  907. *
  908. * @since 0.71
  909. * @global array $EZSQL_ERROR Stores error information of query and error string
  910. *
  911. * @param string $str The error to display
  912. * @return bool False if the showing of errors is disabled.
  913. */
  914. function print_error( $str = '' ) {
  915. global $EZSQL_ERROR;
  916. if ( !$str )
  917. $str = mysql_error( $this->dbh );
  918. $EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str );
  919. if ( $this->suppress_errors )
  920. return false;
  921. wp_load_translations_early();
  922. if ( $caller = $this->get_caller() )
  923. $error_str = sprintf( __( 'WordPress database error %1$s for query %2$s made by %3$s' ), $str, $this->last_query, $caller );
  924. else
  925. $error_str = sprintf( __( 'WordPress database error %1$s for query %2$s' ), $str, $this->last_query );
  926. error_log( $error_str );
  927. // Are we showing errors?
  928. if ( ! $this->show_errors )
  929. return false;
  930. // If there is an error then take note of it
  931. if ( is_multisite() ) {
  932. $msg = "WordPress database error: [$str]\n{$this->last_query}\n";
  933. if ( defined( 'ERRORLOGFILE' ) )
  934. error_log( $msg, 3, ERRORLOGFILE );
  935. if ( defined( 'DIEONDBERROR' ) )
  936. wp_die( $msg );
  937. } else {
  938. $str = htmlspecialchars( $str, ENT_QUOTES );
  939. $query = htmlspecialchars( $this->last_query, ENT_QUOTES );
  940. print "<div id='error'>
  941. <p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br />
  942. <code>$query</code></p>
  943. </div>";
  944. }
  945. }
  946. /**
  947. * Enables showing of database errors.
  948. *
  949. * This function should be used only to enable showing of errors.
  950. * wpdb::hide_errors() should be used instead for hiding of errors. However,
  951. * this function can be used to enable and disable showing of database
  952. * errors.
  953. *
  954. * @since 0.71
  955. * @see wpdb::hide_errors()
  956. *
  957. * @param bool $show Whether to show or hide errors
  958. * @return bool Old value for showing errors.
  959. */
  960. function show_errors( $show = true ) {
  961. $errors = $this->show_errors;
  962. $this->show_errors = $show;
  963. return $errors;
  964. }
  965. /**
  966. * Disables showing of database errors.
  967. *
  968. * By default database errors are not shown.
  969. *
  970. * @since 0.71
  971. * @see wpdb::show_errors()
  972. *
  973. * @return bool Whether showing of errors was active
  974. */
  975. function hide_errors() {
  976. $show = $this->show_errors;
  977. $this->show_errors = false;
  978. return $show;
  979. }
  980. /**
  981. * Whether to suppress database errors.
  982. *
  983. * By default database errors are suppressed, with a simple
  984. * call to this function they can be enabled.
  985. *
  986. * @since 2.5.0
  987. * @see wpdb::hide_errors()
  988. * @param bool $suppress Optional. New value. Defaults to true.
  989. * @return bool Old value
  990. */
  991. function suppress_errors( $suppress = true ) {
  992. $errors = $this->suppress_errors;
  993. $this->suppress_errors = (bool) $suppress;
  994. return $errors;
  995. }
  996. /**
  997. * Kill cached query results.
  998. *
  999. * @since 0.71
  1000. * @return void
  1001. */
  1002. function flush() {
  1003. $this->last_result = array();
  1004. $this->col_info = null;
  1005. $this->last_query = null;
  1006. $this->rows_affected = $this->num_rows = 0;
  1007. $this->last_error = '';
  1008. if ( is_resource( $this->result ) )
  1009. mysql_free_result( $this->result );
  1010. }
  1011. /**
  1012. * Connect to and select database
  1013. *
  1014. * @since 3.0.0
  1015. */
  1016. function db_connect() {
  1017. $this->is_mysql = true;
  1018. $new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
  1019. $client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
  1020. if ( WP_DEBUG ) {
  1021. $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
  1022. } else {
  1023. $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
  1024. }
  1025. if ( !$this->dbh ) {
  1026. wp_load_translations_early();
  1027. $this->bail( sprintf( __( "
  1028. <h1>Error establishing a database connection</h1>
  1029. <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>
  1030. <ul>
  1031. <li>Are you sure you have the correct username and password?</li>
  1032. <li>Are you sure that you have typed the correct hostname?</li>
  1033. <li>Are you sure that the database server is running?</li>
  1034. </ul>
  1035. <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>
  1036. " ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
  1037. return;
  1038. }
  1039. $this->set_charset( $this->dbh );
  1040. $this->ready = true;
  1041. $this->select( $this->dbname, $this->dbh );
  1042. }
  1043. /**
  1044. * Perform a MySQL database query, using current database connection.
  1045. *
  1046. * More information can be found on the codex page.
  1047. *
  1048. * @since 0.71
  1049. *
  1050. * @param string $query Database query
  1051. * @return int|false Number of rows affected/selected or false on error
  1052. */
  1053. function query( $query ) {
  1054. if ( ! $this->ready )
  1055. return false;
  1056. /**
  1057. * Filter the database query.
  1058. *
  1059. * Some queries are made before the plugins have been loaded, and thus cannot be filtered with this method.
  1060. *
  1061. * @since 2.1.0
  1062. * @param string $query Database query.
  1063. */
  1064. $query = apply_filters( 'query', $query );
  1065. $return_val = 0;
  1066. $this->flush();
  1067. // Log how the function was called
  1068. $this->func_call = "\$db->query(\"$query\")";
  1069. // Keep track of the last query for debug..
  1070. $this->last_query = $query;
  1071. if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
  1072. $this->timer_start();
  1073. $this->result = @mysql_query( $query, $this->dbh );
  1074. $this->num_queries++;
  1075. if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
  1076. $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
  1077. // If there is an error then take note of it..
  1078. if ( $this->last_error = mysql_error( $this->dbh ) ) {
  1079. // Clear insert_id on a subsequent failed insert.
  1080. if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) )
  1081. $this->insert_id = 0;
  1082. $this->print_error();
  1083. return false;
  1084. }
  1085. if ( preg_match( '/^\s*(create|alter|truncate|drop)\s/i', $query ) ) {
  1086. $return_val = $this->result;
  1087. } elseif ( preg_match( '/^\s*(insert|delete|update|replace)\s/i', $query ) ) {
  1088. $this->rows_affected = mysql_affected_rows( $this->dbh );
  1089. // Take note of the insert_id
  1090. if ( preg_match( '/^\s*(insert|replace)\s/i', $query ) ) {
  1091. $this->insert_id = mysql_insert_id($this->dbh);
  1092. }
  1093. // Return number of rows affected
  1094. $return_val = $this->rows_affected;
  1095. } else {
  1096. $num_rows = 0;
  1097. while ( $row = @mysql_fetch_object( $this->result ) ) {
  1098. $this->last_result[$num_rows] = $row;
  1099. $num_rows++;
  1100. }
  1101. // Log number of rows the query returned
  1102. // and return number of rows selected
  1103. $this->num_rows = $num_rows;
  1104. $return_val = $num_rows;
  1105. }
  1106. return $return_val;
  1107. }
  1108. /**
  1109. * Insert a row into a table.
  1110. *
  1111. * <code>
  1112. * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
  1113. * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
  1114. * </code>
  1115. *
  1116. * @since 2.5.0
  1117. * @see wpdb::prepare()
  1118. * @see wpdb::$field_types
  1119. * @see wp_set_wpdb_vars()
  1120. *
  1121. * @param string $table table name
  1122. * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1123. * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data.
  1124. * A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1125. * @return int|false The number of rows inserted, or false on error.
  1126. */
  1127. function insert( $table, $data, $format = null ) {
  1128. return $this->_insert_replace_helper( $table, $data, $format, 'INSERT' );
  1129. }
  1130. /**
  1131. * Replace a row into a table.
  1132. *
  1133. * <code>
  1134. * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
  1135. * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
  1136. * </code>
  1137. *
  1138. * @since 3.0.0
  1139. * @see wpdb::prepare()
  1140. * @see wpdb::$field_types
  1141. * @see wp_set_wpdb_vars()
  1142. *
  1143. * @param string $table table name
  1144. * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1145. * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data.
  1146. * A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1147. * @return int|false The number of rows affected, or false on error.
  1148. */
  1149. function replace( $table, $data, $format = null ) {
  1150. return $this->_insert_replace_helper( $table, $data, $format, 'REPLACE' );
  1151. }
  1152. /**
  1153. * Helper function for insert and replace.
  1154. *
  1155. * Runs an insert or replace query based on $type argument.
  1156. *
  1157. * @access private
  1158. * @since 3.0.0
  1159. * @see wpdb::prepare()
  1160. * @see wpdb::$field_types
  1161. * @see wp_set_wpdb_vars()
  1162. *
  1163. * @param string $table table name
  1164. * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1165. * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data.
  1166. * A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1167. * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT.
  1168. * @return int|false The number of rows affected, or false on error.
  1169. */
  1170. function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) {
  1171. if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) )
  1172. return false;
  1173. $this->insert_id = 0;
  1174. $formats = $format = (array) $format;
  1175. $fields = array_keys( $data );
  1176. $formatted_fields = array();
  1177. foreach ( $fields as $field ) {
  1178. if ( !empty( $format ) )
  1179. $form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
  1180. elseif ( isset( $this->field_types[$field] ) )
  1181. $form = $this->field_types[$field];
  1182. else
  1183. $form = '%s';
  1184. $formatted_fields[] = $form;
  1185. }
  1186. $sql = "{$type} INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $formatted_fields ) . ")";
  1187. return $this->query( $this->prepare( $sql, $data ) );
  1188. }
  1189. /**
  1190. * Update a row in the table
  1191. *
  1192. * <code>
  1193. * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 'bar' ), array( 'ID' => 1 ) )
  1194. * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) )
  1195. * </code>
  1196. *
  1197. * @since 2.5.0
  1198. * @see wpdb::prepare()
  1199. * @see wpdb::$field_types
  1200. * @see wp_set_wpdb_vars()
  1201. *
  1202. * @param string $table table name
  1203. * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1204. * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
  1205. * @param array|string $format Optional. An array of formats to be mapped to each of the values in $data. If string, that format will be used for all of the values in $data.
  1206. * A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1207. * @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $where will be treated as strings.
  1208. * @return int|false The number of rows updated, or false on error.
  1209. */
  1210. function update( $table, $data, $where, $format = null, $where_format = null ) {
  1211. if ( ! is_array( $data ) || ! is_array( $where ) )
  1212. return false;
  1213. $formats = $format = (array) $format;
  1214. $bits = $wheres = array();
  1215. foreach ( (array) array_keys( $data ) as $field ) {
  1216. if ( !empty( $format ) )
  1217. $form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
  1218. elseif ( isset($this->field_types[$field]) )
  1219. $form = $this->field_types[$field];
  1220. else
  1221. $form = '%s';
  1222. $bits[] = "`$field` = {$form}";
  1223. }
  1224. $where_formats = $where_format = (array) $where_format;
  1225. foreach ( (array) array_keys( $where ) as $field ) {
  1226. if ( !empty( $where_format ) )
  1227. $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
  1228. elseif ( isset( $this->field_types[$field] ) )
  1229. $form = $this->field_types[$field];
  1230. else
  1231. $form = '%s';
  1232. $wheres[] = "`$field` = {$form}";
  1233. }
  1234. $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
  1235. return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) );
  1236. }
  1237. /**
  1238. * Delete a row in the table
  1239. *
  1240. * <code>
  1241. * wpdb::delete( 'table', array( 'ID' => 1 ) )
  1242. * wpdb::delete( 'table', array( 'ID' => 1 ), array( '%d' ) )
  1243. * </code>
  1244. *
  1245. * @since 3.4.0
  1246. * @see wpdb::prepare()
  1247. * @see wpdb::$field_types
  1248. * @see wp_set_wpdb_vars()
  1249. *
  1250. * @param string $table table name
  1251. * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
  1252. * @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $where will be treated as strings unless otherwise specified in wpdb::$field_types.
  1253. * @return int|false The number of rows updated, or false on error.
  1254. */
  1255. function delete( $table, $where, $where_format = null ) {
  1256. if ( ! is_array( $where ) )
  1257. return false;
  1258. $bits = $wheres = array();
  1259. $where_formats = $where_format = (array) $where_format;
  1260. foreach ( array_keys( $where ) as $field ) {
  1261. if ( !empty( $where_format ) ) {
  1262. $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
  1263. } elseif ( isset( $this->field_types[ $field ] ) ) {
  1264. $form = $this->field_types[ $field ];
  1265. } else {
  1266. $form = '%s';
  1267. }
  1268. $wheres[] = "$field = $form";
  1269. }
  1270. $sql = "DELETE FROM $table WHERE " . implode( ' AND ', $wheres );
  1271. return $this->query( $this->prepare( $sql, $where ) );
  1272. }
  1273. /**
  1274. * Retrieve one variable from the database.
  1275. *
  1276. * Executes a SQL query and returns the value from the SQL result.
  1277. * If the SQL result contains more than one column and/or more than one row, this function returns the value in the column and row specified.
  1278. * If $query is null, this function returns the value in the specified column and row from the previous SQL result.
  1279. *
  1280. * @since 0.71
  1281. *
  1282. * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query.
  1283. * @param int $x Optional. Column of value to return. Indexed from 0.
  1284. * @param int $y Optional. Row of value to return. Indexed from 0.
  1285. * @return string|null Database query result (as string), or null on failure
  1286. */
  1287. function get_var( $query = null, $x = 0, $y = 0 ) {
  1288. $this->func_call = "\$db->get_var(\"$query\", $x, $y)";
  1289. if ( $query )
  1290. $this->query( $query );
  1291. // Extract var out of cached results based x,y vals
  1292. if ( !empty( $this->last_result[$y] ) ) {
  1293. $values = array_values( get_object_vars( $this->last_result[$y] ) );
  1294. }
  1295. // If there is a value return it else return null
  1296. return ( isset( $values[$x] ) && $values[$x] !== '' ) ? $values[$x] : null;
  1297. }
  1298. /**
  1299. * Retrieve one row from the database.
  1300. *
  1301. * Executes a SQL query and returns the row from the SQL result.
  1302. *
  1303. * @since 0.71
  1304. *
  1305. * @param string|null $query SQL query.
  1306. * @param string $output Optional. one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...),
  1307. * a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively.
  1308. * @param int $y Optional. Row to return. Indexed from 0.
  1309. * @return mixed Database query result in format specified by $output or null on failure
  1310. */
  1311. function get_row( $query = null, $output = OBJECT, $y = 0 ) {
  1312. $this->func_call = "\$db->get_row(\"$query\",$output,$y)";
  1313. if ( $query )
  1314. $this->query( $query );
  1315. else
  1316. return null;
  1317. if ( !isset( $this->last_result[$y] ) )
  1318. return null;
  1319. if ( $output == OBJECT ) {
  1320. return $this->last_result[$y] ? $this->last_result[$y] : null;
  1321. } elseif ( $output == ARRAY_A ) {
  1322. return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null;
  1323. } elseif ( $output == ARRAY_N ) {
  1324. return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null;
  1325. } else {
  1326. $this->print_error( " \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" );
  1327. }
  1328. }
  1329. /**
  1330. * Retrieve one column from the database.
  1331. *
  1332. * Executes a SQL query and returns the column from the SQL result.
  1333. * If the SQL result contains more than one column, this function returns the column specified.
  1334. * If $query is null, this function returns the specified column from the previous SQL result.
  1335. *
  1336. * @since 0.71
  1337. *
  1338. * @param string|null $query Optional. SQL query. Defaults to previous query.
  1339. * @param int $x Optional. Column to return. Indexed from 0.
  1340. * @return array Database query result. Array indexed from 0 by SQL result row number.
  1341. */
  1342. function get_col( $query = null , $x = 0 ) {
  1343. if ( $query )
  1344. $this->query( $query );
  1345. $new_array = array();
  1346. // Extract the column values
  1347. for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
  1348. $new_array[$i] = $this->get_var( null, $x, $i );
  1349. }
  1350. return $new_array;
  1351. }
  1352. /**
  1353. * Retrieve an entire SQL result set from the database (i.e., many rows)
  1354. *
  1355. * Executes a SQL query and returns the entire SQL result.
  1356. *
  1357. * @since 0.71
  1358. *
  1359. * @param string $query SQL query.
  1360. * @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants. With one of the first three, return an array of rows indexed from 0 by SQL result row number.
  1361. * Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively.
  1362. * With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value. Duplicate keys are discarded.
  1363. * @return mixed Database query results
  1364. */
  1365. function get_results( $query = null, $output = OBJECT ) {
  1366. $this->func_call = "\$db->get_results(\"$query\", $output)";
  1367. if ( $query )
  1368. $this->query( $query );
  1369. else
  1370. return null;
  1371. $new_array = array();
  1372. if ( $output == OBJECT ) {
  1373. // Return an integer-keyed array of row objects
  1374. return $this->last_result;
  1375. } elseif ( $output == OBJECT_K ) {
  1376. // Return an array of row objects with keys from column 1
  1377. // (Duplicates are discarded)
  1378. foreach ( $this->last_result as $row ) {
  1379. $var_by_ref = get_object_vars( $row );
  1380. $key = array_shift( $var_by_ref );
  1381. if ( ! isset( $new_array[ $key ] ) )
  1382. $new_array[ $key ] = $row;
  1383. }
  1384. return $new_array;
  1385. } elseif ( $output == ARRAY_A || $output == ARRAY_N ) {
  1386. // Return an integer-keyed array of...
  1387. if ( $this->last_result ) {
  1388. foreach( (array) $this->last_result as $row ) {
  1389. if ( $output == ARRAY_N ) {
  1390. // ...integer-keyed row arrays
  1391. $new_array[] = array_values( get_object_vars( $row ) );
  1392. } else {
  1393. // ...column name-keyed row arrays
  1394. $new_array[] = get_object_vars( $row );
  1395. }
  1396. }
  1397. }
  1398. return $new_array;
  1399. }
  1400. return null;
  1401. }
  1402. /**
  1403. * Load the column metadata from the last query.
  1404. *
  1405. * @since 3.5.0
  1406. *
  1407. * @access protected
  1408. */
  1409. protected function load_col_info() {
  1410. if ( $this->col_info )
  1411. return;
  1412. for ( $i = 0; $i < @mysql_num_fields( $this->result ); $i++ ) {
  1413. $this->col_info[ $i ] = @mysql_fetch_field( $this->result, $i );
  1414. }
  1415. }
  1416. /**
  1417. * Retrieve column metadata from the last query.
  1418. *
  1419. * @since 0.71
  1420. *
  1421. * @param string $info_type Optional. Type one of name, table, def, max_length, not_null, primary_key, multiple_key, unique_key, numeric, blob, type, unsigned, zerofill
  1422. * @param int $col_offset Optional. 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
  1423. * @return mixed Column Results
  1424. */
  1425. function get_col_info( $info_type = 'name', $col_offset = -1 ) {
  1426. $this->load_col_info();
  1427. if ( $this->col_info ) {
  1428. if ( $col_offset == -1 ) {
  1429. $i = 0;
  1430. $new_array = array();
  1431. foreach( (array) $this->col_info as $col ) {
  1432. $new_array[$i] = $col->{$info_type};
  1433. $i++;
  1434. }
  1435. return $new_array;
  1436. } else {
  1437. return $this->col_info[$col_offset]->{$info_type};
  1438. }
  1439. }
  1440. }
  1441. /**
  1442. * Starts the timer, for debugging purposes.
  1443. *
  1444. * @since 1.5.0
  1445. *
  1446. * @return true
  1447. */
  1448. function timer_start() {
  1449. $this->time_start = microtime( true );
  1450. return true;
  1451. }
  1452. /**
  1453. * Stops the debugging timer.
  1454. *
  1455. * @since 1.5.0
  1456. *
  1457. * @return float Total time spent on the query, in seconds
  1458. */
  1459. function timer_stop() {
  1460. return ( microtime( true ) - $this->time_start );
  1461. }
  1462. /**
  1463. * Wraps errors in a nice header and footer and dies.
  1464. *
  1465. * Will not die if wpdb::$show_errors is false.
  1466. *
  1467. * @since 1.5.0
  1468. *
  1469. * @param string $message The Error message
  1470. * @param string $error_code Optional. A Computer readable string to identify the error.
  1471. * @return false|void
  1472. */
  1473. function bail( $message, $error_code = '500' ) {
  1474. if ( !$this->show_errors ) {
  1475. if ( class_exists( 'WP_Error' ) )
  1476. $this->error = new WP_Error($error_code, $message);
  1477. else
  1478. $this->error = $message;
  1479. return false;
  1480. }
  1481. wp_die($message);
  1482. }
  1483. /**
  1484. * Whether MySQL database is at least the required minimum version.
  1485. *
  1486. * @since 2.5.0
  1487. * @uses $wp_version
  1488. * @uses $required_mysql_version
  1489. *
  1490. * @return WP_Error
  1491. */
  1492. function check_database_version() {
  1493. global $wp_version, $required_mysql_version;
  1494. // Make sure the server has the required MySQL version
  1495. if ( version_compare($this->db_version(), $required_mysql_version, '<') )
  1496. return new WP_Error('database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ));
  1497. }
  1498. /**
  1499. * Whether the database supports collation.
  1500. *
  1501. * Called when WordPress is generating the table scheme.
  1502. *
  1503. * @since 2.5.0
  1504. * @deprecated 3.5.0
  1505. * @deprecated Use wpdb::has_cap( 'collation' )
  1506. *
  1507. * @return bool True if collation is supported, false if version does not
  1508. */
  1509. function supports_collation() {
  1510. _deprecated_function( __FUNCTION__, '3.5', 'wpdb::has_cap( \'collation\' )' );
  1511. return $this->has_cap( 'collation' );
  1512. }
  1513. /**
  1514. * The database character collate.
  1515. *
  1516. * @since 3.5.0
  1517. *
  1518. * @return string The database character collate.
  1519. */
  1520. public function get_charset_collate() {
  1521. $charset_collate = '';
  1522. if ( ! empty( $this->charset ) )
  1523. $charset_collate = "DEFAULT CHARACTER SET $this->charset";
  1524. if ( ! empty( $this->collate ) )
  1525. $charset_collate .= " COLLATE $this->collate";
  1526. return $charset_collate;
  1527. }
  1528. /**
  1529. * Determine if a database supports a particular feature.
  1530. *
  1531. * @since 2.7.0
  1532. * @see wpdb::db_version()
  1533. *
  1534. * @param string $db_cap The feature to check for.
  1535. * @return bool
  1536. */
  1537. function has_cap( $db_cap ) {
  1538. $version = $this->db_version();
  1539. switch ( strtolower( $db_cap ) ) {
  1540. case 'collation' : // @since 2.5.0
  1541. case 'group_concat' : // @since 2.7.0
  1542. case 'subqueries' : // @since 2.7.0
  1543. return version_compare( $version, '4.1', '>=' );
  1544. case 'set_charset' :
  1545. return version_compare( $version, '5.0.7', '>=' );
  1546. };
  1547. return false;
  1548. }
  1549. /**
  1550. * Retrieve the name of the function that called wpdb.
  1551. *
  1552. * Searches up the list of functions until it reaches
  1553. * the one that would most logically had called this method.
  1554. *
  1555. * @since 2.5.0
  1556. *
  1557. * @return string The name of the calling function
  1558. */
  1559. function get_caller() {
  1560. return wp_debug_backtrace_summary( __CLASS__ );
  1561. }
  1562. /**
  1563. * The database version number.
  1564. *
  1565. * @since 2.7.0
  1566. *
  1567. * @return false|string false on failure, version number on success
  1568. */
  1569. function db_version() {
  1570. return preg_replace( '/[^0-9.].*/', '', mysql_get_server_info( $this->dbh ) );
  1571. }
  1572. }