Advertisement
Guest User

Untitled

a guest
Jan 15th, 2016
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 61.39 KB | None | 0 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. /**
  13. * @since 0.71
  14. */
  15. define( 'EZSQL_VERSION', 'WP1.25' );
  16.  
  17. /**
  18. * @since 0.71
  19. */
  20. define( 'OBJECT', 'OBJECT' );
  21. define( 'object', 'OBJECT' ); // Back compat.
  22.  
  23. /**
  24. * @since 2.5.0
  25. */
  26. define( 'OBJECT_K', 'OBJECT_K' );
  27.  
  28. /**
  29. * @since 0.71
  30. */
  31. define( 'ARRAY_A', 'ARRAY_A' );
  32.  
  33. /**
  34. * @since 0.71
  35. */
  36. define( 'ARRAY_N', 'ARRAY_N' );
  37.  
  38. /**
  39. * WordPress Database Access Abstraction Object
  40. *
  41. * It is possible to replace this class with your own
  42. * by setting the $wpdb global variable in wp-content/db.php
  43. * file to your class. The wpdb class will still be included,
  44. * so you can extend it or simply use your own.
  45. *
  46. * @link http://codex.wordpress.org/Function_Reference/wpdb_Class
  47. *
  48. * @package WordPress
  49. * @subpackage Database
  50. * @since 0.71
  51. */
  52. class wpdb {
  53.  
  54. /**
  55. * Whether to show SQL/DB errors.
  56. *
  57. * Default behavior is to show errors if both WP_DEBUG and WP_DEBUG_DISPLAY
  58. * evaluated to true.
  59. *
  60. * @since 0.71
  61. * @access private
  62. * @var bool
  63. */
  64. var $show_errors = false;
  65.  
  66. /**
  67. * Whether to suppress errors during the DB bootstrapping.
  68. *
  69. * @access private
  70. * @since 2.5.0
  71. * @var bool
  72. */
  73. var $suppress_errors = false;
  74.  
  75. /**
  76. * The last error during query.
  77. *
  78. * @since 2.5.0
  79. * @var string
  80. */
  81. public $last_error = '';
  82.  
  83. /**
  84. * Amount of queries made
  85. *
  86. * @since 1.2.0
  87. * @access private
  88. * @var int
  89. */
  90. var $num_queries = 0;
  91.  
  92. /**
  93. * Count of rows returned by previous query
  94. *
  95. * @since 0.71
  96. * @access private
  97. * @var int
  98. */
  99. var $num_rows = 0;
  100.  
  101. /**
  102. * Count of affected rows by previous query
  103. *
  104. * @since 0.71
  105. * @access private
  106. * @var int
  107. */
  108. var $rows_affected = 0;
  109.  
  110. /**
  111. * The ID generated for an AUTO_INCREMENT column by the previous query (usually INSERT).
  112. *
  113. * @since 0.71
  114. * @access public
  115. * @var int
  116. */
  117. var $insert_id = 0;
  118.  
  119. /**
  120. * Last query made
  121. *
  122. * @since 0.71
  123. * @access private
  124. * @var array
  125. */
  126. var $last_query;
  127.  
  128. /**
  129. * Results of the last query made
  130. *
  131. * @since 0.71
  132. * @access private
  133. * @var array|null
  134. */
  135. var $last_result;
  136.  
  137. /**
  138. * MySQL result, which is either a resource or boolean.
  139. *
  140. * @since 0.71
  141. * @access protected
  142. * @var mixed
  143. */
  144. protected $result;
  145.  
  146. /**
  147. * Saved info on the table column
  148. *
  149. * @since 0.71
  150. * @access protected
  151. * @var array
  152. */
  153. protected $col_info;
  154.  
  155. /**
  156. * Saved queries that were executed
  157. *
  158. * @since 1.5.0
  159. * @access private
  160. * @var array
  161. */
  162. var $queries;
  163.  
  164. /**
  165. * The number of times to retry reconnecting before dying.
  166. *
  167. * @since 3.9.0
  168. * @access protected
  169. * @see wpdb::check_connection()
  170. * @var int
  171. */
  172. protected $reconnect_retries = 5;
  173.  
  174. /**
  175. * WordPress table prefix
  176. *
  177. * You can set this to have multiple WordPress installations
  178. * in a single database. The second reason is for possible
  179. * security precautions.
  180. *
  181. * @since 2.5.0
  182. * @access private
  183. * @var string
  184. */
  185. var $prefix = '';
  186.  
  187. /**
  188. * WordPress base table prefix.
  189. *
  190. * @since 3.0.0
  191. * @access public
  192. * @var string
  193. */
  194. public $base_prefix;
  195.  
  196. /**
  197. * Whether the database queries are ready to start executing.
  198. *
  199. * @since 2.3.2
  200. * @access private
  201. * @var bool
  202. */
  203. var $ready = false;
  204.  
  205. /**
  206. * {@internal Missing Description}}
  207. *
  208. * @since 3.0.0
  209. * @access public
  210. * @var int
  211. */
  212. public $blogid = 0;
  213.  
  214. /**
  215. * {@internal Missing Description}}
  216. *
  217. * @since 3.0.0
  218. * @access public
  219. * @var int
  220. */
  221. public $siteid = 0;
  222.  
  223. /**
  224. * List of WordPress per-blog tables
  225. *
  226. * @since 2.5.0
  227. * @access private
  228. * @see wpdb::tables()
  229. * @var array
  230. */
  231. var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta',
  232. 'terms', 'term_taxonomy', 'term_relationships', 'commentmeta' );
  233.  
  234. /**
  235. * List of deprecated WordPress tables
  236. *
  237. * categories, post2cat, and link2cat were deprecated in 2.3.0, db version 5539
  238. *
  239. * @since 2.9.0
  240. * @access private
  241. * @see wpdb::tables()
  242. * @var array
  243. */
  244. var $old_tables = array( 'categories', 'post2cat', 'link2cat' );
  245.  
  246. /**
  247. * List of WordPress global tables
  248. *
  249. * @since 3.0.0
  250. * @access private
  251. * @see wpdb::tables()
  252. * @var array
  253. */
  254. var $global_tables = array( 'users', 'usermeta' );
  255.  
  256. /**
  257. * List of Multisite global tables
  258. *
  259. * @since 3.0.0
  260. * @access private
  261. * @see wpdb::tables()
  262. * @var array
  263. */
  264. var $ms_global_tables = array( 'blogs', 'signups', 'site', 'sitemeta',
  265. 'sitecategories', 'registration_log', 'blog_versions' );
  266.  
  267. /**
  268. * WordPress Comments table
  269. *
  270. * @since 1.5.0
  271. * @access public
  272. * @var string
  273. */
  274. public $comments;
  275.  
  276. /**
  277. * WordPress Comment Metadata table
  278. *
  279. * @since 2.9.0
  280. * @access public
  281. * @var string
  282. */
  283. public $commentmeta;
  284.  
  285. /**
  286. * WordPress Links table
  287. *
  288. * @since 1.5.0
  289. * @access public
  290. * @var string
  291. */
  292. public $links;
  293.  
  294. /**
  295. * WordPress Options table
  296. *
  297. * @since 1.5.0
  298. * @access public
  299. * @var string
  300. */
  301. public $options;
  302.  
  303. /**
  304. * WordPress Post Metadata table
  305. *
  306. * @since 1.5.0
  307. * @access public
  308. * @var string
  309. */
  310. public $postmeta;
  311.  
  312. /**
  313. * WordPress Posts table
  314. *
  315. * @since 1.5.0
  316. * @access public
  317. * @var string
  318. */
  319. public $posts;
  320.  
  321. /**
  322. * WordPress Terms table
  323. *
  324. * @since 2.3.0
  325. * @access public
  326. * @var string
  327. */
  328. public $terms;
  329.  
  330. /**
  331. * WordPress Term Relationships table
  332. *
  333. * @since 2.3.0
  334. * @access public
  335. * @var string
  336. */
  337. public $term_relationships;
  338.  
  339. /**
  340. * WordPress Term Taxonomy table
  341. *
  342. * @since 2.3.0
  343. * @access public
  344. * @var string
  345. */
  346. public $term_taxonomy;
  347.  
  348. /*
  349. * Global and Multisite tables
  350. */
  351.  
  352. /**
  353. * WordPress User Metadata table
  354. *
  355. * @since 2.3.0
  356. * @access public
  357. * @var string
  358. */
  359. public $usermeta;
  360.  
  361. /**
  362. * WordPress Users table
  363. *
  364. * @since 1.5.0
  365. * @access public
  366. * @var string
  367. */
  368. public $users;
  369.  
  370. /**
  371. * Multisite Blogs table
  372. *
  373. * @since 3.0.0
  374. * @access public
  375. * @var string
  376. */
  377. public $blogs;
  378.  
  379. /**
  380. * Multisite Blog Versions table
  381. *
  382. * @since 3.0.0
  383. * @access public
  384. * @var string
  385. */
  386. public $blog_versions;
  387.  
  388. /**
  389. * Multisite Registration Log table
  390. *
  391. * @since 3.0.0
  392. * @access public
  393. * @var string
  394. */
  395. public $registration_log;
  396.  
  397. /**
  398. * Multisite Signups table
  399. *
  400. * @since 3.0.0
  401. * @access public
  402. * @var string
  403. */
  404. public $signups;
  405.  
  406. /**
  407. * Multisite Sites table
  408. *
  409. * @since 3.0.0
  410. * @access public
  411. * @var string
  412. */
  413. public $site;
  414.  
  415. /**
  416. * Multisite Sitewide Terms table
  417. *
  418. * @since 3.0.0
  419. * @access public
  420. * @var string
  421. */
  422. public $sitecategories;
  423.  
  424. /**
  425. * Multisite Site Metadata table
  426. *
  427. * @since 3.0.0
  428. * @access public
  429. * @var string
  430. */
  431. public $sitemeta;
  432.  
  433. /**
  434. * Format specifiers for DB columns. Columns not listed here default to %s. Initialized during WP load.
  435. *
  436. * Keys are column names, values are format types: 'ID' => '%d'
  437. *
  438. * @since 2.8.0
  439. * @see wpdb::prepare()
  440. * @see wpdb::insert()
  441. * @see wpdb::update()
  442. * @see wpdb::delete()
  443. * @see wp_set_wpdb_vars()
  444. * @access public
  445. * @var array
  446. */
  447. public $field_types = array();
  448.  
  449. /**
  450. * Database table columns charset
  451. *
  452. * @since 2.2.0
  453. * @access public
  454. * @var string
  455. */
  456. public $charset;
  457.  
  458. /**
  459. * Database table columns collate
  460. *
  461. * @since 2.2.0
  462. * @access public
  463. * @var string
  464. */
  465. public $collate;
  466.  
  467. /**
  468. * Database Username
  469. *
  470. * @since 2.9.0
  471. * @access protected
  472. * @var string
  473. */
  474. protected $dbuser;
  475.  
  476. /**
  477. * Database Password
  478. *
  479. * @since 3.1.0
  480. * @access protected
  481. * @var string
  482. */
  483. protected $dbpassword;
  484.  
  485. /**
  486. * Database Name
  487. *
  488. * @since 3.1.0
  489. * @access protected
  490. * @var string
  491. */
  492. protected $dbname;
  493.  
  494. /**
  495. * Database Host
  496. *
  497. * @since 3.1.0
  498. * @access protected
  499. * @var string
  500. */
  501. protected $dbhost;
  502.  
  503. /**
  504. * Database Handle
  505. *
  506. * @since 0.71
  507. * @access protected
  508. * @var string
  509. */
  510. protected $dbh;
  511.  
  512. /**
  513. * A textual description of the last query/get_row/get_var call
  514. *
  515. * @since 3.0.0
  516. * @access public
  517. * @var string
  518. */
  519. public $func_call;
  520.  
  521. /**
  522. * Whether MySQL is used as the database engine.
  523. *
  524. * Set in WPDB::db_connect() to true, by default. This is used when checking
  525. * against the required MySQL version for WordPress. Normally, a replacement
  526. * database drop-in (db.php) will skip these checks, but setting this to true
  527. * will force the checks to occur.
  528. *
  529. * @since 3.3.0
  530. * @access public
  531. * @var bool
  532. */
  533. public $is_mysql = null;
  534.  
  535. /**
  536. * A list of incompatible SQL modes.
  537. *
  538. * @since 3.9.0
  539. * @access protected
  540. * @var array
  541. */
  542. protected $incompatible_modes = array( 'NO_ZERO_DATE', 'ONLY_FULL_GROUP_BY',
  543. 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'TRADITIONAL' );
  544.  
  545. /**
  546. * Whether to use mysqli over mysql.
  547. *
  548. * @since 3.9.0
  549. * @access private
  550. * @var bool
  551. */
  552. private $use_mysqli = false;
  553.  
  554. /**
  555. * Whether we've managed to successfully connect at some point
  556. *
  557. * @since 3.9.0
  558. * @access private
  559. * @var bool
  560. */
  561. private $has_connected = false;
  562.  
  563. /**
  564. * Connects to the database server and selects a database
  565. *
  566. * PHP5 style constructor for compatibility with PHP5. Does
  567. * the actual setting up of the class properties and connection
  568. * to the database.
  569. *
  570. * @link http://core.trac.wordpress.org/ticket/3354
  571. * @since 2.0.8
  572. *
  573. * @param string $dbuser MySQL database user
  574. * @param string $dbpassword MySQL database password
  575. * @param string $dbname MySQL database name
  576. * @param string $dbhost MySQL database host
  577. */
  578. public function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
  579. register_shutdown_function( array( $this, '__destruct' ) );
  580.  
  581. if ( WP_DEBUG && WP_DEBUG_DISPLAY )
  582. $this->show_errors();
  583.  
  584. /* Use ext/mysqli if it exists and:
  585. * - WP_USE_EXT_MYSQL is defined as false, or
  586. * - We are a development version of WordPress, or
  587. * - We are running PHP 5.5 or greater, or
  588. * - ext/mysql is not loaded.
  589. */
  590. if ( function_exists( 'mysqli_connect' ) ) {
  591. if ( defined( 'WP_USE_EXT_MYSQL' ) ) {
  592. $this->use_mysqli = ! WP_USE_EXT_MYSQL;
  593. } elseif ( version_compare( phpversion(), '5.5', '>=' ) || ! function_exists( 'mysql_connect' ) ) {
  594. $this->use_mysqli = true;
  595. } elseif ( false !== strpos( $GLOBALS['wp_version'], '-' ) ) {
  596. $this->use_mysqli = true;
  597. }
  598. }
  599.  
  600. $this->init_charset();
  601.  
  602. $this->dbuser = $dbuser;
  603. $this->dbpassword = $dbpassword;
  604. $this->dbname = $dbname;
  605. $this->dbhost = $dbhost;
  606.  
  607. // wp-config.php creation will manually connect when ready.
  608. if ( defined( 'WP_SETUP_CONFIG' ) ) {
  609. return;
  610. }
  611.  
  612. $this->db_connect();
  613. }
  614.  
  615. /**
  616. * PHP5 style destructor and will run when database object is destroyed.
  617. *
  618. * @see wpdb::__construct()
  619. * @since 2.0.8
  620. * @return bool true
  621. */
  622. public function __destruct() {
  623. return true;
  624. }
  625.  
  626. /**
  627. * PHP5 style magic getter, used to lazy-load expensive data.
  628. *
  629. * @since 3.5.0
  630. *
  631. * @param string $name The private member to get, and optionally process
  632. * @return mixed The private member
  633. */
  634. public function __get( $name ) {
  635. if ( 'col_info' == $name )
  636. $this->load_col_info();
  637.  
  638. return $this->$name;
  639. }
  640.  
  641. /**
  642. * Magic function, for backwards compatibility.
  643. *
  644. * @since 3.5.0
  645. *
  646. * @param string $name The private member to set
  647. * @param mixed $value The value to set
  648. */
  649. public function __set( $name, $value ) {
  650. $this->$name = $value;
  651. }
  652.  
  653. /**
  654. * Magic function, for backwards compatibility.
  655. *
  656. * @since 3.5.0
  657. *
  658. * @param string $name The private member to check
  659. *
  660. * @return bool If the member is set or not
  661. */
  662. public function __isset( $name ) {
  663. return isset( $this->$name );
  664. }
  665.  
  666. /**
  667. * Magic function, for backwards compatibility.
  668. *
  669. * @since 3.5.0
  670. *
  671. * @param string $name The private member to unset
  672. */
  673. public function __unset( $name ) {
  674. unset( $this->$name );
  675. }
  676.  
  677. /**
  678. * Set $this->charset and $this->collate
  679. *
  680. * @since 3.1.0
  681. */
  682. public function init_charset() {
  683. if ( function_exists('is_multisite') && is_multisite() ) {
  684. $this->charset = 'utf8';
  685. if ( defined( 'DB_COLLATE' ) && DB_COLLATE )
  686. $this->collate = DB_COLLATE;
  687. else
  688. $this->collate = 'utf8_general_ci';
  689. } elseif ( defined( 'DB_COLLATE' ) ) {
  690. $this->collate = DB_COLLATE;
  691. }
  692.  
  693. if ( defined( 'DB_CHARSET' ) )
  694. $this->charset = DB_CHARSET;
  695. }
  696.  
  697. /**
  698. * Sets the connection's character set.
  699. *
  700. * @since 3.1.0
  701. *
  702. * @param resource $dbh The resource given by mysql_connect
  703. * @param string $charset The character set (optional)
  704. * @param string $collate The collation (optional)
  705. */
  706. public function set_charset( $dbh, $charset = null, $collate = null ) {
  707. if ( ! isset( $charset ) )
  708. $charset = $this->charset;
  709. if ( ! isset( $collate ) )
  710. $collate = $this->collate;
  711. if ( $this->has_cap( 'collation' ) && ! empty( $charset ) ) {
  712. if ( $this->use_mysqli ) {
  713. if ( function_exists( 'mysqli_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
  714. mysqli_set_charset( $dbh, $charset );
  715. } else {
  716. $query = $this->prepare( 'SET NAMES %s', $charset );
  717. if ( ! empty( $collate ) )
  718. $query .= $this->prepare( ' COLLATE %s', $collate );
  719. mysqli_query( $query, $dbh );
  720. }
  721. } else {
  722. if ( function_exists( 'mysql_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
  723. mysql_set_charset( $charset, $dbh );
  724. } else {
  725. $query = $this->prepare( 'SET NAMES %s', $charset );
  726. if ( ! empty( $collate ) )
  727. $query .= $this->prepare( ' COLLATE %s', $collate );
  728. mysql_query( $query, $dbh );
  729. }
  730. }
  731. }
  732. }
  733.  
  734. /**
  735. * Change the current SQL mode, and ensure its WordPress compatibility.
  736. *
  737. * If no modes are passed, it will ensure the current MySQL server
  738. * modes are compatible.
  739. *
  740. * @since 3.9.0
  741. *
  742. * @param array $modes Optional. A list of SQL modes to set.
  743. */
  744. public function set_sql_mode( $modes = array() ) {
  745. if ( empty( $modes ) ) {
  746. if ( $this->use_mysqli ) {
  747. $res = mysqli_query( $this->dbh, 'SELECT @@SESSION.sql_mode' );
  748. } else {
  749. $res = mysql_query( 'SELECT @@SESSION.sql_mode', $this->dbh );
  750. }
  751.  
  752. if ( empty( $res ) ) {
  753. return;
  754. }
  755.  
  756. if ( $this->use_mysqli ) {
  757. $modes_array = mysqli_fetch_array( $res );
  758. if ( empty( $modes_array[0] ) ) {
  759. return;
  760. }
  761. $modes_str = $modes_array[0];
  762. } else {
  763. $modes_str = mysql_result( $res, 0 );
  764. }
  765.  
  766. if ( empty( $modes_str ) ) {
  767. return;
  768. }
  769.  
  770. $modes = explode( ',', $modes_str );
  771. }
  772.  
  773. $modes = array_change_key_case( $modes, CASE_UPPER );
  774.  
  775. /**
  776. * Filter the list of incompatible SQL modes to exclude.
  777. *
  778. * @since 3.9.0
  779. *
  780. * @see wpdb::$incompatible_modes
  781. *
  782. * @param array $incompatible_modes An array of incompatible modes.
  783. */
  784. $incompatible_modes = (array) apply_filters( 'incompatible_sql_modes', $this->incompatible_modes );
  785.  
  786. foreach( $modes as $i => $mode ) {
  787. if ( in_array( $mode, $incompatible_modes ) ) {
  788. unset( $modes[ $i ] );
  789. }
  790. }
  791.  
  792. $modes_str = implode( ',', $modes );
  793.  
  794. if ( $this->use_mysqli ) {
  795. mysqli_query( $this->dbh, "SET SESSION sql_mode='$modes_str'" );
  796. } else {
  797. mysql_query( "SET SESSION sql_mode='$modes_str'", $this->dbh );
  798. }
  799. }
  800.  
  801. /**
  802. * Sets the table prefix for the WordPress tables.
  803. *
  804. * @since 2.5.0
  805. *
  806. * @param string $prefix Alphanumeric name for the new prefix.
  807. * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not.
  808. * @return string|WP_Error Old prefix or WP_Error on error
  809. */
  810. public function set_prefix( $prefix, $set_table_names = true ) {
  811.  
  812. if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
  813. return new WP_Error('invalid_db_prefix', 'Invalid database prefix' );
  814.  
  815. $old_prefix = is_multisite() ? '' : $prefix;
  816.  
  817. if ( isset( $this->base_prefix ) )
  818. $old_prefix = $this->base_prefix;
  819.  
  820. $this->base_prefix = $prefix;
  821.  
  822. if ( $set_table_names ) {
  823. foreach ( $this->tables( 'global' ) as $table => $prefixed_table )
  824. $this->$table = $prefixed_table;
  825.  
  826. if ( is_multisite() && empty( $this->blogid ) )
  827. return $old_prefix;
  828.  
  829. $this->prefix = $this->get_blog_prefix();
  830.  
  831. foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
  832. $this->$table = $prefixed_table;
  833.  
  834. foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
  835. $this->$table = $prefixed_table;
  836. }
  837. return $old_prefix;
  838. }
  839.  
  840. /**
  841. * Sets blog id.
  842. *
  843. * @since 3.0.0
  844. * @access public
  845. * @param int $blog_id
  846. * @param int $site_id Optional.
  847. * @return string previous blog id
  848. */
  849. public function set_blog_id( $blog_id, $site_id = 0 ) {
  850. if ( ! empty( $site_id ) )
  851. $this->siteid = $site_id;
  852.  
  853. $old_blog_id = $this->blogid;
  854. $this->blogid = $blog_id;
  855.  
  856. $this->prefix = $this->get_blog_prefix();
  857.  
  858. foreach ( $this->tables( 'blog' ) as $table => $prefixed_table )
  859. $this->$table = $prefixed_table;
  860.  
  861. foreach ( $this->tables( 'old' ) as $table => $prefixed_table )
  862. $this->$table = $prefixed_table;
  863.  
  864. return $old_blog_id;
  865. }
  866.  
  867. /**
  868. * Gets blog prefix.
  869. *
  870. * @uses is_multisite()
  871. * @since 3.0.0
  872. * @param int $blog_id Optional.
  873. * @return string Blog prefix.
  874. */
  875. public function get_blog_prefix( $blog_id = null ) {
  876. if ( is_multisite() ) {
  877. if ( null === $blog_id )
  878. $blog_id = $this->blogid;
  879. $blog_id = (int) $blog_id;
  880. if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) )
  881. return $this->base_prefix;
  882. else
  883. return $this->base_prefix . $blog_id . '_';
  884. } else {
  885. return $this->base_prefix;
  886. }
  887. }
  888.  
  889. /**
  890. * Returns an array of WordPress tables.
  891. *
  892. * Also allows for the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE to
  893. * override the WordPress users and usermeta tables that would otherwise
  894. * be determined by the prefix.
  895. *
  896. * The scope argument can take one of the following:
  897. *
  898. * 'all' - returns 'all' and 'global' tables. No old tables are returned.
  899. * 'blog' - returns the blog-level tables for the queried blog.
  900. * 'global' - returns the global tables for the installation, returning multisite tables only if running multisite.
  901. * 'ms_global' - returns the multisite global tables, regardless if current installation is multisite.
  902. * 'old' - returns tables which are deprecated.
  903. *
  904. * @since 3.0.0
  905. * @uses wpdb::$tables
  906. * @uses wpdb::$old_tables
  907. * @uses wpdb::$global_tables
  908. * @uses wpdb::$ms_global_tables
  909. * @uses is_multisite()
  910. *
  911. * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all.
  912. * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog
  913. * prefix is requested, then the custom users and usermeta tables will be mapped.
  914. * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested.
  915. * @return array Table names. When a prefix is requested, the key is the unprefixed table name.
  916. */
  917. public function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) {
  918. switch ( $scope ) {
  919. case 'all' :
  920. $tables = array_merge( $this->global_tables, $this->tables );
  921. if ( is_multisite() )
  922. $tables = array_merge( $tables, $this->ms_global_tables );
  923. break;
  924. case 'blog' :
  925. $tables = $this->tables;
  926. break;
  927. case 'global' :
  928. $tables = $this->global_tables;
  929. if ( is_multisite() )
  930. $tables = array_merge( $tables, $this->ms_global_tables );
  931. break;
  932. case 'ms_global' :
  933. $tables = $this->ms_global_tables;
  934. break;
  935. case 'old' :
  936. $tables = $this->old_tables;
  937. break;
  938. default :
  939. return array();
  940. }
  941.  
  942. if ( $prefix ) {
  943. if ( ! $blog_id )
  944. $blog_id = $this->blogid;
  945. $blog_prefix = $this->get_blog_prefix( $blog_id );
  946. $base_prefix = $this->base_prefix;
  947. $global_tables = array_merge( $this->global_tables, $this->ms_global_tables );
  948. foreach ( $tables as $k => $table ) {
  949. if ( in_array( $table, $global_tables ) )
  950. $tables[ $table ] = $base_prefix . $table;
  951. else
  952. $tables[ $table ] = $blog_prefix . $table;
  953. unset( $tables[ $k ] );
  954. }
  955.  
  956. if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) )
  957. $tables['users'] = CUSTOM_USER_TABLE;
  958.  
  959. if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) )
  960. $tables['usermeta'] = CUSTOM_USER_META_TABLE;
  961. }
  962.  
  963. return $tables;
  964. }
  965.  
  966. /**
  967. * Selects a database using the current database connection.
  968. *
  969. * The database name will be changed based on the current database
  970. * connection. On failure, the execution will bail and display an DB error.
  971. *
  972. * @since 0.71
  973. *
  974. * @param string $db MySQL database name
  975. * @param resource $dbh Optional link identifier.
  976. * @return null Always null.
  977. */
  978. public function select( $db, $dbh = null ) {
  979. if ( is_null($dbh) )
  980. $dbh = $this->dbh;
  981.  
  982. if ( $this->use_mysqli ) {
  983. $success = @mysqli_select_db( $dbh, $db );
  984. } else {
  985. $success = @mysql_select_db( $db, $dbh );
  986. }
  987. if ( ! $success ) {
  988. $this->ready = false;
  989. if ( ! did_action( 'template_redirect' ) ) {
  990. wp_load_translations_early();
  991. $this->bail( sprintf( __( '<h1>Can&#8217;t select database</h1>
  992. <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>
  993. <ul>
  994. <li>Are you sure it exists?</li>
  995. <li>Does the user <code>%2$s</code> have permission to use the <code>%1$s</code> database?</li>
  996. <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>
  997. </ul>
  998. <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="https://wordpress.org/support/">WordPress Support Forums</a>.</p>' ), htmlspecialchars( $db, ENT_QUOTES ), htmlspecialchars( $this->dbuser, ENT_QUOTES ) ), 'db_select_fail' );
  999. }
  1000. return;
  1001. }
  1002. }
  1003.  
  1004. /**
  1005. * Do not use, deprecated.
  1006. *
  1007. * Use esc_sql() or wpdb::prepare() instead.
  1008. *
  1009. * @since 2.8.0
  1010. * @deprecated 3.6.0
  1011. * @see wpdb::prepare
  1012. * @see esc_sql()
  1013. * @access private
  1014. *
  1015. * @param string $string
  1016. * @return string
  1017. */
  1018. function _weak_escape( $string ) {
  1019. if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) )
  1020. _deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' );
  1021. return addslashes( $string );
  1022. }
  1023.  
  1024. /**
  1025. * Real escape, using mysqli_real_escape_string() or mysql_real_escape_string()
  1026. *
  1027. * @see mysqli_real_escape_string()
  1028. * @see mysql_real_escape_string()
  1029. * @since 2.8.0
  1030. * @access private
  1031. *
  1032. * @param string $string to escape
  1033. * @return string escaped
  1034. */
  1035. function _real_escape( $string ) {
  1036. if ( $this->dbh ) {
  1037. if ( $this->use_mysqli ) {
  1038. return mysqli_real_escape_string( $this->dbh, $string );
  1039. } else {
  1040. return mysql_real_escape_string( $string, $this->dbh );
  1041. }
  1042. }
  1043.  
  1044. $class = get_class( $this );
  1045. _doing_it_wrong( $class, "$class must set a database connection for use with escaping.", E_USER_NOTICE );
  1046. return addslashes( $string );
  1047. }
  1048.  
  1049. /**
  1050. * Escape data. Works on arrays.
  1051. *
  1052. * @uses wpdb::_real_escape()
  1053. * @since 2.8.0
  1054. * @access private
  1055. *
  1056. * @param string|array $data
  1057. * @return string|array escaped
  1058. */
  1059. function _escape( $data ) {
  1060. if ( is_array( $data ) ) {
  1061. foreach ( $data as $k => $v ) {
  1062. if ( is_array($v) )
  1063. $data[$k] = $this->_escape( $v );
  1064. else
  1065. $data[$k] = $this->_real_escape( $v );
  1066. }
  1067. } else {
  1068. $data = $this->_real_escape( $data );
  1069. }
  1070.  
  1071. return $data;
  1072. }
  1073.  
  1074. /**
  1075. * Do not use, deprecated.
  1076. *
  1077. * Use esc_sql() or wpdb::prepare() instead.
  1078. *
  1079. * @since 0.71
  1080. * @deprecated 3.6.0
  1081. * @see wpdb::prepare()
  1082. * @see esc_sql()
  1083. *
  1084. * @param mixed $data
  1085. * @return mixed
  1086. */
  1087. public function escape( $data ) {
  1088. if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) )
  1089. _deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' );
  1090. if ( is_array( $data ) ) {
  1091. foreach ( $data as $k => $v ) {
  1092. if ( is_array( $v ) )
  1093. $data[$k] = $this->escape( $v, 'recursive' );
  1094. else
  1095. $data[$k] = $this->_weak_escape( $v, 'internal' );
  1096. }
  1097. } else {
  1098. $data = $this->_weak_escape( $data, 'internal' );
  1099. }
  1100.  
  1101. return $data;
  1102. }
  1103.  
  1104. /**
  1105. * Escapes content by reference for insertion into the database, for security
  1106. *
  1107. * @uses wpdb::_real_escape()
  1108. * @since 2.3.0
  1109. * @param string $string to escape
  1110. * @return void
  1111. */
  1112. public function escape_by_ref( &$string ) {
  1113. if ( ! is_float( $string ) )
  1114. $string = $this->_real_escape( $string );
  1115. }
  1116.  
  1117. /**
  1118. * Prepares a SQL query for safe execution. Uses sprintf()-like syntax.
  1119. *
  1120. * The following directives can be used in the query format string:
  1121. * %d (integer)
  1122. * %f (float)
  1123. * %s (string)
  1124. * %% (literal percentage sign - no argument needed)
  1125. *
  1126. * All of %d, %f, and %s are to be left unquoted in the query string and they need an argument passed for them.
  1127. * Literals (%) as parts of the query must be properly written as %%.
  1128. *
  1129. * This function only supports a small subset of the sprintf syntax; it only supports %d (integer), %f (float), and %s (string).
  1130. * Does not support sign, padding, alignment, width or precision specifiers.
  1131. * Does not support argument numbering/swapping.
  1132. *
  1133. * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
  1134. *
  1135. * Both %d and %s should be left unquoted in the query string.
  1136. *
  1137. * <code>
  1138. * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", 'foo', 1337 )
  1139. * wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
  1140. * </code>
  1141. *
  1142. * @link http://php.net/sprintf Description of syntax.
  1143. * @since 2.3.0
  1144. *
  1145. * @param string $query Query statement with sprintf()-like placeholders
  1146. * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like
  1147. * {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if
  1148. * being called like {@link http://php.net/sprintf sprintf()}.
  1149. * @param mixed $args,... further variables to substitute into the query's placeholders if being called like
  1150. * {@link http://php.net/sprintf sprintf()}.
  1151. * @return null|false|string Sanitized query string, null if there is no query, false if there is an error and string
  1152. * if there was something to prepare
  1153. */
  1154. public function prepare( $query, $args ) {
  1155. if ( is_null( $query ) )
  1156. return;
  1157.  
  1158. // This is not meant to be foolproof -- but it will catch obviously incorrect usage.
  1159. if ( strpos( $query, '%' ) === false ) {
  1160. _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9' );
  1161. }
  1162.  
  1163. $args = func_get_args();
  1164. array_shift( $args );
  1165. // If args were passed as an array (as in vsprintf), move them up
  1166. if ( isset( $args[0] ) && is_array($args[0]) )
  1167. $args = $args[0];
  1168. $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
  1169. $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
  1170. $query = preg_replace( '|(?<!%)%f|' , '%F', $query ); // Force floats to be locale unaware
  1171. $query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s
  1172. array_walk( $args, array( $this, 'escape_by_ref' ) );
  1173. return @vsprintf( $query, $args );
  1174. }
  1175.  
  1176. /**
  1177. * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
  1178. *
  1179. * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security.
  1180. *
  1181. * Example Prepared Statement:
  1182. * $wild = '%';
  1183. * $find = 'only 43% of planets';
  1184. * $like = $wild . $wpdb->esc_like( $find ) . $wild;
  1185. * $sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like );
  1186. *
  1187. * Example Escape Chain:
  1188. * $sql = esc_sql( $wpdb->esc_like( $input ) );
  1189. *
  1190. * @since 4.0.0
  1191. * @access public
  1192. *
  1193. * @param string $text The raw text to be escaped. The input typed by the user should have no
  1194. * extra or deleted slashes.
  1195. * @return string Text in the form of a LIKE phrase. The output is not SQL safe. Call $wpdb::prepare()
  1196. * or real_escape next.
  1197. */
  1198. public function esc_like( $text ) {
  1199. return addcslashes( $text, '_%\\' );
  1200. }
  1201.  
  1202. /**
  1203. * Print SQL/DB error.
  1204. *
  1205. * @since 0.71
  1206. * @global array $EZSQL_ERROR Stores error information of query and error string
  1207. *
  1208. * @param string $str The error to display
  1209. * @return bool False if the showing of errors is disabled.
  1210. */
  1211. public function print_error( $str = '' ) {
  1212. global $EZSQL_ERROR;
  1213.  
  1214. if ( !$str ) {
  1215. if ( $this->use_mysqli ) {
  1216. $str = mysqli_error( $this->dbh );
  1217. } else {
  1218. $str = mysql_error( $this->dbh );
  1219. }
  1220. }
  1221. $EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str );
  1222.  
  1223. if ( $this->suppress_errors )
  1224. return false;
  1225.  
  1226. wp_load_translations_early();
  1227.  
  1228. if ( $caller = $this->get_caller() )
  1229. $error_str = sprintf( __( 'WordPress database error %1$s for query %2$s made by %3$s' ), $str, $this->last_query, $caller );
  1230. else
  1231. $error_str = sprintf( __( 'WordPress database error %1$s for query %2$s' ), $str, $this->last_query );
  1232.  
  1233. error_log( $error_str );
  1234.  
  1235. // Are we showing errors?
  1236. if ( ! $this->show_errors )
  1237. return false;
  1238.  
  1239. // If there is an error then take note of it
  1240. if ( is_multisite() ) {
  1241. $msg = "WordPress database error: [$str]\n{$this->last_query}\n";
  1242. if ( defined( 'ERRORLOGFILE' ) )
  1243. error_log( $msg, 3, ERRORLOGFILE );
  1244. if ( defined( 'DIEONDBERROR' ) )
  1245. wp_die( $msg );
  1246. } else {
  1247. $str = htmlspecialchars( $str, ENT_QUOTES );
  1248. $query = htmlspecialchars( $this->last_query, ENT_QUOTES );
  1249.  
  1250. print "<div id='error'>
  1251. <p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br />
  1252. <code>$query</code></p>
  1253. </div>";
  1254. }
  1255. }
  1256.  
  1257. /**
  1258. * Enables showing of database errors.
  1259. *
  1260. * This function should be used only to enable showing of errors.
  1261. * wpdb::hide_errors() should be used instead for hiding of errors. However,
  1262. * this function can be used to enable and disable showing of database
  1263. * errors.
  1264. *
  1265. * @since 0.71
  1266. * @see wpdb::hide_errors()
  1267. *
  1268. * @param bool $show Whether to show or hide errors
  1269. * @return bool Old value for showing errors.
  1270. */
  1271. public function show_errors( $show = true ) {
  1272. $errors = $this->show_errors;
  1273. $this->show_errors = $show;
  1274. return $errors;
  1275. }
  1276.  
  1277. /**
  1278. * Disables showing of database errors.
  1279. *
  1280. * By default database errors are not shown.
  1281. *
  1282. * @since 0.71
  1283. * @see wpdb::show_errors()
  1284. *
  1285. * @return bool Whether showing of errors was active
  1286. */
  1287. public function hide_errors() {
  1288. $show = $this->show_errors;
  1289. $this->show_errors = false;
  1290. return $show;
  1291. }
  1292.  
  1293. /**
  1294. * Whether to suppress database errors.
  1295. *
  1296. * By default database errors are suppressed, with a simple
  1297. * call to this function they can be enabled.
  1298. *
  1299. * @since 2.5.0
  1300. * @see wpdb::hide_errors()
  1301. * @param bool $suppress Optional. New value. Defaults to true.
  1302. * @return bool Old value
  1303. */
  1304. public function suppress_errors( $suppress = true ) {
  1305. $errors = $this->suppress_errors;
  1306. $this->suppress_errors = (bool) $suppress;
  1307. return $errors;
  1308. }
  1309.  
  1310. /**
  1311. * Kill cached query results.
  1312. *
  1313. * @since 0.71
  1314. * @return void
  1315. */
  1316. public function flush() {
  1317. $this->last_result = array();
  1318. $this->col_info = null;
  1319. $this->last_query = null;
  1320. $this->rows_affected = $this->num_rows = 0;
  1321. $this->last_error = '';
  1322.  
  1323. if ( is_resource( $this->result ) ) {
  1324. if ( $this->use_mysqli ) {
  1325. mysqli_free_result( $this->result );
  1326. } else {
  1327. mysql_free_result( $this->result );
  1328. }
  1329. }
  1330. }
  1331.  
  1332. /**
  1333. * Connect to and select database.
  1334. *
  1335. * If $allow_bail is false, the lack of database connection will need
  1336. * to be handled manually.
  1337. *
  1338. * @since 3.0.0
  1339. * @since 3.9.0 $allow_bail parameter added.
  1340. *
  1341. * @param bool $allow_bail Optional. Allows the function to bail. Default true.
  1342. * @return bool True with a successful connection, false on failure.
  1343. */
  1344. public function db_connect( $allow_bail = true ) {
  1345.  
  1346. $this->is_mysql = true;
  1347.  
  1348. /*
  1349. * Deprecated in 3.9+ when using MySQLi. No equivalent
  1350. * $new_link parameter exists for mysqli_* functions.
  1351. */
  1352. $new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
  1353. $client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
  1354.  
  1355. if ( $this->use_mysqli ) {
  1356. $this->dbh = mysqli_init();
  1357.  
  1358. // mysqli_real_connect doesn't support the host param including a port or socket
  1359. // like mysql_connect does. This duplicates how mysql_connect detects a port and/or socket file.
  1360. $port = null;
  1361. $socket = null;
  1362. $host = $this->dbhost;
  1363. $port_or_socket = strstr( $host, ':' );
  1364. if ( ! empty( $port_or_socket ) ) {
  1365. $host = substr( $host, 0, strpos( $host, ':' ) );
  1366. $port_or_socket = substr( $port_or_socket, 1 );
  1367. if ( 0 !== strpos( $port_or_socket, '/' ) ) {
  1368. $port = intval( $port_or_socket );
  1369. $maybe_socket = strstr( $port_or_socket, ':' );
  1370. if ( ! empty( $maybe_socket ) ) {
  1371. $socket = substr( $maybe_socket, 1 );
  1372. }
  1373. } else {
  1374. $socket = $port_or_socket;
  1375. }
  1376. }
  1377.  
  1378. if ( WP_DEBUG ) {
  1379. mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
  1380. } else {
  1381. @mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
  1382. }
  1383.  
  1384. if ( $this->dbh->connect_errno ) {
  1385. $this->dbh = null;
  1386.  
  1387. /* It's possible ext/mysqli is misconfigured. Fall back to ext/mysql if:
  1388. * - We haven't previously connected, and
  1389. * - WP_USE_EXT_MYSQL isn't set to false, and
  1390. * - ext/mysql is loaded.
  1391. */
  1392. $attempt_fallback = true;
  1393.  
  1394. if ( $this->has_connected ) {
  1395. $attempt_fallback = false;
  1396. } else if ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL ) {
  1397. $attempt_fallback = false;
  1398. } else if ( ! function_exists( 'mysql_connect' ) ) {
  1399. $attempt_fallback = false;
  1400. }
  1401.  
  1402. if ( $attempt_fallback ) {
  1403. $this->use_mysqli = false;
  1404. $this->db_connect();
  1405. }
  1406. }
  1407. } else {
  1408. if ( WP_DEBUG ) {
  1409. $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
  1410. } else {
  1411. $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
  1412. }
  1413. }
  1414.  
  1415. if ( ! $this->dbh && $allow_bail ) {
  1416. wp_load_translations_early();
  1417.  
  1418. // Load custom DB error template, if present.
  1419. if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) {
  1420. require_once( WP_CONTENT_DIR . '/db-error.php' );
  1421. die();
  1422. }
  1423.  
  1424. $this->bail( sprintf( __( "
  1425. <h1>Error establishing a database connection</h1>
  1426. <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>
  1427. <ul>
  1428. <li>Are you sure you have the correct username and password?</li>
  1429. <li>Are you sure that you have typed the correct hostname?</li>
  1430. <li>Are you sure that the database server is running?</li>
  1431. </ul>
  1432. <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='https://wordpress.org/support/'>WordPress Support Forums</a>.</p>
  1433. " ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
  1434.  
  1435. return false;
  1436. } else if ( $this->dbh ) {
  1437. $this->has_connected = true;
  1438. $this->set_charset( $this->dbh );
  1439. $this->set_sql_mode();
  1440. $this->ready = true;
  1441. $this->select( $this->dbname, $this->dbh );
  1442.  
  1443. return true;
  1444. }
  1445.  
  1446. return false;
  1447. }
  1448.  
  1449. /**
  1450. * Check that the connection to the database is still up. If not, try to reconnect.
  1451. *
  1452. * If this function is unable to reconnect, it will forcibly die, or if after the
  1453. * the template_redirect hook has been fired, return false instead.
  1454. *
  1455. * If $allow_bail is false, the lack of database connection will need
  1456. * to be handled manually.
  1457. *
  1458. * @since 3.9.0
  1459. *
  1460. * @param bool $allow_bail Optional. Allows the function to bail. Default true.
  1461. * @return bool True if the connection is up.
  1462. */
  1463. public function check_connection( $allow_bail = true ) {
  1464. if ( $this->use_mysqli ) {
  1465. if ( @mysqli_ping( $this->dbh ) ) {
  1466. return true;
  1467. }
  1468. } else {
  1469. if ( @mysql_ping( $this->dbh ) ) {
  1470. return true;
  1471. }
  1472. }
  1473.  
  1474. $error_reporting = false;
  1475.  
  1476. // Disable warnings, as we don't want to see a multitude of "unable to connect" messages
  1477. if ( WP_DEBUG ) {
  1478. $error_reporting = error_reporting();
  1479. error_reporting( $error_reporting & ~E_WARNING );
  1480. }
  1481.  
  1482. for ( $tries = 1; $tries <= $this->reconnect_retries; $tries++ ) {
  1483. // On the last try, re-enable warnings. We want to see a single instance of the
  1484. // "unable to connect" message on the bail() screen, if it appears.
  1485. if ( $this->reconnect_retries === $tries && WP_DEBUG ) {
  1486. error_reporting( $error_reporting );
  1487. }
  1488.  
  1489. if ( $this->db_connect( false ) ) {
  1490. if ( $error_reporting ) {
  1491. error_reporting( $error_reporting );
  1492. }
  1493.  
  1494. return true;
  1495. }
  1496.  
  1497. sleep( 1 );
  1498. }
  1499.  
  1500. // If template_redirect has already happened, it's too late for wp_die()/dead_db().
  1501. // Let's just return and hope for the best.
  1502. if ( did_action( 'template_redirect' ) ) {
  1503. return false;
  1504. }
  1505.  
  1506. if ( ! $allow_bail ) {
  1507. return false;
  1508. }
  1509.  
  1510. // We weren't able to reconnect, so we better bail.
  1511. $this->bail( sprintf( ( "
  1512. <h1>Error reconnecting to the database</h1>
  1513. <p>This means that we lost contact with the database server at <code>%s</code>. This could mean your host's database server is down.</p>
  1514. <ul>
  1515. <li>Are you sure that the database server is running?</li>
  1516. <li>Are you sure that the database server is not under particularly heavy load?</li>
  1517. </ul>
  1518. <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='https://wordpress.org/support/'>WordPress Support Forums</a>.</p>
  1519. " ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
  1520.  
  1521. // Call dead_db() if bail didn't die, because this database is no more. It has ceased to be (at least temporarily).
  1522. dead_db();
  1523. }
  1524.  
  1525. /**
  1526. * Perform a MySQL database query, using current database connection.
  1527. *
  1528. * More information can be found on the codex page.
  1529. *
  1530. * @since 0.71
  1531. *
  1532. * @param string $query Database query
  1533. * @return int|false Number of rows affected/selected or false on error
  1534. */
  1535. public function query( $query ) {
  1536. if ( ! $this->ready )
  1537. return false;
  1538.  
  1539. /**
  1540. * Filter the database query.
  1541. *
  1542. * Some queries are made before the plugins have been loaded,
  1543. * and thus cannot be filtered with this method.
  1544. *
  1545. * @since 2.1.0
  1546. *
  1547. * @param string $query Database query.
  1548. */
  1549. $query = apply_filters( 'query', $query );
  1550.  
  1551. $this->flush();
  1552.  
  1553. // Log how the function was called
  1554. $this->func_call = "\$db->query(\"$query\")";
  1555.  
  1556. // Keep track of the last query for debug..
  1557. $this->last_query = $query;
  1558.  
  1559. $this->_do_query( $query );
  1560.  
  1561. // MySQL server has gone away, try to reconnect
  1562. $mysql_errno = 0;
  1563. if ( ! empty( $this->dbh ) ) {
  1564. if ( $this->use_mysqli ) {
  1565. $mysql_errno = mysqli_errno( $this->dbh );
  1566. } else {
  1567. $mysql_errno = mysql_errno( $this->dbh );
  1568. }
  1569. }
  1570.  
  1571. if ( empty( $this->dbh ) || 2006 == $mysql_errno ) {
  1572. if ( $this->check_connection() ) {
  1573. $this->_do_query( $query );
  1574. } else {
  1575. $this->insert_id = 0;
  1576. return false;
  1577. }
  1578. }
  1579.  
  1580. // If there is an error then take note of it..
  1581. if ( $this->use_mysqli ) {
  1582. $this->last_error = mysqli_error( $this->dbh );
  1583. } else {
  1584. $this->last_error = mysql_error( $this->dbh );
  1585. }
  1586.  
  1587. if ( $this->last_error ) {
  1588. // Clear insert_id on a subsequent failed insert.
  1589. if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) )
  1590. $this->insert_id = 0;
  1591.  
  1592. $this->print_error();
  1593. return false;
  1594. }
  1595.  
  1596. if ( preg_match( '/^\s*(create|alter|truncate|drop)\s/i', $query ) ) {
  1597. $return_val = $this->result;
  1598. } elseif ( preg_match( '/^\s*(insert|delete|update|replace)\s/i', $query ) ) {
  1599. if ( $this->use_mysqli ) {
  1600. $this->rows_affected = mysqli_affected_rows( $this->dbh );
  1601. } else {
  1602. $this->rows_affected = mysql_affected_rows( $this->dbh );
  1603. }
  1604. // Take note of the insert_id
  1605. if ( preg_match( '/^\s*(insert|replace)\s/i', $query ) ) {
  1606. if ( $this->use_mysqli ) {
  1607. $this->insert_id = mysqli_insert_id( $this->dbh );
  1608. } else {
  1609. $this->insert_id = mysql_insert_id( $this->dbh );
  1610. }
  1611. }
  1612. // Return number of rows affected
  1613. $return_val = $this->rows_affected;
  1614. } else {
  1615. $num_rows = 0;
  1616. if ( $this->use_mysqli ) {
  1617. while ( $row = @mysqli_fetch_object( $this->result ) ) {
  1618. $this->last_result[$num_rows] = $row;
  1619. $num_rows++;
  1620. }
  1621. } else {
  1622. while ( $row = @mysql_fetch_object( $this->result ) ) {
  1623. $this->last_result[$num_rows] = $row;
  1624. $num_rows++;
  1625. }
  1626. }
  1627.  
  1628. // Log number of rows the query returned
  1629. // and return number of rows selected
  1630. $this->num_rows = $num_rows;
  1631. $return_val = $num_rows;
  1632. }
  1633.  
  1634. return $return_val;
  1635. }
  1636.  
  1637. /**
  1638. * Internal function to perform the mysql_query() call.
  1639. *
  1640. * @since 3.9.0
  1641. *
  1642. * @access private
  1643. * @see wpdb::query()
  1644. *
  1645. * @param string $query The query to run.
  1646. */
  1647. private function _do_query( $query ) {
  1648. if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
  1649. $this->timer_start();
  1650. }
  1651.  
  1652. if ( $this->use_mysqli ) {
  1653. $this->result = @mysqli_query( $this->dbh, $query );
  1654. } else {
  1655. $this->result = @mysql_query( $query, $this->dbh );
  1656. }
  1657. $this->num_queries++;
  1658.  
  1659. if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
  1660. $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
  1661. }
  1662. }
  1663.  
  1664. /**
  1665. * Insert a row into a table.
  1666. *
  1667. * <code>
  1668. * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
  1669. * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
  1670. * </code>
  1671. *
  1672. * @since 2.5.0
  1673. * @see wpdb::prepare()
  1674. * @see wpdb::$field_types
  1675. * @see wp_set_wpdb_vars()
  1676. *
  1677. * @param string $table table name
  1678. * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1679. * @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.
  1680. * 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.
  1681. * @return int|false The number of rows inserted, or false on error.
  1682. */
  1683. public function insert( $table, $data, $format = null ) {
  1684. return $this->_insert_replace_helper( $table, $data, $format, 'INSERT' );
  1685. }
  1686.  
  1687. /**
  1688. * Replace a row into a table.
  1689. *
  1690. * <code>
  1691. * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
  1692. * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
  1693. * </code>
  1694. *
  1695. * @since 3.0.0
  1696. * @see wpdb::prepare()
  1697. * @see wpdb::$field_types
  1698. * @see wp_set_wpdb_vars()
  1699. *
  1700. * @param string $table table name
  1701. * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1702. * @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.
  1703. * 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.
  1704. * @return int|false The number of rows affected, or false on error.
  1705. */
  1706. public function replace( $table, $data, $format = null ) {
  1707. return $this->_insert_replace_helper( $table, $data, $format, 'REPLACE' );
  1708. }
  1709.  
  1710. /**
  1711. * Helper function for insert and replace.
  1712. *
  1713. * Runs an insert or replace query based on $type argument.
  1714. *
  1715. * @access private
  1716. * @since 3.0.0
  1717. * @see wpdb::prepare()
  1718. * @see wpdb::$field_types
  1719. * @see wp_set_wpdb_vars()
  1720. *
  1721. * @param string $table table name
  1722. * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1723. * @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.
  1724. * 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.
  1725. * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT.
  1726. * @return int|false The number of rows affected, or false on error.
  1727. */
  1728. function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) {
  1729. if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) )
  1730. return false;
  1731. $this->insert_id = 0;
  1732. $formats = $format = (array) $format;
  1733. $fields = array_keys( $data );
  1734. $formatted_fields = array();
  1735. foreach ( $fields as $field ) {
  1736. if ( !empty( $format ) )
  1737. $form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
  1738. elseif ( isset( $this->field_types[$field] ) )
  1739. $form = $this->field_types[$field];
  1740. else
  1741. $form = '%s';
  1742. $formatted_fields[] = $form;
  1743. }
  1744. $sql = "{$type} INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $formatted_fields ) . ")";
  1745. return $this->query( $this->prepare( $sql, $data ) );
  1746. }
  1747.  
  1748. /**
  1749. * Update a row in the table
  1750. *
  1751. * <code>
  1752. * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 'bar' ), array( 'ID' => 1 ) )
  1753. * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) )
  1754. * </code>
  1755. *
  1756. * @since 2.5.0
  1757. * @see wpdb::prepare()
  1758. * @see wpdb::$field_types
  1759. * @see wp_set_wpdb_vars()
  1760. *
  1761. * @param string $table table name
  1762. * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1763. * @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".
  1764. * @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.
  1765. * 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.
  1766. * @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.
  1767. * @return int|false The number of rows updated, or false on error.
  1768. */
  1769. public function update( $table, $data, $where, $format = null, $where_format = null ) {
  1770. if ( ! is_array( $data ) || ! is_array( $where ) )
  1771. return false;
  1772.  
  1773. $formats = $format = (array) $format;
  1774. $bits = $wheres = array();
  1775. foreach ( (array) array_keys( $data ) as $field ) {
  1776. if ( !empty( $format ) )
  1777. $form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
  1778. elseif ( isset($this->field_types[$field]) )
  1779. $form = $this->field_types[$field];
  1780. else
  1781. $form = '%s';
  1782. $bits[] = "`$field` = {$form}";
  1783. }
  1784.  
  1785. $where_formats = $where_format = (array) $where_format;
  1786. foreach ( (array) array_keys( $where ) as $field ) {
  1787. if ( !empty( $where_format ) )
  1788. $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
  1789. elseif ( isset( $this->field_types[$field] ) )
  1790. $form = $this->field_types[$field];
  1791. else
  1792. $form = '%s';
  1793. $wheres[] = "`$field` = {$form}";
  1794. }
  1795.  
  1796. $sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
  1797. return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) );
  1798. }
  1799.  
  1800. /**
  1801. * Delete a row in the table
  1802. *
  1803. * <code>
  1804. * wpdb::delete( 'table', array( 'ID' => 1 ) )
  1805. * wpdb::delete( 'table', array( 'ID' => 1 ), array( '%d' ) )
  1806. * </code>
  1807. *
  1808. * @since 3.4.0
  1809. * @see wpdb::prepare()
  1810. * @see wpdb::$field_types
  1811. * @see wp_set_wpdb_vars()
  1812. *
  1813. * @param string $table table name
  1814. * @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".
  1815. * @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.
  1816. * @return int|false The number of rows updated, or false on error.
  1817. */
  1818. public function delete( $table, $where, $where_format = null ) {
  1819. if ( ! is_array( $where ) )
  1820. return false;
  1821.  
  1822. $wheres = array();
  1823.  
  1824. $where_formats = $where_format = (array) $where_format;
  1825.  
  1826. foreach ( array_keys( $where ) as $field ) {
  1827. if ( !empty( $where_format ) ) {
  1828. $form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
  1829. } elseif ( isset( $this->field_types[ $field ] ) ) {
  1830. $form = $this->field_types[ $field ];
  1831. } else {
  1832. $form = '%s';
  1833. }
  1834.  
  1835. $wheres[] = "$field = $form";
  1836. }
  1837.  
  1838. $sql = "DELETE FROM $table WHERE " . implode( ' AND ', $wheres );
  1839. return $this->query( $this->prepare( $sql, $where ) );
  1840. }
  1841.  
  1842.  
  1843. /**
  1844. * Retrieve one variable from the database.
  1845. *
  1846. * Executes a SQL query and returns the value from the SQL result.
  1847. * 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.
  1848. * If $query is null, this function returns the value in the specified column and row from the previous SQL result.
  1849. *
  1850. * @since 0.71
  1851. *
  1852. * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query.
  1853. * @param int $x Optional. Column of value to return. Indexed from 0.
  1854. * @param int $y Optional. Row of value to return. Indexed from 0.
  1855. * @return string|null Database query result (as string), or null on failure
  1856. */
  1857. public function get_var( $query = null, $x = 0, $y = 0 ) {
  1858. $this->func_call = "\$db->get_var(\"$query\", $x, $y)";
  1859. if ( $query )
  1860. $this->query( $query );
  1861.  
  1862. // Extract var out of cached results based x,y vals
  1863. if ( !empty( $this->last_result[$y] ) ) {
  1864. $values = array_values( get_object_vars( $this->last_result[$y] ) );
  1865. }
  1866.  
  1867. // If there is a value return it else return null
  1868. return ( isset( $values[$x] ) && $values[$x] !== '' ) ? $values[$x] : null;
  1869. }
  1870.  
  1871. /**
  1872. * Retrieve one row from the database.
  1873. *
  1874. * Executes a SQL query and returns the row from the SQL result.
  1875. *
  1876. * @since 0.71
  1877. *
  1878. * @param string|null $query SQL query.
  1879. * @param string $output Optional. one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...),
  1880. * a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively.
  1881. * @param int $y Optional. Row to return. Indexed from 0.
  1882. * @return mixed Database query result in format specified by $output or null on failure
  1883. */
  1884. public function get_row( $query = null, $output = OBJECT, $y = 0 ) {
  1885. $this->func_call = "\$db->get_row(\"$query\",$output,$y)";
  1886. if ( $query )
  1887. $this->query( $query );
  1888. else
  1889. return null;
  1890.  
  1891. if ( !isset( $this->last_result[$y] ) )
  1892. return null;
  1893.  
  1894. if ( $output == OBJECT ) {
  1895. return $this->last_result[$y] ? $this->last_result[$y] : null;
  1896. } elseif ( $output == ARRAY_A ) {
  1897. return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null;
  1898. } elseif ( $output == ARRAY_N ) {
  1899. return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null;
  1900. } elseif ( strtoupper( $output ) === OBJECT ) {
  1901. // Back compat for OBJECT being previously case insensitive.
  1902. return $this->last_result[$y] ? $this->last_result[$y] : null;
  1903. } else {
  1904. $this->print_error( " \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" );
  1905. }
  1906. }
  1907.  
  1908. /**
  1909. * Retrieve one column from the database.
  1910. *
  1911. * Executes a SQL query and returns the column from the SQL result.
  1912. * If the SQL result contains more than one column, this function returns the column specified.
  1913. * If $query is null, this function returns the specified column from the previous SQL result.
  1914. *
  1915. * @since 0.71
  1916. *
  1917. * @param string|null $query Optional. SQL query. Defaults to previous query.
  1918. * @param int $x Optional. Column to return. Indexed from 0.
  1919. * @return array Database query result. Array indexed from 0 by SQL result row number.
  1920. */
  1921. public function get_col( $query = null , $x = 0 ) {
  1922. if ( $query )
  1923. $this->query( $query );
  1924.  
  1925. $new_array = array();
  1926. // Extract the column values
  1927. for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
  1928. $new_array[$i] = $this->get_var( null, $x, $i );
  1929. }
  1930. return $new_array;
  1931. }
  1932.  
  1933. /**
  1934. * Retrieve an entire SQL result set from the database (i.e., many rows)
  1935. *
  1936. * Executes a SQL query and returns the entire SQL result.
  1937. *
  1938. * @since 0.71
  1939. *
  1940. * @param string $query SQL query.
  1941. * @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.
  1942. * Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively.
  1943. * 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.
  1944. * @return mixed Database query results
  1945. */
  1946. public function get_results( $query = null, $output = OBJECT ) {
  1947. $this->func_call = "\$db->get_results(\"$query\", $output)";
  1948.  
  1949. if ( $query )
  1950. $this->query( $query );
  1951. else
  1952. return null;
  1953.  
  1954. $new_array = array();
  1955. if ( $output == OBJECT ) {
  1956. // Return an integer-keyed array of row objects
  1957. return $this->last_result;
  1958. } elseif ( $output == OBJECT_K ) {
  1959. // Return an array of row objects with keys from column 1
  1960. // (Duplicates are discarded)
  1961. foreach ( $this->last_result as $row ) {
  1962. $var_by_ref = get_object_vars( $row );
  1963. $key = array_shift( $var_by_ref );
  1964. if ( ! isset( $new_array[ $key ] ) )
  1965. $new_array[ $key ] = $row;
  1966. }
  1967. return $new_array;
  1968. } elseif ( $output == ARRAY_A || $output == ARRAY_N ) {
  1969. // Return an integer-keyed array of...
  1970. if ( $this->last_result ) {
  1971. foreach( (array) $this->last_result as $row ) {
  1972. if ( $output == ARRAY_N ) {
  1973. // ...integer-keyed row arrays
  1974. $new_array[] = array_values( get_object_vars( $row ) );
  1975. } else {
  1976. // ...column name-keyed row arrays
  1977. $new_array[] = get_object_vars( $row );
  1978. }
  1979. }
  1980. }
  1981. return $new_array;
  1982. } elseif ( strtoupper( $output ) === OBJECT ) {
  1983. // Back compat for OBJECT being previously case insensitive.
  1984. return $this->last_result;
  1985. }
  1986. return null;
  1987. }
  1988.  
  1989. /**
  1990. * Load the column metadata from the last query.
  1991. *
  1992. * @since 3.5.0
  1993. *
  1994. * @access protected
  1995. */
  1996. protected function load_col_info() {
  1997. if ( $this->col_info )
  1998. return;
  1999.  
  2000. if ( $this->use_mysqli ) {
  2001. for ( $i = 0; $i < @mysqli_num_fields( $this->result ); $i++ ) {
  2002. $this->col_info[ $i ] = @mysqli_fetch_field( $this->result );
  2003. }
  2004. } else {
  2005. for ( $i = 0; $i < @mysql_num_fields( $this->result ); $i++ ) {
  2006. $this->col_info[ $i ] = @mysql_fetch_field( $this->result, $i );
  2007. }
  2008. }
  2009. }
  2010.  
  2011. /**
  2012. * Retrieve column metadata from the last query.
  2013. *
  2014. * @since 0.71
  2015. *
  2016. * @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
  2017. * @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
  2018. * @return mixed Column Results
  2019. */
  2020. public function get_col_info( $info_type = 'name', $col_offset = -1 ) {
  2021. $this->load_col_info();
  2022.  
  2023. if ( $this->col_info ) {
  2024. if ( $col_offset == -1 ) {
  2025. $i = 0;
  2026. $new_array = array();
  2027. foreach( (array) $this->col_info as $col ) {
  2028. $new_array[$i] = $col->{$info_type};
  2029. $i++;
  2030. }
  2031. return $new_array;
  2032. } else {
  2033. return $this->col_info[$col_offset]->{$info_type};
  2034. }
  2035. }
  2036. }
  2037.  
  2038. /**
  2039. * Starts the timer, for debugging purposes.
  2040. *
  2041. * @since 1.5.0
  2042. *
  2043. * @return true
  2044. */
  2045. public function timer_start() {
  2046. $this->time_start = microtime( true );
  2047. return true;
  2048. }
  2049.  
  2050. /**
  2051. * Stops the debugging timer.
  2052. *
  2053. * @since 1.5.0
  2054. *
  2055. * @return float Total time spent on the query, in seconds
  2056. */
  2057. public function timer_stop() {
  2058. return ( microtime( true ) - $this->time_start );
  2059. }
  2060.  
  2061. /**
  2062. * Wraps errors in a nice header and footer and dies.
  2063. *
  2064. * Will not die if wpdb::$show_errors is false.
  2065. *
  2066. * @since 1.5.0
  2067. *
  2068. * @param string $message The Error message
  2069. * @param string $error_code Optional. A Computer readable string to identify the error.
  2070. * @return false|void
  2071. */
  2072. public function bail( $message, $error_code = '500' ) {
  2073. if ( !$this->show_errors ) {
  2074. if ( class_exists( 'WP_Error' ) )
  2075. $this->error = new WP_Error($error_code, $message);
  2076. else
  2077. $this->error = $message;
  2078. return false;
  2079. }
  2080. wp_die($message);
  2081. }
  2082.  
  2083. /**
  2084. * Whether MySQL database is at least the required minimum version.
  2085. *
  2086. * @since 2.5.0
  2087. * @uses $wp_version
  2088. * @uses $required_mysql_version
  2089. *
  2090. * @return WP_Error
  2091. */
  2092. public function check_database_version() {
  2093. global $wp_version, $required_mysql_version;
  2094. // Make sure the server has the required MySQL version
  2095. if ( version_compare($this->db_version(), $required_mysql_version, '<') )
  2096. return new WP_Error('database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ));
  2097. }
  2098.  
  2099. /**
  2100. * Whether the database supports collation.
  2101. *
  2102. * Called when WordPress is generating the table scheme.
  2103. *
  2104. * @since 2.5.0
  2105. * @deprecated 3.5.0
  2106. * @deprecated Use wpdb::has_cap( 'collation' )
  2107. *
  2108. * @return bool True if collation is supported, false if version does not
  2109. */
  2110. public function supports_collation() {
  2111. _deprecated_function( __FUNCTION__, '3.5', 'wpdb::has_cap( \'collation\' )' );
  2112. return $this->has_cap( 'collation' );
  2113. }
  2114.  
  2115. /**
  2116. * The database character collate.
  2117. *
  2118. * @since 3.5.0
  2119. *
  2120. * @return string The database character collate.
  2121. */
  2122. public function get_charset_collate() {
  2123. $charset_collate = '';
  2124.  
  2125. if ( ! empty( $this->charset ) )
  2126. $charset_collate = "DEFAULT CHARACTER SET $this->charset";
  2127. if ( ! empty( $this->collate ) )
  2128. $charset_collate .= " COLLATE $this->collate";
  2129.  
  2130. return $charset_collate;
  2131. }
  2132.  
  2133. /**
  2134. * Determine if a database supports a particular feature.
  2135. *
  2136. * @since 2.7.0
  2137. * @see wpdb::db_version()
  2138. *
  2139. * @param string $db_cap The feature to check for.
  2140. * @return bool
  2141. */
  2142. public function has_cap( $db_cap ) {
  2143. $version = $this->db_version();
  2144.  
  2145. switch ( strtolower( $db_cap ) ) {
  2146. case 'collation' : // @since 2.5.0
  2147. case 'group_concat' : // @since 2.7.0
  2148. case 'subqueries' : // @since 2.7.0
  2149. return version_compare( $version, '4.1', '>=' );
  2150. case 'set_charset' :
  2151. return version_compare( $version, '5.0.7', '>=' );
  2152. };
  2153.  
  2154. return false;
  2155. }
  2156.  
  2157. /**
  2158. * Retrieve the name of the function that called wpdb.
  2159. *
  2160. * Searches up the list of functions until it reaches
  2161. * the one that would most logically had called this method.
  2162. *
  2163. * @since 2.5.0
  2164. *
  2165. * @return string The name of the calling function
  2166. */
  2167. public function get_caller() {
  2168. return wp_debug_backtrace_summary( __CLASS__ );
  2169. }
  2170.  
  2171. /**
  2172. * The database version number.
  2173. *
  2174. * @since 2.7.0
  2175. *
  2176. * @return false|string false on failure, version number on success
  2177. */
  2178. public function db_version() {
  2179. if ( $this->use_mysqli ) {
  2180. $server_info = mysqli_get_server_info( $this->dbh );
  2181. } else {
  2182. $server_info = mysql_get_server_info( $this->dbh );
  2183. }
  2184. return preg_replace( '/[^0-9.].*/', '', $server_info );
  2185. }
  2186. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement