wp/wp-includes/wp-db.php
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
4:346c88efed21 5:5e2f62d02dcd
    15 define( 'EZSQL_VERSION', 'WP1.25' );
    15 define( 'EZSQL_VERSION', 'WP1.25' );
    16 
    16 
    17 /**
    17 /**
    18  * @since 0.71
    18  * @since 0.71
    19  */
    19  */
    20 define( 'OBJECT', 'OBJECT', true );
    20 define( 'OBJECT', 'OBJECT' );
       
    21 define( 'object', 'OBJECT' ); // Back compat.
    21 
    22 
    22 /**
    23 /**
    23  * @since 2.5.0
    24  * @since 2.5.0
    24  */
    25  */
    25 define( 'OBJECT_K', 'OBJECT_K' );
    26 define( 'OBJECT_K', 'OBJECT_K' );
    40  * It is possible to replace this class with your own
    41  * It is possible to replace this class with your own
    41  * by setting the $wpdb global variable in wp-content/db.php
    42  * by setting the $wpdb global variable in wp-content/db.php
    42  * file to your class. The wpdb class will still be included,
    43  * file to your class. The wpdb class will still be included,
    43  * so you can extend it or simply use your own.
    44  * so you can extend it or simply use your own.
    44  *
    45  *
    45  * @link http://codex.wordpress.org/Function_Reference/wpdb_Class
    46  * @link https://codex.wordpress.org/Function_Reference/wpdb_Class
    46  *
    47  *
    47  * @package WordPress
    48  * @package WordPress
    48  * @subpackage Database
    49  * @subpackage Database
    49  * @since 0.71
    50  * @since 0.71
    50  */
    51  */
    51 class wpdb {
    52 class wpdb {
    52 
    53 
    53 	/**
    54 	/**
    54 	 * Whether to show SQL/DB errors
    55 	 * Whether to show SQL/DB errors.
       
    56 	 *
       
    57 	 * Default behavior is to show errors if both WP_DEBUG and WP_DEBUG_DISPLAY
       
    58 	 * evaluated to true.
    55 	 *
    59 	 *
    56 	 * @since 0.71
    60 	 * @since 0.71
    57 	 * @access private
    61 	 * @access private
    58 	 * @var bool
    62 	 * @var bool
    59 	 */
    63 	 */
    72 	 * The last error during query.
    76 	 * The last error during query.
    73 	 *
    77 	 *
    74 	 * @since 2.5.0
    78 	 * @since 2.5.0
    75 	 * @var string
    79 	 * @var string
    76 	 */
    80 	 */
    77 	var $last_error = '';
    81 	public $last_error = '';
    78 
    82 
    79 	/**
    83 	/**
    80 	 * Amount of queries made
    84 	 * Amount of queries made
    81 	 *
    85 	 *
    82 	 * @since 1.2.0
    86 	 * @since 1.2.0
   138 	 * @var mixed
   142 	 * @var mixed
   139 	 */
   143 	 */
   140 	protected $result;
   144 	protected $result;
   141 
   145 
   142 	/**
   146 	/**
       
   147 	 * Cached column info, for sanity checking data before inserting
       
   148 	 *
       
   149 	 * @since 4.2.0
       
   150 	 * @access protected
       
   151 	 * @var array
       
   152 	 */
       
   153 	protected $col_meta = array();
       
   154 
       
   155 	/**
       
   156 	 * Calculated character sets on tables
       
   157 	 *
       
   158 	 * @since 4.2.0
       
   159 	 * @access protected
       
   160 	 * @var array
       
   161 	 */
       
   162 	protected $table_charset = array();
       
   163 
       
   164 	/**
       
   165 	 * Whether text fields in the current query need to be sanity checked.
       
   166 	 *
       
   167 	 * @since 4.2.0
       
   168 	 * @access protected
       
   169 	 * @var bool
       
   170 	 */
       
   171 	protected $check_current_query = true;
       
   172 
       
   173 	/**
       
   174 	 * Flag to ensure we don't run into recursion problems when checking the collation.
       
   175 	 *
       
   176 	 * @since 4.2.0
       
   177 	 * @access private
       
   178 	 * @see wpdb::check_safe_collation()
       
   179 	 * @var boolean
       
   180 	 */
       
   181 	private $checking_collation = false;
       
   182 
       
   183 	/**
   143 	 * Saved info on the table column
   184 	 * Saved info on the table column
   144 	 *
   185 	 *
   145 	 * @since 0.71
   186 	 * @since 0.71
   146 	 * @access protected
   187 	 * @access protected
   147 	 * @var array
   188 	 * @var array
   156 	 * @var array
   197 	 * @var array
   157 	 */
   198 	 */
   158 	var $queries;
   199 	var $queries;
   159 
   200 
   160 	/**
   201 	/**
       
   202 	 * The number of times to retry reconnecting before dying.
       
   203 	 *
       
   204 	 * @since 3.9.0
       
   205 	 * @access protected
       
   206 	 * @see wpdb::check_connection()
       
   207 	 * @var int
       
   208 	 */
       
   209 	protected $reconnect_retries = 5;
       
   210 
       
   211 	/**
   161 	 * WordPress table prefix
   212 	 * WordPress table prefix
   162 	 *
   213 	 *
   163 	 * You can set this to have multiple WordPress installations
   214 	 * You can set this to have multiple WordPress installations
   164 	 * in a single database. The second reason is for possible
   215 	 * in a single database. The second reason is for possible
   165 	 * security precautions.
   216 	 * security precautions.
   169 	 * @var string
   220 	 * @var string
   170 	 */
   221 	 */
   171 	var $prefix = '';
   222 	var $prefix = '';
   172 
   223 
   173 	/**
   224 	/**
       
   225 	 * WordPress base table prefix.
       
   226 	 *
       
   227 	 * @since 3.0.0
       
   228 	 * @access public
       
   229 	 * @var string
       
   230 	 */
       
   231 	 public $base_prefix;
       
   232 
       
   233 	/**
   174 	 * Whether the database queries are ready to start executing.
   234 	 * Whether the database queries are ready to start executing.
   175 	 *
   235 	 *
   176 	 * @since 2.3.2
   236 	 * @since 2.3.2
   177 	 * @access private
   237 	 * @access private
   178 	 * @var bool
   238 	 * @var bool
   179 	 */
   239 	 */
   180 	var $ready = false;
   240 	var $ready = false;
   181 
   241 
   182 	/**
   242 	/**
   183 	 * {@internal Missing Description}}
   243 	 * Blog ID.
   184 	 *
   244 	 *
   185 	 * @since 3.0.0
   245 	 * @since 3.0.0
   186 	 * @access public
   246 	 * @access public
   187 	 * @var int
   247 	 * @var int
   188 	 */
   248 	 */
   189 	var $blogid = 0;
   249 	public $blogid = 0;
   190 
   250 
   191 	/**
   251 	/**
   192 	 * {@internal Missing Description}}
   252 	 * Site ID.
   193 	 *
   253 	 *
   194 	 * @since 3.0.0
   254 	 * @since 3.0.0
   195 	 * @access public
   255 	 * @access public
   196 	 * @var int
   256 	 * @var int
   197 	 */
   257 	 */
   198 	var $siteid = 0;
   258 	public $siteid = 0;
   199 
   259 
   200 	/**
   260 	/**
   201 	 * List of WordPress per-blog tables
   261 	 * List of WordPress per-blog tables
   202 	 *
   262 	 *
   203 	 * @since 2.5.0
   263 	 * @since 2.5.0
   246 	 *
   306 	 *
   247 	 * @since 1.5.0
   307 	 * @since 1.5.0
   248 	 * @access public
   308 	 * @access public
   249 	 * @var string
   309 	 * @var string
   250 	 */
   310 	 */
   251 	var $comments;
   311 	public $comments;
   252 
   312 
   253 	/**
   313 	/**
   254 	 * WordPress Comment Metadata table
   314 	 * WordPress Comment Metadata table
   255 	 *
   315 	 *
   256 	 * @since 2.9.0
   316 	 * @since 2.9.0
   257 	 * @access public
   317 	 * @access public
   258 	 * @var string
   318 	 * @var string
   259 	 */
   319 	 */
   260 	var $commentmeta;
   320 	public $commentmeta;
   261 
   321 
   262 	/**
   322 	/**
   263 	 * WordPress Links table
   323 	 * WordPress Links table
   264 	 *
   324 	 *
   265 	 * @since 1.5.0
   325 	 * @since 1.5.0
   266 	 * @access public
   326 	 * @access public
   267 	 * @var string
   327 	 * @var string
   268 	 */
   328 	 */
   269 	var $links;
   329 	public $links;
   270 
   330 
   271 	/**
   331 	/**
   272 	 * WordPress Options table
   332 	 * WordPress Options table
   273 	 *
   333 	 *
   274 	 * @since 1.5.0
   334 	 * @since 1.5.0
   275 	 * @access public
   335 	 * @access public
   276 	 * @var string
   336 	 * @var string
   277 	 */
   337 	 */
   278 	var $options;
   338 	public $options;
   279 
   339 
   280 	/**
   340 	/**
   281 	 * WordPress Post Metadata table
   341 	 * WordPress Post Metadata table
   282 	 *
   342 	 *
   283 	 * @since 1.5.0
   343 	 * @since 1.5.0
   284 	 * @access public
   344 	 * @access public
   285 	 * @var string
   345 	 * @var string
   286 	 */
   346 	 */
   287 	var $postmeta;
   347 	public $postmeta;
   288 
   348 
   289 	/**
   349 	/**
   290 	 * WordPress Posts table
   350 	 * WordPress Posts table
   291 	 *
   351 	 *
   292 	 * @since 1.5.0
   352 	 * @since 1.5.0
   293 	 * @access public
   353 	 * @access public
   294 	 * @var string
   354 	 * @var string
   295 	 */
   355 	 */
   296 	var $posts;
   356 	public $posts;
   297 
   357 
   298 	/**
   358 	/**
   299 	 * WordPress Terms table
   359 	 * WordPress Terms table
   300 	 *
   360 	 *
   301 	 * @since 2.3.0
   361 	 * @since 2.3.0
   302 	 * @access public
   362 	 * @access public
   303 	 * @var string
   363 	 * @var string
   304 	 */
   364 	 */
   305 	var $terms;
   365 	public $terms;
   306 
   366 
   307 	/**
   367 	/**
   308 	 * WordPress Term Relationships table
   368 	 * WordPress Term Relationships table
   309 	 *
   369 	 *
   310 	 * @since 2.3.0
   370 	 * @since 2.3.0
   311 	 * @access public
   371 	 * @access public
   312 	 * @var string
   372 	 * @var string
   313 	 */
   373 	 */
   314 	var $term_relationships;
   374 	public $term_relationships;
   315 
   375 
   316 	/**
   376 	/**
   317 	 * WordPress Term Taxonomy table
   377 	 * WordPress Term Taxonomy table
   318 	 *
   378 	 *
   319 	 * @since 2.3.0
   379 	 * @since 2.3.0
   320 	 * @access public
   380 	 * @access public
   321 	 * @var string
   381 	 * @var string
   322 	 */
   382 	 */
   323 	var $term_taxonomy;
   383 	public $term_taxonomy;
   324 
   384 
   325 	/*
   385 	/*
   326 	 * Global and Multisite tables
   386 	 * Global and Multisite tables
   327 	 */
   387 	 */
   328 
   388 
   331 	 *
   391 	 *
   332 	 * @since 2.3.0
   392 	 * @since 2.3.0
   333 	 * @access public
   393 	 * @access public
   334 	 * @var string
   394 	 * @var string
   335 	 */
   395 	 */
   336 	var $usermeta;
   396 	public $usermeta;
   337 
   397 
   338 	/**
   398 	/**
   339 	 * WordPress Users table
   399 	 * WordPress Users table
   340 	 *
   400 	 *
   341 	 * @since 1.5.0
   401 	 * @since 1.5.0
   342 	 * @access public
   402 	 * @access public
   343 	 * @var string
   403 	 * @var string
   344 	 */
   404 	 */
   345 	var $users;
   405 	public $users;
   346 
   406 
   347 	/**
   407 	/**
   348 	 * Multisite Blogs table
   408 	 * Multisite Blogs table
   349 	 *
   409 	 *
   350 	 * @since 3.0.0
   410 	 * @since 3.0.0
   351 	 * @access public
   411 	 * @access public
   352 	 * @var string
   412 	 * @var string
   353 	 */
   413 	 */
   354 	var $blogs;
   414 	public $blogs;
   355 
   415 
   356 	/**
   416 	/**
   357 	 * Multisite Blog Versions table
   417 	 * Multisite Blog Versions table
   358 	 *
   418 	 *
   359 	 * @since 3.0.0
   419 	 * @since 3.0.0
   360 	 * @access public
   420 	 * @access public
   361 	 * @var string
   421 	 * @var string
   362 	 */
   422 	 */
   363 	var $blog_versions;
   423 	public $blog_versions;
   364 
   424 
   365 	/**
   425 	/**
   366 	 * Multisite Registration Log table
   426 	 * Multisite Registration Log table
   367 	 *
   427 	 *
   368 	 * @since 3.0.0
   428 	 * @since 3.0.0
   369 	 * @access public
   429 	 * @access public
   370 	 * @var string
   430 	 * @var string
   371 	 */
   431 	 */
   372 	var $registration_log;
   432 	public $registration_log;
   373 
   433 
   374 	/**
   434 	/**
   375 	 * Multisite Signups table
   435 	 * Multisite Signups table
   376 	 *
   436 	 *
   377 	 * @since 3.0.0
   437 	 * @since 3.0.0
   378 	 * @access public
   438 	 * @access public
   379 	 * @var string
   439 	 * @var string
   380 	 */
   440 	 */
   381 	var $signups;
   441 	public $signups;
   382 
   442 
   383 	/**
   443 	/**
   384 	 * Multisite Sites table
   444 	 * Multisite Sites table
   385 	 *
   445 	 *
   386 	 * @since 3.0.0
   446 	 * @since 3.0.0
   387 	 * @access public
   447 	 * @access public
   388 	 * @var string
   448 	 * @var string
   389 	 */
   449 	 */
   390 	var $site;
   450 	public $site;
   391 
   451 
   392 	/**
   452 	/**
   393 	 * Multisite Sitewide Terms table
   453 	 * Multisite Sitewide Terms table
   394 	 *
   454 	 *
   395 	 * @since 3.0.0
   455 	 * @since 3.0.0
   396 	 * @access public
   456 	 * @access public
   397 	 * @var string
   457 	 * @var string
   398 	 */
   458 	 */
   399 	var $sitecategories;
   459 	public $sitecategories;
   400 
   460 
   401 	/**
   461 	/**
   402 	 * Multisite Site Metadata table
   462 	 * Multisite Site Metadata table
   403 	 *
   463 	 *
   404 	 * @since 3.0.0
   464 	 * @since 3.0.0
   405 	 * @access public
   465 	 * @access public
   406 	 * @var string
   466 	 * @var string
   407 	 */
   467 	 */
   408 	var $sitemeta;
   468 	public $sitemeta;
   409 
   469 
   410 	/**
   470 	/**
   411 	 * Format specifiers for DB columns. Columns not listed here default to %s. Initialized during WP load.
   471 	 * Format specifiers for DB columns. Columns not listed here default to %s. Initialized during WP load.
   412 	 *
   472 	 *
   413 	 * Keys are column names, values are format types: 'ID' => '%d'
   473 	 * Keys are column names, values are format types: 'ID' => '%d'
   419 	 * @see wpdb::delete()
   479 	 * @see wpdb::delete()
   420 	 * @see wp_set_wpdb_vars()
   480 	 * @see wp_set_wpdb_vars()
   421 	 * @access public
   481 	 * @access public
   422 	 * @var array
   482 	 * @var array
   423 	 */
   483 	 */
   424 	var $field_types = array();
   484 	public $field_types = array();
   425 
   485 
   426 	/**
   486 	/**
   427 	 * Database table columns charset
   487 	 * Database table columns charset
   428 	 *
   488 	 *
   429 	 * @since 2.2.0
   489 	 * @since 2.2.0
   430 	 * @access public
   490 	 * @access public
   431 	 * @var string
   491 	 * @var string
   432 	 */
   492 	 */
   433 	var $charset;
   493 	public $charset;
   434 
   494 
   435 	/**
   495 	/**
   436 	 * Database table columns collate
   496 	 * Database table columns collate
   437 	 *
   497 	 *
   438 	 * @since 2.2.0
   498 	 * @since 2.2.0
   439 	 * @access public
   499 	 * @access public
   440 	 * @var string
   500 	 * @var string
   441 	 */
   501 	 */
   442 	var $collate;
   502 	public $collate;
   443 
   503 
   444 	/**
   504 	/**
   445 	 * Database Username
   505 	 * Database Username
   446 	 *
   506 	 *
   447 	 * @since 2.9.0
   507 	 * @since 2.9.0
   491 	 *
   551 	 *
   492 	 * @since 3.0.0
   552 	 * @since 3.0.0
   493 	 * @access public
   553 	 * @access public
   494 	 * @var string
   554 	 * @var string
   495 	 */
   555 	 */
   496 	var $func_call;
   556 	public $func_call;
   497 
   557 
   498 	/**
   558 	/**
   499 	 * Whether MySQL is used as the database engine.
   559 	 * Whether MySQL is used as the database engine.
   500 	 *
   560 	 *
   501 	 * Set in WPDB::db_connect() to true, by default. This is used when checking
   561 	 * Set in WPDB::db_connect() to true, by default. This is used when checking
   508 	 * @var bool
   568 	 * @var bool
   509 	 */
   569 	 */
   510 	public $is_mysql = null;
   570 	public $is_mysql = null;
   511 
   571 
   512 	/**
   572 	/**
       
   573 	 * A list of incompatible SQL modes.
       
   574 	 *
       
   575 	 * @since 3.9.0
       
   576 	 * @access protected
       
   577 	 * @var array
       
   578 	 */
       
   579 	protected $incompatible_modes = array( 'NO_ZERO_DATE', 'ONLY_FULL_GROUP_BY',
       
   580 		'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'TRADITIONAL' );
       
   581 
       
   582 	/**
       
   583 	 * Whether to use mysqli over mysql.
       
   584 	 *
       
   585 	 * @since 3.9.0
       
   586 	 * @access private
       
   587 	 * @var bool
       
   588 	 */
       
   589 	private $use_mysqli = false;
       
   590 
       
   591 	/**
       
   592 	 * Whether we've managed to successfully connect at some point
       
   593 	 *
       
   594 	 * @since 3.9.0
       
   595 	 * @access private
       
   596 	 * @var bool
       
   597 	 */
       
   598 	private $has_connected = false;
       
   599 
       
   600 	/**
   513 	 * Connects to the database server and selects a database
   601 	 * Connects to the database server and selects a database
   514 	 *
   602 	 *
   515 	 * PHP5 style constructor for compatibility with PHP5. Does
   603 	 * PHP5 style constructor for compatibility with PHP5. Does
   516 	 * the actual setting up of the class properties and connection
   604 	 * the actual setting up of the class properties and connection
   517 	 * to the database.
   605 	 * to the database.
   518 	 *
   606 	 *
   519 	 * @link http://core.trac.wordpress.org/ticket/3354
   607 	 * @link https://core.trac.wordpress.org/ticket/3354
   520 	 * @since 2.0.8
   608 	 * @since 2.0.8
   521 	 *
   609 	 *
   522 	 * @param string $dbuser MySQL database user
   610 	 * @param string $dbuser MySQL database user
   523 	 * @param string $dbpassword MySQL database password
   611 	 * @param string $dbpassword MySQL database password
   524 	 * @param string $dbname MySQL database name
   612 	 * @param string $dbname MySQL database name
   525 	 * @param string $dbhost MySQL database host
   613 	 * @param string $dbhost MySQL database host
   526 	 */
   614 	 */
   527 	function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
   615 	public function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
   528 		register_shutdown_function( array( $this, '__destruct' ) );
   616 		register_shutdown_function( array( $this, '__destruct' ) );
   529 
   617 
   530 		if ( WP_DEBUG && WP_DEBUG_DISPLAY )
   618 		if ( WP_DEBUG && WP_DEBUG_DISPLAY )
   531 			$this->show_errors();
   619 			$this->show_errors();
   532 
   620 
   533 		$this->init_charset();
   621 		/* Use ext/mysqli if it exists and:
       
   622 		 *  - WP_USE_EXT_MYSQL is defined as false, or
       
   623 		 *  - We are a development version of WordPress, or
       
   624 		 *  - We are running PHP 5.5 or greater, or
       
   625 		 *  - ext/mysql is not loaded.
       
   626 		 */
       
   627 		if ( function_exists( 'mysqli_connect' ) ) {
       
   628 			if ( defined( 'WP_USE_EXT_MYSQL' ) ) {
       
   629 				$this->use_mysqli = ! WP_USE_EXT_MYSQL;
       
   630 			} elseif ( version_compare( phpversion(), '5.5', '>=' ) || ! function_exists( 'mysql_connect' ) ) {
       
   631 				$this->use_mysqli = true;
       
   632 			} elseif ( false !== strpos( $GLOBALS['wp_version'], '-' ) ) {
       
   633 				$this->use_mysqli = true;
       
   634 			}
       
   635 		}
   534 
   636 
   535 		$this->dbuser = $dbuser;
   637 		$this->dbuser = $dbuser;
   536 		$this->dbpassword = $dbpassword;
   638 		$this->dbpassword = $dbpassword;
   537 		$this->dbname = $dbname;
   639 		$this->dbname = $dbname;
   538 		$this->dbhost = $dbhost;
   640 		$this->dbhost = $dbhost;
   539 
   641 
       
   642 		// wp-config.php creation will manually connect when ready.
       
   643 		if ( defined( 'WP_SETUP_CONFIG' ) ) {
       
   644 			return;
       
   645 		}
       
   646 
   540 		$this->db_connect();
   647 		$this->db_connect();
   541 	}
   648 	}
   542 
   649 
   543 	/**
   650 	/**
   544 	 * PHP5 style destructor and will run when database object is destroyed.
   651 	 * PHP5 style destructor and will run when database object is destroyed.
   545 	 *
   652 	 *
   546 	 * @see wpdb::__construct()
   653 	 * @see wpdb::__construct()
   547 	 * @since 2.0.8
   654 	 * @since 2.0.8
   548 	 * @return bool true
   655 	 * @return bool true
   549 	 */
   656 	 */
   550 	function __destruct() {
   657 	public function __destruct() {
   551 		return true;
   658 		return true;
   552 	}
   659 	}
   553 
   660 
   554 	/**
   661 	/**
   555 	 * PHP5 style magic getter, used to lazy-load expensive data.
   662 	 * PHP5 style magic getter, used to lazy-load expensive data.
   557 	 * @since 3.5.0
   664 	 * @since 3.5.0
   558 	 *
   665 	 *
   559 	 * @param string $name The private member to get, and optionally process
   666 	 * @param string $name The private member to get, and optionally process
   560 	 * @return mixed The private member
   667 	 * @return mixed The private member
   561 	 */
   668 	 */
   562 	function __get( $name ) {
   669 	public function __get( $name ) {
   563 		if ( 'col_info' == $name )
   670 		if ( 'col_info' === $name )
   564 			$this->load_col_info();
   671 			$this->load_col_info();
   565 
   672 
   566 		return $this->$name;
   673 		return $this->$name;
   567 	}
   674 	}
   568 
   675 
   569 	/**
   676 	/**
   570 	 * Magic function, for backwards compatibility
   677 	 * Magic function, for backwards compatibility.
   571 	 *
   678 	 *
   572 	 * @since 3.5.0
   679 	 * @since 3.5.0
   573 	 *
   680 	 *
   574 	 * @param string $name  The private member to set
   681 	 * @param string $name  The private member to set
   575 	 * @param mixed  $value The value to set
   682 	 * @param mixed  $value The value to set
   576 	 */
   683 	 */
   577 	function __set( $name, $value ) {
   684 	public function __set( $name, $value ) {
       
   685 		$protected_members = array(
       
   686 			'col_meta',
       
   687 			'table_charset',
       
   688 			'check_current_query',
       
   689 		);
       
   690 		if (  in_array( $name, $protected_members, true ) ) {
       
   691 			return;
       
   692 		}
   578 		$this->$name = $value;
   693 		$this->$name = $value;
   579 	}
   694 	}
   580 
   695 
   581 	/**
   696 	/**
   582 	 * Magic function, for backwards compatibility
   697 	 * Magic function, for backwards compatibility.
   583 	 *
   698 	 *
   584 	 * @since 3.5.0
   699 	 * @since 3.5.0
   585 	 *
   700 	 *
   586 	 * @param string $name  The private member to check
   701 	 * @param string $name  The private member to check
   587 	 *
   702 	 *
   588 	 * @return bool If the member is set or not
   703 	 * @return bool If the member is set or not
   589 	 */
   704 	 */
   590 	function __isset( $name ) {
   705 	public function __isset( $name ) {
   591 		return isset( $this->$name );
   706 		return isset( $this->$name );
   592 	}
   707 	}
   593 
   708 
   594 	/**
   709 	/**
   595 	 * Magic function, for backwards compatibility
   710 	 * Magic function, for backwards compatibility.
   596 	 *
   711 	 *
   597 	 * @since 3.5.0
   712 	 * @since 3.5.0
   598 	 *
   713 	 *
   599 	 * @param string $name  The private member to unset
   714 	 * @param string $name  The private member to unset
   600 	 */
   715 	 */
   601 	function __unset( $name ) {
   716 	public function __unset( $name ) {
   602 		unset( $this->$name );
   717 		unset( $this->$name );
   603 	}
   718 	}
   604 
   719 
   605 	/**
   720 	/**
   606 	 * Set $this->charset and $this->collate
   721 	 * Set $this->charset and $this->collate
   607 	 *
   722 	 *
   608 	 * @since 3.1.0
   723 	 * @since 3.1.0
   609 	 */
   724 	 */
   610 	function init_charset() {
   725 	public function init_charset() {
   611 		if ( function_exists('is_multisite') && is_multisite() ) {
   726 		if ( function_exists('is_multisite') && is_multisite() ) {
   612 			$this->charset = 'utf8';
   727 			$this->charset = 'utf8';
   613 			if ( defined( 'DB_COLLATE' ) && DB_COLLATE )
   728 			if ( defined( 'DB_COLLATE' ) && DB_COLLATE ) {
   614 				$this->collate = DB_COLLATE;
   729 				$this->collate = DB_COLLATE;
   615 			else
   730 			} else {
   616 				$this->collate = 'utf8_general_ci';
   731 				$this->collate = 'utf8_general_ci';
       
   732 			}
   617 		} elseif ( defined( 'DB_COLLATE' ) ) {
   733 		} elseif ( defined( 'DB_COLLATE' ) ) {
   618 			$this->collate = DB_COLLATE;
   734 			$this->collate = DB_COLLATE;
   619 		}
   735 		}
   620 
   736 
   621 		if ( defined( 'DB_CHARSET' ) )
   737 		if ( defined( 'DB_CHARSET' ) ) {
   622 			$this->charset = DB_CHARSET;
   738 			$this->charset = DB_CHARSET;
       
   739 		}
       
   740 
       
   741 		if ( ( $this->use_mysqli && ! ( $this->dbh instanceof mysqli ) )
       
   742 		  || ( empty( $this->dbh ) || ! ( $this->dbh instanceof mysqli ) ) ) {
       
   743 			return;
       
   744 		}
       
   745 
       
   746 		if ( 'utf8' === $this->charset && $this->has_cap( 'utf8mb4' ) ) {
       
   747 			$this->charset = 'utf8mb4';
       
   748 		}
       
   749 
       
   750 		if ( 'utf8mb4' === $this->charset && ( ! $this->collate || stripos( $this->collate, 'utf8_' ) === 0 ) ) {
       
   751 			$this->collate = 'utf8mb4_unicode_ci';
       
   752 		}
   623 	}
   753 	}
   624 
   754 
   625 	/**
   755 	/**
   626 	 * Sets the connection's character set.
   756 	 * Sets the connection's character set.
   627 	 *
   757 	 *
   628 	 * @since 3.1.0
   758 	 * @since 3.1.0
   629 	 *
   759 	 *
   630 	 * @param resource $dbh     The resource given by mysql_connect
   760 	 * @param resource $dbh     The resource given by mysql_connect
   631 	 * @param string   $charset The character set (optional)
   761 	 * @param string   $charset Optional. The character set. Default null.
   632 	 * @param string   $collate The collation (optional)
   762 	 * @param string   $collate Optional. The collation. Default null.
   633 	 */
   763 	 */
   634 	function set_charset( $dbh, $charset = null, $collate = null ) {
   764 	public function set_charset( $dbh, $charset = null, $collate = null ) {
   635 		if ( ! isset( $charset ) )
   765 		if ( ! isset( $charset ) )
   636 			$charset = $this->charset;
   766 			$charset = $this->charset;
   637 		if ( ! isset( $collate ) )
   767 		if ( ! isset( $collate ) )
   638 			$collate = $this->collate;
   768 			$collate = $this->collate;
   639 		if ( $this->has_cap( 'collation' ) && ! empty( $charset ) ) {
   769 		if ( $this->has_cap( 'collation' ) && ! empty( $charset ) ) {
   640 			if ( function_exists( 'mysql_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
   770 			if ( $this->use_mysqli ) {
   641 				mysql_set_charset( $charset, $dbh );
   771 				if ( function_exists( 'mysqli_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
       
   772 					mysqli_set_charset( $dbh, $charset );
       
   773 				} else {
       
   774 					$query = $this->prepare( 'SET NAMES %s', $charset );
       
   775 					if ( ! empty( $collate ) )
       
   776 						$query .= $this->prepare( ' COLLATE %s', $collate );
       
   777 					mysqli_query( $dbh, $query );
       
   778 				}
   642 			} else {
   779 			} else {
   643 				$query = $this->prepare( 'SET NAMES %s', $charset );
   780 				if ( function_exists( 'mysql_set_charset' ) && $this->has_cap( 'set_charset' ) ) {
   644 				if ( ! empty( $collate ) )
   781 					mysql_set_charset( $charset, $dbh );
   645 					$query .= $this->prepare( ' COLLATE %s', $collate );
   782 				} else {
   646 				mysql_query( $query, $dbh );
   783 					$query = $this->prepare( 'SET NAMES %s', $charset );
   647 			}
   784 					if ( ! empty( $collate ) )
       
   785 						$query .= $this->prepare( ' COLLATE %s', $collate );
       
   786 					mysql_query( $query, $dbh );
       
   787 				}
       
   788 			}
       
   789 		}
       
   790 	}
       
   791 
       
   792 	/**
       
   793 	 * Change the current SQL mode, and ensure its WordPress compatibility.
       
   794 	 *
       
   795 	 * If no modes are passed, it will ensure the current MySQL server
       
   796 	 * modes are compatible.
       
   797 	 *
       
   798 	 * @since 3.9.0
       
   799 	 *
       
   800 	 * @param array $modes Optional. A list of SQL modes to set.
       
   801 	 */
       
   802 	public function set_sql_mode( $modes = array() ) {
       
   803 		if ( empty( $modes ) ) {
       
   804 			if ( $this->use_mysqli ) {
       
   805 				$res = mysqli_query( $this->dbh, 'SELECT @@SESSION.sql_mode' );
       
   806 			} else {
       
   807 				$res = mysql_query( 'SELECT @@SESSION.sql_mode', $this->dbh );
       
   808 			}
       
   809 
       
   810 			if ( empty( $res ) ) {
       
   811 				return;
       
   812 			}
       
   813 
       
   814 			if ( $this->use_mysqli ) {
       
   815 				$modes_array = mysqli_fetch_array( $res );
       
   816 				if ( empty( $modes_array[0] ) ) {
       
   817 					return;
       
   818 				}
       
   819 				$modes_str = $modes_array[0];
       
   820 			} else {
       
   821 				$modes_str = mysql_result( $res, 0 );
       
   822 			}
       
   823 
       
   824 			if ( empty( $modes_str ) ) {
       
   825 				return;
       
   826 			}
       
   827 
       
   828 			$modes = explode( ',', $modes_str );
       
   829 		}
       
   830 
       
   831 		$modes = array_change_key_case( $modes, CASE_UPPER );
       
   832 
       
   833 		/**
       
   834 		 * Filter the list of incompatible SQL modes to exclude.
       
   835 		 *
       
   836 		 * @since 3.9.0
       
   837 		 *
       
   838 		 * @param array $incompatible_modes An array of incompatible modes.
       
   839 		 */
       
   840 		$incompatible_modes = (array) apply_filters( 'incompatible_sql_modes', $this->incompatible_modes );
       
   841 
       
   842 		foreach( $modes as $i => $mode ) {
       
   843 			if ( in_array( $mode, $incompatible_modes ) ) {
       
   844 				unset( $modes[ $i ] );
       
   845 			}
       
   846 		}
       
   847 
       
   848 		$modes_str = implode( ',', $modes );
       
   849 
       
   850 		if ( $this->use_mysqli ) {
       
   851 			mysqli_query( $this->dbh, "SET SESSION sql_mode='$modes_str'" );
       
   852 		} else {
       
   853 			mysql_query( "SET SESSION sql_mode='$modes_str'", $this->dbh );
   648 		}
   854 		}
   649 	}
   855 	}
   650 
   856 
   651 	/**
   857 	/**
   652 	 * Sets the table prefix for the WordPress tables.
   858 	 * Sets the table prefix for the WordPress tables.
   655 	 *
   861 	 *
   656 	 * @param string $prefix Alphanumeric name for the new prefix.
   862 	 * @param string $prefix Alphanumeric name for the new prefix.
   657 	 * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not.
   863 	 * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not.
   658 	 * @return string|WP_Error Old prefix or WP_Error on error
   864 	 * @return string|WP_Error Old prefix or WP_Error on error
   659 	 */
   865 	 */
   660 	function set_prefix( $prefix, $set_table_names = true ) {
   866 	public function set_prefix( $prefix, $set_table_names = true ) {
   661 
   867 
   662 		if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
   868 		if ( preg_match( '|[^a-z0-9_]|i', $prefix ) )
   663 			return new WP_Error('invalid_db_prefix', 'Invalid database prefix' );
   869 			return new WP_Error('invalid_db_prefix', 'Invalid database prefix' );
   664 
   870 
   665 		$old_prefix = is_multisite() ? '' : $prefix;
   871 		$old_prefix = is_multisite() ? '' : $prefix;
   692 	 *
   898 	 *
   693 	 * @since 3.0.0
   899 	 * @since 3.0.0
   694 	 * @access public
   900 	 * @access public
   695 	 * @param int $blog_id
   901 	 * @param int $blog_id
   696 	 * @param int $site_id Optional.
   902 	 * @param int $site_id Optional.
   697 	 * @return string previous blog id
   903 	 * @return int previous blog id
   698 	 */
   904 	 */
   699 	function set_blog_id( $blog_id, $site_id = 0 ) {
   905 	public function set_blog_id( $blog_id, $site_id = 0 ) {
   700 		if ( ! empty( $site_id ) )
   906 		if ( ! empty( $site_id ) )
   701 			$this->siteid = $site_id;
   907 			$this->siteid = $site_id;
   702 
   908 
   703 		$old_blog_id  = $this->blogid;
   909 		$old_blog_id  = $this->blogid;
   704 		$this->blogid = $blog_id;
   910 		$this->blogid = $blog_id;
   715 	}
   921 	}
   716 
   922 
   717 	/**
   923 	/**
   718 	 * Gets blog prefix.
   924 	 * Gets blog prefix.
   719 	 *
   925 	 *
   720 	 * @uses is_multisite()
       
   721 	 * @since 3.0.0
   926 	 * @since 3.0.0
   722 	 * @param int $blog_id Optional.
   927 	 * @param int $blog_id Optional.
   723 	 * @return string Blog prefix.
   928 	 * @return string Blog prefix.
   724 	 */
   929 	 */
   725 	function get_blog_prefix( $blog_id = null ) {
   930 	public function get_blog_prefix( $blog_id = null ) {
   726 		if ( is_multisite() ) {
   931 		if ( is_multisite() ) {
   727 			if ( null === $blog_id )
   932 			if ( null === $blog_id )
   728 				$blog_id = $this->blogid;
   933 				$blog_id = $this->blogid;
   729 			$blog_id = (int) $blog_id;
   934 			$blog_id = (int) $blog_id;
   730 			if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) )
   935 			if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) )
   754 	 * @since 3.0.0
   959 	 * @since 3.0.0
   755 	 * @uses wpdb::$tables
   960 	 * @uses wpdb::$tables
   756 	 * @uses wpdb::$old_tables
   961 	 * @uses wpdb::$old_tables
   757 	 * @uses wpdb::$global_tables
   962 	 * @uses wpdb::$global_tables
   758 	 * @uses wpdb::$ms_global_tables
   963 	 * @uses wpdb::$ms_global_tables
   759 	 * @uses is_multisite()
       
   760 	 *
   964 	 *
   761 	 * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all.
   965 	 * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all.
   762 	 * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog
   966 	 * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog
   763 	 * 	prefix is requested, then the custom users and usermeta tables will be mapped.
   967 	 * 	prefix is requested, then the custom users and usermeta tables will be mapped.
   764 	 * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested.
   968 	 * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested.
   765 	 * @return array Table names. When a prefix is requested, the key is the unprefixed table name.
   969 	 * @return array Table names. When a prefix is requested, the key is the unprefixed table name.
   766 	 */
   970 	 */
   767 	function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) {
   971 	public function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) {
   768 		switch ( $scope ) {
   972 		switch ( $scope ) {
   769 			case 'all' :
   973 			case 'all' :
   770 				$tables = array_merge( $this->global_tables, $this->tables );
   974 				$tables = array_merge( $this->global_tables, $this->tables );
   771 				if ( is_multisite() )
   975 				if ( is_multisite() )
   772 					$tables = array_merge( $tables, $this->ms_global_tables );
   976 					$tables = array_merge( $tables, $this->ms_global_tables );
   785 			case 'old' :
   989 			case 'old' :
   786 				$tables = $this->old_tables;
   990 				$tables = $this->old_tables;
   787 				break;
   991 				break;
   788 			default :
   992 			default :
   789 				return array();
   993 				return array();
   790 				break;
       
   791 		}
   994 		}
   792 
   995 
   793 		if ( $prefix ) {
   996 		if ( $prefix ) {
   794 			if ( ! $blog_id )
   997 			if ( ! $blog_id )
   795 				$blog_id = $this->blogid;
   998 				$blog_id = $this->blogid;
   824 	 *
  1027 	 *
   825 	 * @param string $db MySQL database name
  1028 	 * @param string $db MySQL database name
   826 	 * @param resource $dbh Optional link identifier.
  1029 	 * @param resource $dbh Optional link identifier.
   827 	 * @return null Always null.
  1030 	 * @return null Always null.
   828 	 */
  1031 	 */
   829 	function select( $db, $dbh = null ) {
  1032 	public function select( $db, $dbh = null ) {
   830 		if ( is_null($dbh) )
  1033 		if ( is_null($dbh) )
   831 			$dbh = $this->dbh;
  1034 			$dbh = $this->dbh;
   832 
  1035 
   833 		if ( !@mysql_select_db( $db, $dbh ) ) {
  1036 		if ( $this->use_mysqli ) {
       
  1037 			$success = @mysqli_select_db( $dbh, $db );
       
  1038 		} else {
       
  1039 			$success = @mysql_select_db( $db, $dbh );
       
  1040 		}
       
  1041 		if ( ! $success ) {
   834 			$this->ready = false;
  1042 			$this->ready = false;
   835 			wp_load_translations_early();
  1043 			if ( ! did_action( 'template_redirect' ) ) {
   836 			$this->bail( sprintf( __( '<h1>Can&#8217;t select database</h1>
  1044 				wp_load_translations_early();
       
  1045 				$this->bail( sprintf( __( '<h1>Can&#8217;t select database</h1>
   837 <p>We were able to connect to the database server (which means your username and password is okay) but not able to select the <code>%1$s</code> database.</p>
  1046 <p>We were able to connect to the database server (which means your username and password is okay) but not able to select the <code>%1$s</code> database.</p>
   838 <ul>
  1047 <ul>
   839 <li>Are you sure it exists?</li>
  1048 <li>Are you sure it exists?</li>
   840 <li>Does the user <code>%2$s</code> have permission to use the <code>%1$s</code> database?</li>
  1049 <li>Does the user <code>%2$s</code> have permission to use the <code>%1$s</code> database?</li>
   841 <li>On some systems the name of your database is prefixed with your username, so it would be like <code>username_%1$s</code>. Could that be the problem?</li>
  1050 <li>On some systems the name of your database is prefixed with your username, so it would be like <code>username_%1$s</code>. Could that be the problem?</li>
   842 </ul>
  1051 </ul>
   843 <p>If you don\'t know how to set up a database you should <strong>contact your host</strong>. If all else fails you may find help at the <a href="http://wordpress.org/support/">WordPress Support Forums</a>.</p>' ), htmlspecialchars( $db, ENT_QUOTES ), htmlspecialchars( $this->dbuser, ENT_QUOTES ) ), 'db_select_fail' );
  1052 <p>If you don\'t know how to set up a database you should <strong>contact your host</strong>. If all else fails you may find help at the <a href="https://wordpress.org/support/">WordPress Support Forums</a>.</p>' ), htmlspecialchars( $db, ENT_QUOTES ), htmlspecialchars( $this->dbuser, ENT_QUOTES ) ), 'db_select_fail' );
       
  1053 			}
   844 			return;
  1054 			return;
   845 		}
  1055 		}
   846 	}
  1056 	}
   847 
  1057 
   848 	/**
  1058 	/**
   864 			_deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' );
  1074 			_deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' );
   865 		return addslashes( $string );
  1075 		return addslashes( $string );
   866 	}
  1076 	}
   867 
  1077 
   868 	/**
  1078 	/**
   869 	 * Real escape, using mysql_real_escape_string()
  1079 	 * Real escape, using mysqli_real_escape_string() or mysql_real_escape_string()
   870 	 *
  1080 	 *
       
  1081 	 * @see mysqli_real_escape_string()
   871 	 * @see mysql_real_escape_string()
  1082 	 * @see mysql_real_escape_string()
   872 	 * @since 2.8.0
  1083 	 * @since 2.8.0
   873 	 * @access private
  1084 	 * @access private
   874 	 *
  1085 	 *
   875 	 * @param  string $string to escape
  1086 	 * @param  string $string to escape
   876 	 * @return string escaped
  1087 	 * @return string escaped
   877 	 */
  1088 	 */
   878 	function _real_escape( $string ) {
  1089 	function _real_escape( $string ) {
   879 		if ( $this->dbh )
  1090 		if ( $this->dbh ) {
   880 			return mysql_real_escape_string( $string, $this->dbh );
  1091 			if ( $this->use_mysqli ) {
       
  1092 				return mysqli_real_escape_string( $this->dbh, $string );
       
  1093 			} else {
       
  1094 				return mysql_real_escape_string( $string, $this->dbh );
       
  1095 			}
       
  1096 		}
   881 
  1097 
   882 		$class = get_class( $this );
  1098 		$class = get_class( $this );
   883 		_doing_it_wrong( $class, "$class must set a database connection for use with escaping.", E_USER_NOTICE );
  1099 		if ( function_exists( '__' ) ) {
       
  1100 			_doing_it_wrong( $class, sprintf( __( '%s must set a database connection for use with escaping.' ), $class ), E_USER_NOTICE );
       
  1101 		} else {
       
  1102 			_doing_it_wrong( $class, sprintf( '%s must set a database connection for use with escaping.', $class ), E_USER_NOTICE );
       
  1103 		}
   884 		return addslashes( $string );
  1104 		return addslashes( $string );
   885 	}
  1105 	}
   886 
  1106 
   887 	/**
  1107 	/**
   888 	 * Escape data. Works on arrays.
  1108 	 * Escape data. Works on arrays.
   920 	 * @see esc_sql()
  1140 	 * @see esc_sql()
   921 	 *
  1141 	 *
   922 	 * @param mixed $data
  1142 	 * @param mixed $data
   923 	 * @return mixed
  1143 	 * @return mixed
   924 	 */
  1144 	 */
   925 	function escape( $data ) {
  1145 	public function escape( $data ) {
   926 		if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) )
  1146 		if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) )
   927 			_deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' );
  1147 			_deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' );
   928 		if ( is_array( $data ) ) {
  1148 		if ( is_array( $data ) ) {
   929 			foreach ( $data as $k => $v ) {
  1149 			foreach ( $data as $k => $v ) {
   930 				if ( is_array( $v ) )
  1150 				if ( is_array( $v ) )
   945 	 * @uses wpdb::_real_escape()
  1165 	 * @uses wpdb::_real_escape()
   946 	 * @since 2.3.0
  1166 	 * @since 2.3.0
   947 	 * @param string $string to escape
  1167 	 * @param string $string to escape
   948 	 * @return void
  1168 	 * @return void
   949 	 */
  1169 	 */
   950 	function escape_by_ref( &$string ) {
  1170 	public function escape_by_ref( &$string ) {
   951 		if ( ! is_float( $string ) )
  1171 		if ( ! is_float( $string ) )
   952 			$string = $this->_real_escape( $string );
  1172 			$string = $this->_real_escape( $string );
   953 	}
  1173 	}
   954 
  1174 
   955 	/**
  1175 	/**
   970 	 *
  1190 	 *
   971 	 * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
  1191 	 * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}.
   972 	 *
  1192 	 *
   973 	 * Both %d and %s should be left unquoted in the query string.
  1193 	 * Both %d and %s should be left unquoted in the query string.
   974 	 *
  1194 	 *
   975 	 * <code>
  1195 	 *     wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", 'foo', 1337 )
   976 	 * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", 'foo', 1337 )
  1196 	 *     wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
   977 	 * wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' );
       
   978 	 * </code>
       
   979 	 *
  1197 	 *
   980 	 * @link http://php.net/sprintf Description of syntax.
  1198 	 * @link http://php.net/sprintf Description of syntax.
   981 	 * @since 2.3.0
  1199 	 * @since 2.3.0
   982 	 *
  1200 	 *
   983 	 * @param string $query Query statement with sprintf()-like placeholders
  1201 	 * @param string $query Query statement with sprintf()-like placeholders
   987 	 * @param mixed $args,... further variables to substitute into the query's placeholders if being called like
  1205 	 * @param mixed $args,... further variables to substitute into the query's placeholders if being called like
   988 	 * 	{@link http://php.net/sprintf sprintf()}.
  1206 	 * 	{@link http://php.net/sprintf sprintf()}.
   989 	 * @return null|false|string Sanitized query string, null if there is no query, false if there is an error and string
  1207 	 * @return null|false|string Sanitized query string, null if there is no query, false if there is an error and string
   990 	 * 	if there was something to prepare
  1208 	 * 	if there was something to prepare
   991 	 */
  1209 	 */
   992 	function prepare( $query, $args ) {
  1210 	public function prepare( $query, $args ) {
   993 		if ( is_null( $query ) )
  1211 		if ( is_null( $query ) )
   994 			return;
  1212 			return;
       
  1213 
       
  1214 		// This is not meant to be foolproof -- but it will catch obviously incorrect usage.
       
  1215 		if ( strpos( $query, '%' ) === false ) {
       
  1216 			_doing_it_wrong( 'wpdb::prepare', sprintf( __( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9' );
       
  1217 		}
   995 
  1218 
   996 		$args = func_get_args();
  1219 		$args = func_get_args();
   997 		array_shift( $args );
  1220 		array_shift( $args );
   998 		// If args were passed as an array (as in vsprintf), move them up
  1221 		// If args were passed as an array (as in vsprintf), move them up
   999 		if ( isset( $args[0] ) && is_array($args[0]) )
  1222 		if ( isset( $args[0] ) && is_array($args[0]) )
  1005 		array_walk( $args, array( $this, 'escape_by_ref' ) );
  1228 		array_walk( $args, array( $this, 'escape_by_ref' ) );
  1006 		return @vsprintf( $query, $args );
  1229 		return @vsprintf( $query, $args );
  1007 	}
  1230 	}
  1008 
  1231 
  1009 	/**
  1232 	/**
       
  1233 	 * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
       
  1234 	 *
       
  1235 	 * Use this only before wpdb::prepare() or esc_sql().  Reversing the order is very bad for security.
       
  1236 	 *
       
  1237 	 * Example Prepared Statement:
       
  1238 	 *  $wild = '%';
       
  1239 	 *  $find = 'only 43% of planets';
       
  1240 	 *  $like = $wild . $wpdb->esc_like( $find ) . $wild;
       
  1241 	 *  $sql  = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like );
       
  1242 	 *
       
  1243 	 * Example Escape Chain:
       
  1244 	 *  $sql  = esc_sql( $wpdb->esc_like( $input ) );
       
  1245 	 *
       
  1246 	 * @since 4.0.0
       
  1247 	 * @access public
       
  1248 	 *
       
  1249 	 * @param string $text The raw text to be escaped. The input typed by the user should have no
       
  1250 	 *                     extra or deleted slashes.
       
  1251 	 * @return string Text in the form of a LIKE phrase. The output is not SQL safe. Call $wpdb::prepare()
       
  1252 	 *                or real_escape next.
       
  1253 	 */
       
  1254 	public function esc_like( $text ) {
       
  1255 		return addcslashes( $text, '_%\\' );
       
  1256 	}
       
  1257 
       
  1258 	/**
  1010 	 * Print SQL/DB error.
  1259 	 * Print SQL/DB error.
  1011 	 *
  1260 	 *
  1012 	 * @since 0.71
  1261 	 * @since 0.71
  1013 	 * @global array $EZSQL_ERROR Stores error information of query and error string
  1262 	 * @global array $EZSQL_ERROR Stores error information of query and error string
  1014 	 *
  1263 	 *
  1015 	 * @param string $str The error to display
  1264 	 * @param string $str The error to display
  1016 	 * @return bool False if the showing of errors is disabled.
  1265 	 * @return false|null False if the showing of errors is disabled.
  1017 	 */
  1266 	 */
  1018 	function print_error( $str = '' ) {
  1267 	public function print_error( $str = '' ) {
  1019 		global $EZSQL_ERROR;
  1268 		global $EZSQL_ERROR;
  1020 
  1269 
  1021 		if ( !$str )
  1270 		if ( !$str ) {
  1022 			$str = mysql_error( $this->dbh );
  1271 			if ( $this->use_mysqli ) {
       
  1272 				$str = mysqli_error( $this->dbh );
       
  1273 			} else {
       
  1274 				$str = mysql_error( $this->dbh );
       
  1275 			}
       
  1276 		}
  1023 		$EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str );
  1277 		$EZSQL_ERROR[] = array( 'query' => $this->last_query, 'error_str' => $str );
  1024 
  1278 
  1025 		if ( $this->suppress_errors )
  1279 		if ( $this->suppress_errors )
  1026 			return false;
  1280 			return false;
  1027 
  1281 
  1068 	 * @see wpdb::hide_errors()
  1322 	 * @see wpdb::hide_errors()
  1069 	 *
  1323 	 *
  1070 	 * @param bool $show Whether to show or hide errors
  1324 	 * @param bool $show Whether to show or hide errors
  1071 	 * @return bool Old value for showing errors.
  1325 	 * @return bool Old value for showing errors.
  1072 	 */
  1326 	 */
  1073 	function show_errors( $show = true ) {
  1327 	public function show_errors( $show = true ) {
  1074 		$errors = $this->show_errors;
  1328 		$errors = $this->show_errors;
  1075 		$this->show_errors = $show;
  1329 		$this->show_errors = $show;
  1076 		return $errors;
  1330 		return $errors;
  1077 	}
  1331 	}
  1078 
  1332 
  1084 	 * @since 0.71
  1338 	 * @since 0.71
  1085 	 * @see wpdb::show_errors()
  1339 	 * @see wpdb::show_errors()
  1086 	 *
  1340 	 *
  1087 	 * @return bool Whether showing of errors was active
  1341 	 * @return bool Whether showing of errors was active
  1088 	 */
  1342 	 */
  1089 	function hide_errors() {
  1343 	public function hide_errors() {
  1090 		$show = $this->show_errors;
  1344 		$show = $this->show_errors;
  1091 		$this->show_errors = false;
  1345 		$this->show_errors = false;
  1092 		return $show;
  1346 		return $show;
  1093 	}
  1347 	}
  1094 
  1348 
  1101 	 * @since 2.5.0
  1355 	 * @since 2.5.0
  1102 	 * @see wpdb::hide_errors()
  1356 	 * @see wpdb::hide_errors()
  1103 	 * @param bool $suppress Optional. New value. Defaults to true.
  1357 	 * @param bool $suppress Optional. New value. Defaults to true.
  1104 	 * @return bool Old value
  1358 	 * @return bool Old value
  1105 	 */
  1359 	 */
  1106 	function suppress_errors( $suppress = true ) {
  1360 	public function suppress_errors( $suppress = true ) {
  1107 		$errors = $this->suppress_errors;
  1361 		$errors = $this->suppress_errors;
  1108 		$this->suppress_errors = (bool) $suppress;
  1362 		$this->suppress_errors = (bool) $suppress;
  1109 		return $errors;
  1363 		return $errors;
  1110 	}
  1364 	}
  1111 
  1365 
  1113 	 * Kill cached query results.
  1367 	 * Kill cached query results.
  1114 	 *
  1368 	 *
  1115 	 * @since 0.71
  1369 	 * @since 0.71
  1116 	 * @return void
  1370 	 * @return void
  1117 	 */
  1371 	 */
  1118 	function flush() {
  1372 	public function flush() {
  1119 		$this->last_result = array();
  1373 		$this->last_result = array();
  1120 		$this->col_info    = null;
  1374 		$this->col_info    = null;
  1121 		$this->last_query  = null;
  1375 		$this->last_query  = null;
  1122 		$this->rows_affected = $this->num_rows = 0;
  1376 		$this->rows_affected = $this->num_rows = 0;
  1123 		$this->last_error  = '';
  1377 		$this->last_error  = '';
  1124 
  1378 
  1125 		if ( is_resource( $this->result ) )
  1379 		if ( $this->use_mysqli && $this->result instanceof mysqli_result ) {
       
  1380 			mysqli_free_result( $this->result );
       
  1381 			$this->result = null;
       
  1382 
       
  1383 			// Sanity check before using the handle
       
  1384 			if ( empty( $this->dbh ) || !( $this->dbh instanceof mysqli ) ) {
       
  1385 				return;
       
  1386 			}
       
  1387 
       
  1388 			// Clear out any results from a multi-query
       
  1389 			while ( mysqli_more_results( $this->dbh ) ) {
       
  1390 				mysqli_next_result( $this->dbh );
       
  1391 			}
       
  1392 		} elseif ( is_resource( $this->result ) ) {
  1126 			mysql_free_result( $this->result );
  1393 			mysql_free_result( $this->result );
  1127 	}
  1394 		}
  1128 
  1395 	}
  1129 	/**
  1396 
  1130 	 * Connect to and select database
  1397 	/**
       
  1398 	 * Connect to and select database.
       
  1399 	 *
       
  1400 	 * If $allow_bail is false, the lack of database connection will need
       
  1401 	 * to be handled manually.
  1131 	 *
  1402 	 *
  1132 	 * @since 3.0.0
  1403 	 * @since 3.0.0
  1133 	 */
  1404 	 * @since 3.9.0 $allow_bail parameter added.
  1134 	function db_connect() {
  1405 	 *
       
  1406 	 * @param bool $allow_bail Optional. Allows the function to bail. Default true.
       
  1407 	 * @return null|bool True with a successful connection, false on failure.
       
  1408 	 */
       
  1409 	public function db_connect( $allow_bail = true ) {
  1135 
  1410 
  1136 		$this->is_mysql = true;
  1411 		$this->is_mysql = true;
  1137 
  1412 
       
  1413 		/*
       
  1414 		 * Deprecated in 3.9+ when using MySQLi. No equivalent
       
  1415 		 * $new_link parameter exists for mysqli_* functions.
       
  1416 		 */
  1138 		$new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
  1417 		$new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
  1139 		$client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
  1418 		$client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
  1140 
  1419 
  1141 		if ( WP_DEBUG ) {
  1420 		if ( $this->use_mysqli ) {
  1142 			$this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
  1421 			$this->dbh = mysqli_init();
       
  1422 
       
  1423 			// mysqli_real_connect doesn't support the host param including a port or socket
       
  1424 			// like mysql_connect does. This duplicates how mysql_connect detects a port and/or socket file.
       
  1425 			$port = null;
       
  1426 			$socket = null;
       
  1427 			$host = $this->dbhost;
       
  1428 			$port_or_socket = strstr( $host, ':' );
       
  1429 			if ( ! empty( $port_or_socket ) ) {
       
  1430 				$host = substr( $host, 0, strpos( $host, ':' ) );
       
  1431 				$port_or_socket = substr( $port_or_socket, 1 );
       
  1432 				if ( 0 !== strpos( $port_or_socket, '/' ) ) {
       
  1433 					$port = intval( $port_or_socket );
       
  1434 					$maybe_socket = strstr( $port_or_socket, ':' );
       
  1435 					if ( ! empty( $maybe_socket ) ) {
       
  1436 						$socket = substr( $maybe_socket, 1 );
       
  1437 					}
       
  1438 				} else {
       
  1439 					$socket = $port_or_socket;
       
  1440 				}
       
  1441 			}
       
  1442 
       
  1443 			if ( WP_DEBUG ) {
       
  1444 				mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
       
  1445 			} else {
       
  1446 				@mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
       
  1447 			}
       
  1448 
       
  1449 			if ( $this->dbh->connect_errno ) {
       
  1450 				$this->dbh = null;
       
  1451 
       
  1452 				/* It's possible ext/mysqli is misconfigured. Fall back to ext/mysql if:
       
  1453 		 		 *  - We haven't previously connected, and
       
  1454 		 		 *  - WP_USE_EXT_MYSQL isn't set to false, and
       
  1455 		 		 *  - ext/mysql is loaded.
       
  1456 		 		 */
       
  1457 				$attempt_fallback = true;
       
  1458 
       
  1459 				if ( $this->has_connected ) {
       
  1460 					$attempt_fallback = false;
       
  1461 				} elseif ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL ) {
       
  1462 					$attempt_fallback = false;
       
  1463 				} elseif ( ! function_exists( 'mysql_connect' ) ) {
       
  1464 					$attempt_fallback = false;
       
  1465 				}
       
  1466 
       
  1467 				if ( $attempt_fallback ) {
       
  1468 					$this->use_mysqli = false;
       
  1469 					$this->db_connect();
       
  1470 				}
       
  1471 			}
  1143 		} else {
  1472 		} else {
  1144 			$this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
  1473 			if ( WP_DEBUG ) {
  1145 		}
  1474 				$this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
  1146 
  1475 			} else {
  1147 		if ( !$this->dbh ) {
  1476 				$this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
       
  1477 			}
       
  1478 		}
       
  1479 
       
  1480 		if ( ! $this->dbh && $allow_bail ) {
  1148 			wp_load_translations_early();
  1481 			wp_load_translations_early();
       
  1482 
       
  1483 			// Load custom DB error template, if present.
       
  1484 			if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) {
       
  1485 				require_once( WP_CONTENT_DIR . '/db-error.php' );
       
  1486 				die();
       
  1487 			}
       
  1488 
  1149 			$this->bail( sprintf( __( "
  1489 			$this->bail( sprintf( __( "
  1150 <h1>Error establishing a database connection</h1>
  1490 <h1>Error establishing a database connection</h1>
  1151 <p>This either means that the username and password information in your <code>wp-config.php</code> file is incorrect or we can't contact the database server at <code>%s</code>. This could mean your host's database server is down.</p>
  1491 <p>This either means that the username and password information in your <code>wp-config.php</code> file is incorrect or we can't contact the database server at <code>%s</code>. This could mean your host's database server is down.</p>
  1152 <ul>
  1492 <ul>
  1153 	<li>Are you sure you have the correct username and password?</li>
  1493 	<li>Are you sure you have the correct username and password?</li>
  1154 	<li>Are you sure that you have typed the correct hostname?</li>
  1494 	<li>Are you sure that you have typed the correct hostname?</li>
  1155 	<li>Are you sure that the database server is running?</li>
  1495 	<li>Are you sure that the database server is running?</li>
  1156 </ul>
  1496 </ul>
  1157 <p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='http://wordpress.org/support/'>WordPress Support Forums</a>.</p>
  1497 <p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='https://wordpress.org/support/'>WordPress Support Forums</a>.</p>
  1158 " ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
  1498 " ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
  1159 
  1499 
  1160 			return;
  1500 			return false;
  1161 		}
  1501 		} elseif ( $this->dbh ) {
  1162 
  1502 			if ( ! $this->has_connected ) {
  1163 		$this->set_charset( $this->dbh );
  1503 				$this->init_charset();
  1164 
  1504 			}
  1165 		$this->ready = true;
  1505 
  1166 
  1506 			$this->has_connected = true;
  1167 		$this->select( $this->dbname, $this->dbh );
  1507 
       
  1508 			$this->set_charset( $this->dbh );
       
  1509 
       
  1510 			$this->ready = true;
       
  1511 			$this->set_sql_mode();
       
  1512 			$this->select( $this->dbname, $this->dbh );
       
  1513 
       
  1514 			return true;
       
  1515 		}
       
  1516 
       
  1517 		return false;
       
  1518 	}
       
  1519 
       
  1520 	/**
       
  1521 	 * Check that the connection to the database is still up. If not, try to reconnect.
       
  1522 	 *
       
  1523 	 * If this function is unable to reconnect, it will forcibly die, or if after the
       
  1524 	 * the template_redirect hook has been fired, return false instead.
       
  1525 	 *
       
  1526 	 * If $allow_bail is false, the lack of database connection will need
       
  1527 	 * to be handled manually.
       
  1528 	 *
       
  1529 	 * @since 3.9.0
       
  1530 	 *
       
  1531 	 * @param bool $allow_bail Optional. Allows the function to bail. Default true.
       
  1532 	 * @return bool|null True if the connection is up.
       
  1533 	 */
       
  1534 	public function check_connection( $allow_bail = true ) {
       
  1535 		if ( $this->use_mysqli ) {
       
  1536 			if ( @mysqli_ping( $this->dbh ) ) {
       
  1537 				return true;
       
  1538 			}
       
  1539 		} else {
       
  1540 			if ( @mysql_ping( $this->dbh ) ) {
       
  1541 				return true;
       
  1542 			}
       
  1543 		}
       
  1544 
       
  1545 		$error_reporting = false;
       
  1546 
       
  1547 		// Disable warnings, as we don't want to see a multitude of "unable to connect" messages
       
  1548 		if ( WP_DEBUG ) {
       
  1549 			$error_reporting = error_reporting();
       
  1550 			error_reporting( $error_reporting & ~E_WARNING );
       
  1551 		}
       
  1552 
       
  1553 		for ( $tries = 1; $tries <= $this->reconnect_retries; $tries++ ) {
       
  1554 			// On the last try, re-enable warnings. We want to see a single instance of the
       
  1555 			// "unable to connect" message on the bail() screen, if it appears.
       
  1556 			if ( $this->reconnect_retries === $tries && WP_DEBUG ) {
       
  1557 				error_reporting( $error_reporting );
       
  1558 			}
       
  1559 
       
  1560 			if ( $this->db_connect( false ) ) {
       
  1561 				if ( $error_reporting ) {
       
  1562 					error_reporting( $error_reporting );
       
  1563 				}
       
  1564 
       
  1565 				return true;
       
  1566 			}
       
  1567 
       
  1568 			sleep( 1 );
       
  1569 		}
       
  1570 
       
  1571 		// If template_redirect has already happened, it's too late for wp_die()/dead_db().
       
  1572 		// Let's just return and hope for the best.
       
  1573 		if ( did_action( 'template_redirect' ) ) {
       
  1574 			return false;
       
  1575 		}
       
  1576 
       
  1577 		if ( ! $allow_bail ) {
       
  1578 			return false;
       
  1579 		}
       
  1580 
       
  1581 		// We weren't able to reconnect, so we better bail.
       
  1582 		$this->bail( sprintf( ( "
       
  1583 <h1>Error reconnecting to the database</h1>
       
  1584 <p>This means that we lost contact with the database server at <code>%s</code>. This could mean your host's database server is down.</p>
       
  1585 <ul>
       
  1586 	<li>Are you sure that the database server is running?</li>
       
  1587 	<li>Are you sure that the database server is not under particularly heavy load?</li>
       
  1588 </ul>
       
  1589 <p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='https://wordpress.org/support/'>WordPress Support Forums</a>.</p>
       
  1590 " ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
       
  1591 
       
  1592 		// Call dead_db() if bail didn't die, because this database is no more. It has ceased to be (at least temporarily).
       
  1593 		dead_db();
  1168 	}
  1594 	}
  1169 
  1595 
  1170 	/**
  1596 	/**
  1171 	 * Perform a MySQL database query, using current database connection.
  1597 	 * Perform a MySQL database query, using current database connection.
  1172 	 *
  1598 	 *
  1175 	 * @since 0.71
  1601 	 * @since 0.71
  1176 	 *
  1602 	 *
  1177 	 * @param string $query Database query
  1603 	 * @param string $query Database query
  1178 	 * @return int|false Number of rows affected/selected or false on error
  1604 	 * @return int|false Number of rows affected/selected or false on error
  1179 	 */
  1605 	 */
  1180 	function query( $query ) {
  1606 	public function query( $query ) {
  1181 		if ( ! $this->ready )
  1607 		if ( ! $this->ready ) {
       
  1608 			$this->check_current_query = true;
  1182 			return false;
  1609 			return false;
       
  1610 		}
       
  1611 
  1183 		/**
  1612 		/**
  1184 		 * Filter the database query.
  1613 		 * Filter the database query.
  1185 		 *
  1614 		 *
  1186 		 * Some queries are made before the plugins have been loaded, and thus cannot be filtered with this method.
  1615 		 * Some queries are made before the plugins have been loaded,
       
  1616 		 * and thus cannot be filtered with this method.
  1187 		 *
  1617 		 *
  1188 		 * @since 2.1.0
  1618 		 * @since 2.1.0
       
  1619 		 *
  1189 		 * @param string $query Database query.
  1620 		 * @param string $query Database query.
  1190 		 */
  1621 		 */
  1191 		$query = apply_filters( 'query', $query );
  1622 		$query = apply_filters( 'query', $query );
  1192 
  1623 
  1193 		$return_val = 0;
       
  1194 		$this->flush();
  1624 		$this->flush();
  1195 
  1625 
  1196 		// Log how the function was called
  1626 		// Log how the function was called
  1197 		$this->func_call = "\$db->query(\"$query\")";
  1627 		$this->func_call = "\$db->query(\"$query\")";
  1198 
  1628 
       
  1629 		// If we're writing to the database, make sure the query will write safely.
       
  1630 		if ( $this->check_current_query && ! $this->check_ascii( $query ) ) {
       
  1631 			$stripped_query = $this->strip_invalid_text_from_query( $query );
       
  1632 			// strip_invalid_text_from_query() can perform queries, so we need
       
  1633 			// to flush again, just to make sure everything is clear.
       
  1634 			$this->flush();
       
  1635 			if ( $stripped_query !== $query ) {
       
  1636 				$this->insert_id = 0;
       
  1637 				return false;
       
  1638 			}
       
  1639 		}
       
  1640 
       
  1641 		$this->check_current_query = true;
       
  1642 
  1199 		// Keep track of the last query for debug..
  1643 		// Keep track of the last query for debug..
  1200 		$this->last_query = $query;
  1644 		$this->last_query = $query;
  1201 
  1645 
  1202 		if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
  1646 		$this->_do_query( $query );
  1203 			$this->timer_start();
  1647 
  1204 
  1648 		// MySQL server has gone away, try to reconnect
  1205 		$this->result = @mysql_query( $query, $this->dbh );
  1649 		$mysql_errno = 0;
  1206 		$this->num_queries++;
  1650 		if ( ! empty( $this->dbh ) ) {
  1207 
  1651 			if ( $this->use_mysqli ) {
  1208 		if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
  1652 				$mysql_errno = mysqli_errno( $this->dbh );
  1209 			$this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
  1653 			} else {
       
  1654 				$mysql_errno = mysql_errno( $this->dbh );
       
  1655 			}
       
  1656 		}
       
  1657 
       
  1658 		if ( empty( $this->dbh ) || 2006 == $mysql_errno ) {
       
  1659 			if ( $this->check_connection() ) {
       
  1660 				$this->_do_query( $query );
       
  1661 			} else {
       
  1662 				$this->insert_id = 0;
       
  1663 				return false;
       
  1664 			}
       
  1665 		}
  1210 
  1666 
  1211 		// If there is an error then take note of it..
  1667 		// If there is an error then take note of it..
  1212 		if ( $this->last_error = mysql_error( $this->dbh ) ) {
  1668 		if ( $this->use_mysqli ) {
       
  1669 			$this->last_error = mysqli_error( $this->dbh );
       
  1670 		} else {
       
  1671 			$this->last_error = mysql_error( $this->dbh );
       
  1672 		}
       
  1673 
       
  1674 		if ( $this->last_error ) {
  1213 			// Clear insert_id on a subsequent failed insert.
  1675 			// Clear insert_id on a subsequent failed insert.
  1214 			if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) )
  1676 			if ( $this->insert_id && preg_match( '/^\s*(insert|replace)\s/i', $query ) )
  1215 				$this->insert_id = 0;
  1677 				$this->insert_id = 0;
  1216 
  1678 
  1217 			$this->print_error();
  1679 			$this->print_error();
  1219 		}
  1681 		}
  1220 
  1682 
  1221 		if ( preg_match( '/^\s*(create|alter|truncate|drop)\s/i', $query ) ) {
  1683 		if ( preg_match( '/^\s*(create|alter|truncate|drop)\s/i', $query ) ) {
  1222 			$return_val = $this->result;
  1684 			$return_val = $this->result;
  1223 		} elseif ( preg_match( '/^\s*(insert|delete|update|replace)\s/i', $query ) ) {
  1685 		} elseif ( preg_match( '/^\s*(insert|delete|update|replace)\s/i', $query ) ) {
  1224 			$this->rows_affected = mysql_affected_rows( $this->dbh );
  1686 			if ( $this->use_mysqli ) {
       
  1687 				$this->rows_affected = mysqli_affected_rows( $this->dbh );
       
  1688 			} else {
       
  1689 				$this->rows_affected = mysql_affected_rows( $this->dbh );
       
  1690 			}
  1225 			// Take note of the insert_id
  1691 			// Take note of the insert_id
  1226 			if ( preg_match( '/^\s*(insert|replace)\s/i', $query ) ) {
  1692 			if ( preg_match( '/^\s*(insert|replace)\s/i', $query ) ) {
  1227 				$this->insert_id = mysql_insert_id($this->dbh);
  1693 				if ( $this->use_mysqli ) {
       
  1694 					$this->insert_id = mysqli_insert_id( $this->dbh );
       
  1695 				} else {
       
  1696 					$this->insert_id = mysql_insert_id( $this->dbh );
       
  1697 				}
  1228 			}
  1698 			}
  1229 			// Return number of rows affected
  1699 			// Return number of rows affected
  1230 			$return_val = $this->rows_affected;
  1700 			$return_val = $this->rows_affected;
  1231 		} else {
  1701 		} else {
  1232 			$num_rows = 0;
  1702 			$num_rows = 0;
  1233 			while ( $row = @mysql_fetch_object( $this->result ) ) {
  1703 			if ( $this->use_mysqli && $this->result instanceof mysqli_result ) {
  1234 				$this->last_result[$num_rows] = $row;
  1704 				while ( $row = @mysqli_fetch_object( $this->result ) ) {
  1235 				$num_rows++;
  1705 					$this->last_result[$num_rows] = $row;
       
  1706 					$num_rows++;
       
  1707 				}
       
  1708 			} elseif ( is_resource( $this->result ) ) {
       
  1709 				while ( $row = @mysql_fetch_object( $this->result ) ) {
       
  1710 					$this->last_result[$num_rows] = $row;
       
  1711 					$num_rows++;
       
  1712 				}
  1236 			}
  1713 			}
  1237 
  1714 
  1238 			// Log number of rows the query returned
  1715 			// Log number of rows the query returned
  1239 			// and return number of rows selected
  1716 			// and return number of rows selected
  1240 			$this->num_rows = $num_rows;
  1717 			$this->num_rows = $num_rows;
  1243 
  1720 
  1244 		return $return_val;
  1721 		return $return_val;
  1245 	}
  1722 	}
  1246 
  1723 
  1247 	/**
  1724 	/**
       
  1725 	 * Internal function to perform the mysql_query() call.
       
  1726 	 *
       
  1727 	 * @since 3.9.0
       
  1728 	 *
       
  1729 	 * @access private
       
  1730 	 * @see wpdb::query()
       
  1731 	 *
       
  1732 	 * @param string $query The query to run.
       
  1733 	 */
       
  1734 	private function _do_query( $query ) {
       
  1735 		if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
       
  1736 			$this->timer_start();
       
  1737 		}
       
  1738 
       
  1739 		if ( $this->use_mysqli ) {
       
  1740 			$this->result = @mysqli_query( $this->dbh, $query );
       
  1741 		} else {
       
  1742 			$this->result = @mysql_query( $query, $this->dbh );
       
  1743 		}
       
  1744 		$this->num_queries++;
       
  1745 
       
  1746 		if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
       
  1747 			$this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
       
  1748 		}
       
  1749 	}
       
  1750 
       
  1751 	/**
  1248 	 * Insert a row into a table.
  1752 	 * Insert a row into a table.
  1249 	 *
  1753 	 *
  1250 	 * <code>
  1754 	 *     wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
  1251 	 * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
  1755 	 *     wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
  1252 	 * wpdb::insert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
       
  1253 	 * </code>
       
  1254 	 *
  1756 	 *
  1255 	 * @since 2.5.0
  1757 	 * @since 2.5.0
  1256 	 * @see wpdb::prepare()
  1758 	 * @see wpdb::prepare()
  1257 	 * @see wpdb::$field_types
  1759 	 * @see wpdb::$field_types
  1258 	 * @see wp_set_wpdb_vars()
  1760 	 * @see wp_set_wpdb_vars()
  1261 	 * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1763 	 * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1262 	 * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data.
  1764 	 * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data.
  1263 	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1765 	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1264 	 * @return int|false The number of rows inserted, or false on error.
  1766 	 * @return int|false The number of rows inserted, or false on error.
  1265 	 */
  1767 	 */
  1266 	function insert( $table, $data, $format = null ) {
  1768 	public function insert( $table, $data, $format = null ) {
  1267 		return $this->_insert_replace_helper( $table, $data, $format, 'INSERT' );
  1769 		return $this->_insert_replace_helper( $table, $data, $format, 'INSERT' );
  1268 	}
  1770 	}
  1269 
  1771 
  1270 	/**
  1772 	/**
  1271 	 * Replace a row into a table.
  1773 	 * Replace a row into a table.
  1272 	 *
  1774 	 *
  1273 	 * <code>
  1775 	 *     wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
  1274 	 * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
  1776 	 *     wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
  1275 	 * wpdb::replace( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ) )
       
  1276 	 * </code>
       
  1277 	 *
  1777 	 *
  1278 	 * @since 3.0.0
  1778 	 * @since 3.0.0
  1279 	 * @see wpdb::prepare()
  1779 	 * @see wpdb::prepare()
  1280 	 * @see wpdb::$field_types
  1780 	 * @see wpdb::$field_types
  1281 	 * @see wp_set_wpdb_vars()
  1781 	 * @see wp_set_wpdb_vars()
  1284 	 * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1784 	 * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped).
  1285 	 * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data.
  1785 	 * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data. If string, that format will be used for all of the values in $data.
  1286 	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1786 	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1287 	 * @return int|false The number of rows affected, or false on error.
  1787 	 * @return int|false The number of rows affected, or false on error.
  1288 	 */
  1788 	 */
  1289 	function replace( $table, $data, $format = null ) {
  1789 	public function replace( $table, $data, $format = null ) {
  1290 		return $this->_insert_replace_helper( $table, $data, $format, 'REPLACE' );
  1790 		return $this->_insert_replace_helper( $table, $data, $format, 'REPLACE' );
  1291 	}
  1791 	}
  1292 
  1792 
  1293 	/**
  1793 	/**
  1294 	 * Helper function for insert and replace.
  1794 	 * Helper function for insert and replace.
  1307 	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1807 	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1308 	 * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT.
  1808 	 * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT.
  1309 	 * @return int|false The number of rows affected, or false on error.
  1809 	 * @return int|false The number of rows affected, or false on error.
  1310 	 */
  1810 	 */
  1311 	function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) {
  1811 	function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) {
  1312 		if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) )
  1812 		$this->insert_id = 0;
       
  1813 
       
  1814 		if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) {
  1313 			return false;
  1815 			return false;
  1314 		$this->insert_id = 0;
  1816 		}
  1315 		$formats = $format = (array) $format;
  1817 
  1316 		$fields = array_keys( $data );
  1818 		$data = $this->process_fields( $table, $data, $format );
  1317 		$formatted_fields = array();
  1819 		if ( false === $data ) {
  1318 		foreach ( $fields as $field ) {
  1820 			return false;
  1319 			if ( !empty( $format ) )
  1821 		}
  1320 				$form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
  1822 
  1321 			elseif ( isset( $this->field_types[$field] ) )
  1823 		$formats = $values = array();
  1322 				$form = $this->field_types[$field];
  1824 		foreach ( $data as $value ) {
  1323 			else
  1825 			$formats[] = $value['format'];
  1324 				$form = '%s';
  1826 			$values[]  = $value['value'];
  1325 			$formatted_fields[] = $form;
  1827 		}
  1326 		}
  1828 
  1327 		$sql = "{$type} INTO `$table` (`" . implode( '`,`', $fields ) . "`) VALUES (" . implode( ",", $formatted_fields ) . ")";
  1829 		$fields  = '`' . implode( '`, `', array_keys( $data ) ) . '`';
  1328 		return $this->query( $this->prepare( $sql, $data ) );
  1830 		$formats = implode( ', ', $formats );
       
  1831 
       
  1832 		$sql = "$type INTO `$table` ($fields) VALUES ($formats)";
       
  1833 
       
  1834 		$this->check_current_query = false;
       
  1835 		return $this->query( $this->prepare( $sql, $values ) );
  1329 	}
  1836 	}
  1330 
  1837 
  1331 	/**
  1838 	/**
  1332 	 * Update a row in the table
  1839 	 * Update a row in the table
  1333 	 *
  1840 	 *
  1334 	 * <code>
  1841 	 *     wpdb::update( 'table', array( 'column' => 'foo', 'field' => 'bar' ), array( 'ID' => 1 ) )
  1335 	 * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 'bar' ), array( 'ID' => 1 ) )
  1842 	 *     wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) )
  1336 	 * wpdb::update( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( 'ID' => 1 ), array( '%s', '%d' ), array( '%d' ) )
       
  1337 	 * </code>
       
  1338 	 *
  1843 	 *
  1339 	 * @since 2.5.0
  1844 	 * @since 2.5.0
  1340 	 * @see wpdb::prepare()
  1845 	 * @see wpdb::prepare()
  1341 	 * @see wpdb::$field_types
  1846 	 * @see wpdb::$field_types
  1342 	 * @see wp_set_wpdb_vars()
  1847 	 * @see wp_set_wpdb_vars()
  1347 	 * @param array|string $format Optional. An array of formats to be mapped to each of the values in $data. If string, that format will be used for all of the values in $data.
  1852 	 * @param array|string $format Optional. An array of formats to be mapped to each of the values in $data. If string, that format will be used for all of the values in $data.
  1348 	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1853 	 * 	A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
  1349 	 * @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $where will be treated as strings.
  1854 	 * @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $where will be treated as strings.
  1350 	 * @return int|false The number of rows updated, or false on error.
  1855 	 * @return int|false The number of rows updated, or false on error.
  1351 	 */
  1856 	 */
  1352 	function update( $table, $data, $where, $format = null, $where_format = null ) {
  1857 	public function update( $table, $data, $where, $format = null, $where_format = null ) {
  1353 		if ( ! is_array( $data ) || ! is_array( $where ) )
  1858 		if ( ! is_array( $data ) || ! is_array( $where ) ) {
  1354 			return false;
  1859 			return false;
  1355 
  1860 		}
  1356 		$formats = $format = (array) $format;
  1861 
  1357 		$bits = $wheres = array();
  1862 		$data = $this->process_fields( $table, $data, $format );
  1358 		foreach ( (array) array_keys( $data ) as $field ) {
  1863 		if ( false === $data ) {
  1359 			if ( !empty( $format ) )
  1864 			return false;
  1360 				$form = ( $form = array_shift( $formats ) ) ? $form : $format[0];
  1865 		}
  1361 			elseif ( isset($this->field_types[$field]) )
  1866 		$where = $this->process_fields( $table, $where, $where_format );
  1362 				$form = $this->field_types[$field];
  1867 		if ( false === $where ) {
  1363 			else
  1868 			return false;
  1364 				$form = '%s';
  1869 		}
  1365 			$bits[] = "`$field` = {$form}";
  1870 
  1366 		}
  1871 		$fields = $conditions = $values = array();
  1367 
  1872 		foreach ( $data as $field => $value ) {
  1368 		$where_formats = $where_format = (array) $where_format;
  1873 			$fields[] = "`$field` = " . $value['format'];
  1369 		foreach ( (array) array_keys( $where ) as $field ) {
  1874 			$values[] = $value['value'];
  1370 			if ( !empty( $where_format ) )
  1875 		}
  1371 				$form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
  1876 		foreach ( $where as $field => $value ) {
  1372 			elseif ( isset( $this->field_types[$field] ) )
  1877 			$conditions[] = "`$field` = " . $value['format'];
  1373 				$form = $this->field_types[$field];
  1878 			$values[] = $value['value'];
  1374 			else
  1879 		}
  1375 				$form = '%s';
  1880 
  1376 			$wheres[] = "`$field` = {$form}";
  1881 		$fields = implode( ', ', $fields );
  1377 		}
  1882 		$conditions = implode( ' AND ', $conditions );
  1378 
  1883 
  1379 		$sql = "UPDATE `$table` SET " . implode( ', ', $bits ) . ' WHERE ' . implode( ' AND ', $wheres );
  1884 		$sql = "UPDATE `$table` SET $fields WHERE $conditions";
  1380 		return $this->query( $this->prepare( $sql, array_merge( array_values( $data ), array_values( $where ) ) ) );
  1885 
       
  1886 		$this->check_current_query = false;
       
  1887 		return $this->query( $this->prepare( $sql, $values ) );
  1381 	}
  1888 	}
  1382 
  1889 
  1383 	/**
  1890 	/**
  1384 	 * Delete a row in the table
  1891 	 * Delete a row in the table
  1385 	 *
  1892 	 *
  1386 	 * <code>
  1893 	 *     wpdb::delete( 'table', array( 'ID' => 1 ) )
  1387 	 * wpdb::delete( 'table', array( 'ID' => 1 ) )
  1894 	 *     wpdb::delete( 'table', array( 'ID' => 1 ), array( '%d' ) )
  1388 	 * wpdb::delete( 'table', array( 'ID' => 1 ), array( '%d' ) )
       
  1389 	 * </code>
       
  1390 	 *
  1895 	 *
  1391 	 * @since 3.4.0
  1896 	 * @since 3.4.0
  1392 	 * @see wpdb::prepare()
  1897 	 * @see wpdb::prepare()
  1393 	 * @see wpdb::$field_types
  1898 	 * @see wpdb::$field_types
  1394 	 * @see wp_set_wpdb_vars()
  1899 	 * @see wp_set_wpdb_vars()
  1396 	 * @param string $table table name
  1901 	 * @param string $table table name
  1397 	 * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
  1902 	 * @param array $where A named array of WHERE clauses (in column => value pairs). Multiple clauses will be joined with ANDs. Both $where columns and $where values should be "raw".
  1398 	 * @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $where will be treated as strings unless otherwise specified in wpdb::$field_types.
  1903 	 * @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where. If string, that format will be used for all of the items in $where. A format is one of '%d', '%f', '%s' (integer, float, string). If omitted, all values in $where will be treated as strings unless otherwise specified in wpdb::$field_types.
  1399 	 * @return int|false The number of rows updated, or false on error.
  1904 	 * @return int|false The number of rows updated, or false on error.
  1400 	 */
  1905 	 */
  1401 	function delete( $table, $where, $where_format = null ) {
  1906 	public function delete( $table, $where, $where_format = null ) {
  1402 		if ( ! is_array( $where ) )
  1907 		if ( ! is_array( $where ) ) {
  1403 			return false;
  1908 			return false;
  1404 
  1909 		}
  1405 		$bits = $wheres = array();
  1910 
  1406 
  1911 		$where = $this->process_fields( $table, $where, $where_format );
  1407 		$where_formats = $where_format = (array) $where_format;
  1912 		if ( false === $where ) {
  1408 
  1913 			return false;
  1409 		foreach ( array_keys( $where ) as $field ) {
  1914 		}
  1410 			if ( !empty( $where_format ) ) {
  1915 
  1411 				$form = ( $form = array_shift( $where_formats ) ) ? $form : $where_format[0];
  1916 		$conditions = $values = array();
       
  1917 		foreach ( $where as $field => $value ) {
       
  1918 			$conditions[] = "`$field` = " . $value['format'];
       
  1919 			$values[] = $value['value'];
       
  1920 		}
       
  1921 
       
  1922 		$conditions = implode( ' AND ', $conditions );
       
  1923 
       
  1924 		$sql = "DELETE FROM `$table` WHERE $conditions";
       
  1925 
       
  1926 		$this->check_current_query = false;
       
  1927 		return $this->query( $this->prepare( $sql, $values ) );
       
  1928 	}
       
  1929 
       
  1930 	/**
       
  1931 	 * Processes arrays of field/value pairs and field formats.
       
  1932 	 *
       
  1933 	 * This is a helper method for wpdb's CRUD methods, which take field/value
       
  1934 	 * pairs for inserts, updates, and where clauses. This method first pairs
       
  1935 	 * each value with a format. Then it determines the charset of that field,
       
  1936 	 * using that to determine if any invalid text would be stripped. If text is
       
  1937 	 * stripped, then field processing is rejected and the query fails.
       
  1938 	 *
       
  1939 	 * @since 4.2.0
       
  1940 	 * @access protected
       
  1941 	 *
       
  1942 	 * @param string $table  Table name.
       
  1943 	 * @param array  $data   Field/value pair.
       
  1944 	 * @param mixed  $format Format for each field.
       
  1945 	 * @return array|bool Returns an array of fields that contain paired values
       
  1946 	 *                    and formats. Returns false for invalid values.
       
  1947 	 */
       
  1948 	protected function process_fields( $table, $data, $format ) {
       
  1949 		$data = $this->process_field_formats( $data, $format );
       
  1950 		if ( false === $data ) {
       
  1951 			return false;
       
  1952 		}
       
  1953 
       
  1954 		$data = $this->process_field_charsets( $data, $table );
       
  1955 		if ( false === $data ) {
       
  1956 			return false;
       
  1957 		}
       
  1958 
       
  1959 		$data = $this->process_field_lengths( $data, $table );
       
  1960 		if ( false === $data ) {
       
  1961 			return false;
       
  1962 		}
       
  1963 
       
  1964 		$converted_data = $this->strip_invalid_text( $data );
       
  1965 
       
  1966 		if ( $data !== $converted_data ) {
       
  1967 			return false;
       
  1968 		}
       
  1969 
       
  1970 		return $data;
       
  1971 	}
       
  1972 
       
  1973 	/**
       
  1974 	 * Prepares arrays of value/format pairs as passed to wpdb CRUD methods.
       
  1975 	 *
       
  1976 	 * @since 4.2.0
       
  1977 	 * @access protected
       
  1978 	 *
       
  1979 	 * @param array $data   Array of fields to values.
       
  1980 	 * @param mixed $format Formats to be mapped to the values in $data.
       
  1981 	 * @return array Array, keyed by field names with values being an array
       
  1982 	 *               of 'value' and 'format' keys.
       
  1983 	 */
       
  1984 	protected function process_field_formats( $data, $format ) {
       
  1985 		$formats = $original_formats = (array) $format;
       
  1986 
       
  1987 		foreach ( $data as $field => $value ) {
       
  1988 			$value = array(
       
  1989 				'value'  => $value,
       
  1990 				'format' => '%s',
       
  1991 			);
       
  1992 
       
  1993 			if ( ! empty( $format ) ) {
       
  1994 				$value['format'] = array_shift( $formats );
       
  1995 				if ( ! $value['format'] ) {
       
  1996 					$value['format'] = reset( $original_formats );
       
  1997 				}
  1412 			} elseif ( isset( $this->field_types[ $field ] ) ) {
  1998 			} elseif ( isset( $this->field_types[ $field ] ) ) {
  1413 				$form = $this->field_types[ $field ];
  1999 				$value['format'] = $this->field_types[ $field ];
       
  2000 			}
       
  2001 
       
  2002 			$data[ $field ] = $value;
       
  2003 		}
       
  2004 
       
  2005 		return $data;
       
  2006 	}
       
  2007 
       
  2008 	/**
       
  2009 	 * Adds field charsets to field/value/format arrays generated by
       
  2010 	 * the wpdb::process_field_formats() method.
       
  2011 	 *
       
  2012 	 * @since 4.2.0
       
  2013 	 * @access protected
       
  2014 	 *
       
  2015 	 * @param array  $data  As it comes from the wpdb::process_field_formats() method.
       
  2016 	 * @param string $table Table name.
       
  2017 	 * @return The same array as $data with additional 'charset' keys.
       
  2018 	 */
       
  2019 	protected function process_field_charsets( $data, $table ) {
       
  2020 		foreach ( $data as $field => $value ) {
       
  2021 			if ( '%d' === $value['format'] || '%f' === $value['format'] ) {
       
  2022 				// We can skip this field if we know it isn't a string.
       
  2023 				// This checks %d/%f versus ! %s because it's sprintf() could take more.
       
  2024 				$value['charset'] = false;
  1414 			} else {
  2025 			} else {
  1415 				$form = '%s';
  2026 				$value['charset'] = $this->get_col_charset( $table, $field );
  1416 			}
  2027 				if ( is_wp_error( $value['charset'] ) ) {
  1417 
  2028 					return false;
  1418 			$wheres[] = "$field = $form";
  2029 				}
  1419 		}
  2030 			}
  1420 
  2031 
  1421 		$sql = "DELETE FROM $table WHERE " . implode( ' AND ', $wheres );
  2032 			$data[ $field ] = $value;
  1422 		return $this->query( $this->prepare( $sql, $where ) );
  2033 		}
  1423 	}
  2034 
  1424 
  2035 		return $data;
       
  2036 	}
       
  2037 
       
  2038 	/**
       
  2039 	 * For string fields, record the maximum string length that field can safely save.
       
  2040 	 *
       
  2041 	 * @since 4.2.1
       
  2042 	 * @access protected
       
  2043 	 *
       
  2044 	 * @param array  $data  As it comes from the wpdb::process_field_charsets() method.
       
  2045 	 * @param string $table Table name.
       
  2046 	 * @return array|False The same array as $data with additional 'length' keys, or false if
       
  2047 	 *                     any of the values were too long for their corresponding field.
       
  2048 	 */
       
  2049 	protected function process_field_lengths( $data, $table ) {
       
  2050 		foreach ( $data as $field => $value ) {
       
  2051 			if ( '%d' === $value['format'] || '%f' === $value['format'] ) {
       
  2052 				// We can skip this field if we know it isn't a string.
       
  2053 				// This checks %d/%f versus ! %s because it's sprintf() could take more.
       
  2054 				$value['length'] = false;
       
  2055 			} else {
       
  2056 				$value['length'] = $this->get_col_length( $table, $field );
       
  2057 				if ( is_wp_error( $value['length'] ) ) {
       
  2058 					return false;
       
  2059 				}
       
  2060 			}
       
  2061 
       
  2062 			$data[ $field ] = $value;
       
  2063 		}
       
  2064 
       
  2065 		return $data;
       
  2066 	}
  1425 
  2067 
  1426 	/**
  2068 	/**
  1427 	 * Retrieve one variable from the database.
  2069 	 * Retrieve one variable from the database.
  1428 	 *
  2070 	 *
  1429 	 * Executes a SQL query and returns the value from the SQL result.
  2071 	 * Executes a SQL query and returns the value from the SQL result.
  1435 	 * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query.
  2077 	 * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query.
  1436 	 * @param int $x Optional. Column of value to return. Indexed from 0.
  2078 	 * @param int $x Optional. Column of value to return. Indexed from 0.
  1437 	 * @param int $y Optional. Row of value to return. Indexed from 0.
  2079 	 * @param int $y Optional. Row of value to return. Indexed from 0.
  1438 	 * @return string|null Database query result (as string), or null on failure
  2080 	 * @return string|null Database query result (as string), or null on failure
  1439 	 */
  2081 	 */
  1440 	function get_var( $query = null, $x = 0, $y = 0 ) {
  2082 	public function get_var( $query = null, $x = 0, $y = 0 ) {
  1441 		$this->func_call = "\$db->get_var(\"$query\", $x, $y)";
  2083 		$this->func_call = "\$db->get_var(\"$query\", $x, $y)";
  1442 		if ( $query )
  2084 
       
  2085 		if ( $this->check_safe_collation( $query ) ) {
       
  2086 			$this->check_current_query = false;
       
  2087 		}
       
  2088 
       
  2089 		if ( $query ) {
  1443 			$this->query( $query );
  2090 			$this->query( $query );
       
  2091 		}
  1444 
  2092 
  1445 		// Extract var out of cached results based x,y vals
  2093 		// Extract var out of cached results based x,y vals
  1446 		if ( !empty( $this->last_result[$y] ) ) {
  2094 		if ( !empty( $this->last_result[$y] ) ) {
  1447 			$values = array_values( get_object_vars( $this->last_result[$y] ) );
  2095 			$values = array_values( get_object_vars( $this->last_result[$y] ) );
  1448 		}
  2096 		}
  1462 	 * @param string $output Optional. one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...),
  2110 	 * @param string $output Optional. one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...),
  1463 	 * 	a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively.
  2111 	 * 	a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively.
  1464 	 * @param int $y Optional. Row to return. Indexed from 0.
  2112 	 * @param int $y Optional. Row to return. Indexed from 0.
  1465 	 * @return mixed Database query result in format specified by $output or null on failure
  2113 	 * @return mixed Database query result in format specified by $output or null on failure
  1466 	 */
  2114 	 */
  1467 	function get_row( $query = null, $output = OBJECT, $y = 0 ) {
  2115 	public function get_row( $query = null, $output = OBJECT, $y = 0 ) {
  1468 		$this->func_call = "\$db->get_row(\"$query\",$output,$y)";
  2116 		$this->func_call = "\$db->get_row(\"$query\",$output,$y)";
  1469 		if ( $query )
  2117 
       
  2118 		if ( $this->check_safe_collation( $query ) ) {
       
  2119 			$this->check_current_query = false;
       
  2120 		}
       
  2121 
       
  2122 		if ( $query ) {
  1470 			$this->query( $query );
  2123 			$this->query( $query );
  1471 		else
  2124 		} else {
  1472 			return null;
  2125 			return null;
       
  2126 		}
  1473 
  2127 
  1474 		if ( !isset( $this->last_result[$y] ) )
  2128 		if ( !isset( $this->last_result[$y] ) )
  1475 			return null;
  2129 			return null;
  1476 
  2130 
  1477 		if ( $output == OBJECT ) {
  2131 		if ( $output == OBJECT ) {
  1478 			return $this->last_result[$y] ? $this->last_result[$y] : null;
  2132 			return $this->last_result[$y] ? $this->last_result[$y] : null;
  1479 		} elseif ( $output == ARRAY_A ) {
  2133 		} elseif ( $output == ARRAY_A ) {
  1480 			return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null;
  2134 			return $this->last_result[$y] ? get_object_vars( $this->last_result[$y] ) : null;
  1481 		} elseif ( $output == ARRAY_N ) {
  2135 		} elseif ( $output == ARRAY_N ) {
  1482 			return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null;
  2136 			return $this->last_result[$y] ? array_values( get_object_vars( $this->last_result[$y] ) ) : null;
       
  2137 		} elseif ( strtoupper( $output ) === OBJECT ) {
       
  2138 			// Back compat for OBJECT being previously case insensitive.
       
  2139 			return $this->last_result[$y] ? $this->last_result[$y] : null;
  1483 		} else {
  2140 		} else {
  1484 			$this->print_error( " \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" );
  2141 			$this->print_error( " \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N" );
  1485 		}
  2142 		}
  1486 	}
  2143 	}
  1487 
  2144 
  1496 	 *
  2153 	 *
  1497 	 * @param string|null $query Optional. SQL query. Defaults to previous query.
  2154 	 * @param string|null $query Optional. SQL query. Defaults to previous query.
  1498 	 * @param int $x Optional. Column to return. Indexed from 0.
  2155 	 * @param int $x Optional. Column to return. Indexed from 0.
  1499 	 * @return array Database query result. Array indexed from 0 by SQL result row number.
  2156 	 * @return array Database query result. Array indexed from 0 by SQL result row number.
  1500 	 */
  2157 	 */
  1501 	function get_col( $query = null , $x = 0 ) {
  2158 	public function get_col( $query = null , $x = 0 ) {
  1502 		if ( $query )
  2159 		if ( $this->check_safe_collation( $query ) ) {
       
  2160 			$this->check_current_query = false;
       
  2161 		}
       
  2162 
       
  2163 		if ( $query ) {
  1503 			$this->query( $query );
  2164 			$this->query( $query );
       
  2165 		}
  1504 
  2166 
  1505 		$new_array = array();
  2167 		$new_array = array();
  1506 		// Extract the column values
  2168 		// Extract the column values
  1507 		for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
  2169 		for ( $i = 0, $j = count( $this->last_result ); $i < $j; $i++ ) {
  1508 			$new_array[$i] = $this->get_var( null, $x, $i );
  2170 			$new_array[$i] = $this->get_var( null, $x, $i );
  1521 	 * @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants. With one of the first three, return an array of rows indexed from 0 by SQL result row number.
  2183 	 * @param string $output Optional. Any of ARRAY_A | ARRAY_N | OBJECT | OBJECT_K constants. With one of the first three, return an array of rows indexed from 0 by SQL result row number.
  1522 	 * 	Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively.
  2184 	 * 	Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively.
  1523 	 * 	With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value. Duplicate keys are discarded.
  2185 	 * 	With OBJECT_K, return an associative array of row objects keyed by the value of each row's first column's value. Duplicate keys are discarded.
  1524 	 * @return mixed Database query results
  2186 	 * @return mixed Database query results
  1525 	 */
  2187 	 */
  1526 	function get_results( $query = null, $output = OBJECT ) {
  2188 	public function get_results( $query = null, $output = OBJECT ) {
  1527 		$this->func_call = "\$db->get_results(\"$query\", $output)";
  2189 		$this->func_call = "\$db->get_results(\"$query\", $output)";
  1528 
  2190 
  1529 		if ( $query )
  2191 		if ( $this->check_safe_collation( $query ) ) {
       
  2192 			$this->check_current_query = false;
       
  2193 		}
       
  2194 
       
  2195 		if ( $query ) {
  1530 			$this->query( $query );
  2196 			$this->query( $query );
  1531 		else
  2197 		} else {
  1532 			return null;
  2198 			return null;
       
  2199 		}
  1533 
  2200 
  1534 		$new_array = array();
  2201 		$new_array = array();
  1535 		if ( $output == OBJECT ) {
  2202 		if ( $output == OBJECT ) {
  1536 			// Return an integer-keyed array of row objects
  2203 			// Return an integer-keyed array of row objects
  1537 			return $this->last_result;
  2204 			return $this->last_result;
  1557 						$new_array[] = get_object_vars( $row );
  2224 						$new_array[] = get_object_vars( $row );
  1558 					}
  2225 					}
  1559 				}
  2226 				}
  1560 			}
  2227 			}
  1561 			return $new_array;
  2228 			return $new_array;
       
  2229 		} elseif ( strtoupper( $output ) === OBJECT ) {
       
  2230 			// Back compat for OBJECT being previously case insensitive.
       
  2231 			return $this->last_result;
  1562 		}
  2232 		}
  1563 		return null;
  2233 		return null;
       
  2234 	}
       
  2235 
       
  2236 	/**
       
  2237 	 * Retrieves the character set for the given table.
       
  2238 	 *
       
  2239 	 * @since 4.2.0
       
  2240 	 * @access protected
       
  2241 	 *
       
  2242 	 * @param string $table Table name.
       
  2243 	 * @return string|WP_Error Table character set, WP_Error object if it couldn't be found.
       
  2244 	 */
       
  2245 	protected function get_table_charset( $table ) {
       
  2246 		$tablekey = strtolower( $table );
       
  2247 
       
  2248 		/**
       
  2249 		 * Filter the table charset value before the DB is checked.
       
  2250 		 *
       
  2251 		 * Passing a non-null value to the filter will effectively short-circuit
       
  2252 		 * checking the DB for the charset, returning that value instead.
       
  2253 		 *
       
  2254 		 * @since 4.2.0
       
  2255 		 *
       
  2256 		 * @param string $charset The character set to use. Default null.
       
  2257 		 * @param string $table   The name of the table being checked.
       
  2258 		 */
       
  2259 		$charset = apply_filters( 'pre_get_table_charset', null, $table );
       
  2260 		if ( null !== $charset ) {
       
  2261 			return $charset;
       
  2262 		}
       
  2263 
       
  2264 		if ( isset( $this->table_charset[ $tablekey ] ) ) {
       
  2265 			return $this->table_charset[ $tablekey ];
       
  2266 		}
       
  2267 
       
  2268 		$charsets = $columns = array();
       
  2269 
       
  2270 		$table_parts = explode( '.', $table );
       
  2271 		$table = '`' . implode( '`.`', $table_parts ) . '`';
       
  2272 		$results = $this->get_results( "SHOW FULL COLUMNS FROM $table" );
       
  2273 		if ( ! $results ) {
       
  2274 			return new WP_Error( 'wpdb_get_table_charset_failure' );
       
  2275 		}
       
  2276 
       
  2277 		foreach ( $results as $column ) {
       
  2278 			$columns[ strtolower( $column->Field ) ] = $column;
       
  2279 		}
       
  2280 
       
  2281 		$this->col_meta[ $tablekey ] = $columns;
       
  2282 
       
  2283 		foreach ( $columns as $column ) {
       
  2284 			if ( ! empty( $column->Collation ) ) {
       
  2285 				list( $charset ) = explode( '_', $column->Collation );
       
  2286 
       
  2287 				// If the current connection can't support utf8mb4 characters, let's only send 3-byte utf8 characters.
       
  2288 				if ( 'utf8mb4' === $charset && ! $this->has_cap( 'utf8mb4' ) ) {
       
  2289 					$charset = 'utf8';
       
  2290 				}
       
  2291 
       
  2292 				$charsets[ strtolower( $charset ) ] = true;
       
  2293 			}
       
  2294 
       
  2295 			list( $type ) = explode( '(', $column->Type );
       
  2296 
       
  2297 			// A binary/blob means the whole query gets treated like this.
       
  2298 			if ( in_array( strtoupper( $type ), array( 'BINARY', 'VARBINARY', 'TINYBLOB', 'MEDIUMBLOB', 'BLOB', 'LONGBLOB' ) ) ) {
       
  2299 				$this->table_charset[ $tablekey ] = 'binary';
       
  2300 				return 'binary';
       
  2301 			}
       
  2302 		}
       
  2303 
       
  2304 		// utf8mb3 is an alias for utf8.
       
  2305 		if ( isset( $charsets['utf8mb3'] ) ) {
       
  2306 			$charsets['utf8'] = true;
       
  2307 			unset( $charsets['utf8mb3'] );
       
  2308 		}
       
  2309 
       
  2310 		// Check if we have more than one charset in play.
       
  2311 		$count = count( $charsets );
       
  2312 		if ( 1 === $count ) {
       
  2313 			$charset = key( $charsets );
       
  2314 		} elseif ( 0 === $count ) {
       
  2315 			// No charsets, assume this table can store whatever.
       
  2316 			$charset = false;
       
  2317 		} else {
       
  2318 			// More than one charset. Remove latin1 if present and recalculate.
       
  2319 			unset( $charsets['latin1'] );
       
  2320 			$count = count( $charsets );
       
  2321 			if ( 1 === $count ) {
       
  2322 				// Only one charset (besides latin1).
       
  2323 				$charset = key( $charsets );
       
  2324 			} elseif ( 2 === $count && isset( $charsets['utf8'], $charsets['utf8mb4'] ) ) {
       
  2325 				// Two charsets, but they're utf8 and utf8mb4, use utf8.
       
  2326 				$charset = 'utf8';
       
  2327 			} else {
       
  2328 				// Two mixed character sets. ascii.
       
  2329 				$charset = 'ascii';
       
  2330 			}
       
  2331 		}
       
  2332 
       
  2333 		$this->table_charset[ $tablekey ] = $charset;
       
  2334 		return $charset;
       
  2335 	}
       
  2336 
       
  2337 	/**
       
  2338 	 * Retrieves the character set for the given column.
       
  2339 	 *
       
  2340 	 * @since 4.2.0
       
  2341 	 * @access public
       
  2342 	 *
       
  2343 	 * @param string $table  Table name.
       
  2344 	 * @param string $column Column name.
       
  2345 	 * @return mixed Column character set as a string. False if the column has no
       
  2346 	 *               character set. WP_Error object if there was an error.
       
  2347 	 */
       
  2348 	public function get_col_charset( $table, $column ) {
       
  2349 		$tablekey = strtolower( $table );
       
  2350 		$columnkey = strtolower( $column );
       
  2351 
       
  2352 		/**
       
  2353 		 * Filter the column charset value before the DB is checked.
       
  2354 		 *
       
  2355 		 * Passing a non-null value to the filter will short-circuit
       
  2356 		 * checking the DB for the charset, returning that value instead.
       
  2357 		 *
       
  2358 		 * @since 4.2.0
       
  2359 		 *
       
  2360 		 * @param string $charset The character set to use. Default null.
       
  2361 		 * @param string $table   The name of the table being checked.
       
  2362 		 * @param string $column  The name of the column being checked.
       
  2363 		 */
       
  2364 		$charset = apply_filters( 'pre_get_col_charset', null, $table, $column );
       
  2365 		if ( null !== $charset ) {
       
  2366 			return $charset;
       
  2367 		}
       
  2368 
       
  2369 		// Skip this entirely if this isn't a MySQL database.
       
  2370 		if ( false === $this->is_mysql ) {
       
  2371 			return false;
       
  2372 		}
       
  2373 
       
  2374 		if ( empty( $this->table_charset[ $tablekey ] ) ) {
       
  2375 			// This primes column information for us.
       
  2376 			$table_charset = $this->get_table_charset( $table );
       
  2377 			if ( is_wp_error( $table_charset ) ) {
       
  2378 				return $table_charset;
       
  2379 			}
       
  2380 		}
       
  2381 
       
  2382 		// If still no column information, return the table charset.
       
  2383 		if ( empty( $this->col_meta[ $tablekey ] ) ) {
       
  2384 			return $this->table_charset[ $tablekey ];
       
  2385 		}
       
  2386 
       
  2387 		// If this column doesn't exist, return the table charset.
       
  2388 		if ( empty( $this->col_meta[ $tablekey ][ $columnkey ] ) ) {
       
  2389 			return $this->table_charset[ $tablekey ];
       
  2390 		}
       
  2391 
       
  2392 		// Return false when it's not a string column.
       
  2393 		if ( empty( $this->col_meta[ $tablekey ][ $columnkey ]->Collation ) ) {
       
  2394 			return false;
       
  2395 		}
       
  2396 
       
  2397 		list( $charset ) = explode( '_', $this->col_meta[ $tablekey ][ $columnkey ]->Collation );
       
  2398 		return $charset;
       
  2399 	}
       
  2400 
       
  2401 	/**
       
  2402 	 * Retrieve the maximum string length allowed in a given column.
       
  2403 	 * The length may either be specified as a byte length or a character length.
       
  2404 	 *
       
  2405 	 * @since 4.2.1
       
  2406 	 * @access public
       
  2407 	 *
       
  2408 	 * @param string $table  Table name.
       
  2409 	 * @param string $column Column name.
       
  2410 	 * @return mixed array( 'length' => (int), 'type' => 'byte' | 'char' )
       
  2411 	 *               false if the column has no length (for example, numeric column)
       
  2412 	 *               WP_Error object if there was an error.
       
  2413 	 */
       
  2414 	public function get_col_length( $table, $column ) {
       
  2415 		$tablekey = strtolower( $table );
       
  2416 		$columnkey = strtolower( $column );
       
  2417 
       
  2418 		// Skip this entirely if this isn't a MySQL database.
       
  2419 		if ( false === $this->is_mysql ) {
       
  2420 			return false;
       
  2421 		}
       
  2422 
       
  2423 		if ( empty( $this->col_meta[ $tablekey ] ) ) {
       
  2424 			// This primes column information for us.
       
  2425 			$table_charset = $this->get_table_charset( $table );
       
  2426 			if ( is_wp_error( $table_charset ) ) {
       
  2427 				return $table_charset;
       
  2428 			}
       
  2429 		}
       
  2430 
       
  2431 		if ( empty( $this->col_meta[ $tablekey ][ $columnkey ] ) ) {
       
  2432 			return false;
       
  2433 		}
       
  2434 
       
  2435 		$typeinfo = explode( '(', $this->col_meta[ $tablekey ][ $columnkey ]->Type );
       
  2436 
       
  2437 		$type = strtolower( $typeinfo[0] );
       
  2438 		if ( ! empty( $typeinfo[1] ) ) {
       
  2439 			$length = trim( $typeinfo[1], ')' );
       
  2440 		} else {
       
  2441 			$length = false;
       
  2442 		}
       
  2443 
       
  2444 		switch( $type ) {
       
  2445 			case 'char':
       
  2446 			case 'varchar':
       
  2447 				return array(
       
  2448 					'type'   => 'char',
       
  2449 					'length' => (int) $length,
       
  2450 				);
       
  2451 				break;
       
  2452 			case 'binary':
       
  2453 			case 'varbinary':
       
  2454 				return array(
       
  2455 					'type'   => 'byte',
       
  2456 					'length' => (int) $length,
       
  2457 				);
       
  2458 				break;
       
  2459 			case 'tinyblob':
       
  2460 			case 'tinytext':
       
  2461 				return array(
       
  2462 					'type'   => 'byte',
       
  2463 					'length' => 255,        // 2^8 - 1
       
  2464 				);
       
  2465 				break;
       
  2466 			case 'blob':
       
  2467 			case 'text':
       
  2468 				return array(
       
  2469 					'type'   => 'byte',
       
  2470 					'length' => 65535,      // 2^16 - 1
       
  2471 				);
       
  2472 				break;
       
  2473 			case 'mediumblob':
       
  2474 			case 'mediumtext':
       
  2475 				return array(
       
  2476 					'type'   => 'byte',
       
  2477 					'length' => 16777215,   // 2^24 - 1
       
  2478 				);
       
  2479 				break;
       
  2480 			case 'longblob':
       
  2481 			case 'longtext':
       
  2482 				return array(
       
  2483 					'type'   => 'byte',
       
  2484 					'length' => 4294967295, // 2^32 - 1
       
  2485 				);
       
  2486 				break;
       
  2487 			default:
       
  2488 				return false;
       
  2489 		}
       
  2490 
       
  2491 		return false;
       
  2492 	}
       
  2493 
       
  2494 	/**
       
  2495 	 * Check if a string is ASCII.
       
  2496 	 *
       
  2497 	 * The negative regex is faster for non-ASCII strings, as it allows
       
  2498 	 * the search to finish as soon as it encounters a non-ASCII character.
       
  2499 	 *
       
  2500 	 * @since 4.2.0
       
  2501 	 * @access protected
       
  2502 	 *
       
  2503 	 * @param string $string String to check.
       
  2504 	 * @return bool True if ASCII, false if not.
       
  2505 	 */
       
  2506 	protected function check_ascii( $string ) {
       
  2507 		if ( function_exists( 'mb_check_encoding' ) ) {
       
  2508 			if ( mb_check_encoding( $string, 'ASCII' ) ) {
       
  2509 				return true;
       
  2510 			}
       
  2511 		} elseif ( ! preg_match( '/[^\x00-\x7F]/', $string ) ) {
       
  2512 			return true;
       
  2513 		}
       
  2514 
       
  2515 		return false;
       
  2516 	}
       
  2517 
       
  2518 	/**
       
  2519 	 * Check if the query is accessing a collation considered safe on the current version of MySQL.
       
  2520 	 *
       
  2521 	 * @since 4.2.0
       
  2522 	 * @access protected
       
  2523 	 *
       
  2524 	 * @param string $query The query to check.
       
  2525 	 * @return bool True if the collation is safe, false if it isn't.
       
  2526 	 */
       
  2527 	protected function check_safe_collation( $query ) {
       
  2528 		if ( $this->checking_collation ) {
       
  2529 			return true;
       
  2530 		}
       
  2531 
       
  2532 		// We don't need to check the collation for queries that don't read data.
       
  2533 		$query = ltrim( $query, "\r\n\t (" );
       
  2534 		if ( preg_match( '/^(?:SHOW|DESCRIBE|DESC|EXPLAIN|CREATE)\s/i', $query ) ) {
       
  2535 			return true;
       
  2536 		}
       
  2537 
       
  2538 		// All-ASCII queries don't need extra checking.
       
  2539 		if ( $this->check_ascii( $query ) ) {
       
  2540 			return true;
       
  2541 		}
       
  2542 
       
  2543 		$table = $this->get_table_from_query( $query );
       
  2544 		if ( ! $table ) {
       
  2545 			return false;
       
  2546 		}
       
  2547 
       
  2548 		$this->checking_collation = true;
       
  2549 		$collation = $this->get_table_charset( $table );
       
  2550 		$this->checking_collation = false;
       
  2551 
       
  2552 		// Tables with no collation, or latin1 only, don't need extra checking.
       
  2553 		if ( false === $collation || 'latin1' === $collation ) {
       
  2554 			return true;
       
  2555 		}
       
  2556 
       
  2557 		$table = strtolower( $table );
       
  2558 		if ( empty( $this->col_meta[ $table ] ) ) {
       
  2559 			return false;
       
  2560 		}
       
  2561 
       
  2562 		// If any of the columns don't have one of these collations, it needs more sanity checking.
       
  2563 		foreach( $this->col_meta[ $table ] as $col ) {
       
  2564 			if ( empty( $col->Collation ) ) {
       
  2565 				continue;
       
  2566 			}
       
  2567 
       
  2568 			if ( ! in_array( $col->Collation, array( 'utf8_general_ci', 'utf8_bin', 'utf8mb4_general_ci', 'utf8mb4_bin' ), true ) ) {
       
  2569 				return false;
       
  2570 			}
       
  2571 		}
       
  2572 
       
  2573 		return true;
       
  2574 	}
       
  2575 
       
  2576 	/**
       
  2577 	 * Strips any invalid characters based on value/charset pairs.
       
  2578 	 *
       
  2579 	 * @since 4.2.0
       
  2580 	 * @access protected
       
  2581 	 *
       
  2582 	 * @param array $data Array of value arrays. Each value array has the keys
       
  2583 	 *                    'value' and 'charset'. An optional 'ascii' key can be
       
  2584 	 *                    set to false to avoid redundant ASCII checks.
       
  2585 	 * @return array|WP_Error The $data parameter, with invalid characters removed from
       
  2586 	 *                        each value. This works as a passthrough: any additional keys
       
  2587 	 *                        such as 'field' are retained in each value array. If we cannot
       
  2588 	 *                        remove invalid characters, a WP_Error object is returned.
       
  2589 	 */
       
  2590 	protected function strip_invalid_text( $data ) {
       
  2591 		$db_check_string = false;
       
  2592 
       
  2593 		foreach ( $data as &$value ) {
       
  2594 			$charset = $value['charset'];
       
  2595 
       
  2596 			if ( is_array( $value['length'] ) ) {
       
  2597 				$length = $value['length']['length'];
       
  2598 			} else {
       
  2599 				$length = false;
       
  2600 			}
       
  2601 
       
  2602 			// There's no charset to work with.
       
  2603 			if ( false === $charset ) {
       
  2604 				continue;
       
  2605 			}
       
  2606 
       
  2607 			// Column isn't a string.
       
  2608 			if ( ! is_string( $value['value'] ) ) {
       
  2609 				continue;
       
  2610 			}
       
  2611 
       
  2612 			$truncate_by_byte_length = 'byte' === $value['length']['type'];
       
  2613 
       
  2614 			$needs_validation = true;
       
  2615 			if (
       
  2616 				// latin1 can store any byte sequence
       
  2617 				'latin1' === $charset
       
  2618 			||
       
  2619 				// ASCII is always OK.
       
  2620 				( ! isset( $value['ascii'] ) && $this->check_ascii( $value['value'] ) )
       
  2621 			) {
       
  2622 				$truncate_by_byte_length = true;
       
  2623 				$needs_validation = false;
       
  2624 			}
       
  2625 
       
  2626 			if ( $truncate_by_byte_length ) {
       
  2627 				mbstring_binary_safe_encoding();
       
  2628 				if ( false !== $length && strlen( $value['value'] ) > $length ) {
       
  2629 					$value['value'] = substr( $value['value'], 0, $length );
       
  2630 				}
       
  2631 				reset_mbstring_encoding();
       
  2632 
       
  2633 				if ( ! $needs_validation ) {
       
  2634 					continue;
       
  2635 				}
       
  2636 			}
       
  2637 
       
  2638 			// utf8 can be handled by regex, which is a bunch faster than a DB lookup.
       
  2639 			if ( ( 'utf8' === $charset || 'utf8mb3' === $charset || 'utf8mb4' === $charset ) && function_exists( 'mb_strlen' ) ) {
       
  2640 				$regex = '/
       
  2641 					(
       
  2642 						(?: [\x00-\x7F]                  # single-byte sequences   0xxxxxxx
       
  2643 						|   [\xC2-\xDF][\x80-\xBF]       # double-byte sequences   110xxxxx 10xxxxxx
       
  2644 						|   \xE0[\xA0-\xBF][\x80-\xBF]   # triple-byte sequences   1110xxxx 10xxxxxx * 2
       
  2645 						|   [\xE1-\xEC][\x80-\xBF]{2}
       
  2646 						|   \xED[\x80-\x9F][\x80-\xBF]
       
  2647 						|   [\xEE-\xEF][\x80-\xBF]{2}';
       
  2648 
       
  2649 				if ( 'utf8mb4' === $charset ) {
       
  2650 					$regex .= '
       
  2651 						|    \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
       
  2652 						|    [\xF1-\xF3][\x80-\xBF]{3}
       
  2653 						|    \xF4[\x80-\x8F][\x80-\xBF]{2}
       
  2654 					';
       
  2655 				}
       
  2656 
       
  2657 				$regex .= '){1,40}                          # ...one or more times
       
  2658 					)
       
  2659 					| .                                  # anything else
       
  2660 					/x';
       
  2661 				$value['value'] = preg_replace( $regex, '$1', $value['value'] );
       
  2662 
       
  2663 
       
  2664 				if ( false !== $length && mb_strlen( $value['value'], 'UTF-8' ) > $length ) {
       
  2665 					$value['value'] = mb_substr( $value['value'], 0, $length, 'UTF-8' );
       
  2666 				}
       
  2667 				continue;
       
  2668 			}
       
  2669 
       
  2670 			// We couldn't use any local conversions, send it to the DB.
       
  2671 			$value['db'] = $db_check_string = true;
       
  2672 		}
       
  2673 		unset( $value ); // Remove by reference.
       
  2674 
       
  2675 		if ( $db_check_string ) {
       
  2676 			$queries = array();
       
  2677 			foreach ( $data as $col => $value ) {
       
  2678 				if ( ! empty( $value['db'] ) ) {
       
  2679 					if ( ! isset( $queries[ $value['charset'] ] ) ) {
       
  2680 						$queries[ $value['charset'] ] = array();
       
  2681 					}
       
  2682 
       
  2683 					// We're going to need to truncate by characters or bytes, depending on the length value we have.
       
  2684 					if ( 'byte' === $value['length']['type'] ) {
       
  2685 						// Split the CONVERT() calls by charset, so we can make sure the connection is right
       
  2686 						$queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING binary ), %d ) USING {$value['charset']} )", $value['value'], $value['length']['length'] );
       
  2687 					} else {
       
  2688 						$queries[ $value['charset'] ][ $col ] = $this->prepare( "LEFT( CONVERT( %s USING {$value['charset']} ), %d )", $value['value'], $value['length']['length'] );
       
  2689 					}
       
  2690 
       
  2691 					unset( $data[ $col ]['db'] );
       
  2692 				}
       
  2693 			}
       
  2694 
       
  2695 			$connection_charset = $this->charset;
       
  2696 			foreach ( $queries as $charset => $query ) {
       
  2697 				if ( ! $query ) {
       
  2698 					continue;
       
  2699 				}
       
  2700 
       
  2701 				// Change the charset to match the string(s) we're converting
       
  2702 				if ( $charset !== $connection_charset ) {
       
  2703 					$connection_charset = $charset;
       
  2704 					$this->set_charset( $this->dbh, $charset );
       
  2705 				}
       
  2706 
       
  2707 				$this->check_current_query = false;
       
  2708 
       
  2709 				$sql = array();
       
  2710 				foreach ( $query as $column => $column_query ) {
       
  2711 					$sql[] = $column_query . " AS x_$column";
       
  2712 				}
       
  2713 
       
  2714 				$row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A );
       
  2715 				if ( ! $row ) {
       
  2716 					$this->set_charset( $this->dbh, $connection_charset );
       
  2717 					return new WP_Error( 'wpdb_strip_invalid_text_failure' );
       
  2718 				}
       
  2719 
       
  2720 				foreach ( array_keys( $query ) as $column ) {
       
  2721 					$data[ $column ]['value'] = $row["x_$column"];
       
  2722 				}
       
  2723 			}
       
  2724 
       
  2725 			// Don't forget to change the charset back!
       
  2726 			if ( $connection_charset !== $this->charset ) {
       
  2727 				$this->set_charset( $this->dbh );
       
  2728 			}
       
  2729 		}
       
  2730 
       
  2731 		return $data;
       
  2732 	}
       
  2733 
       
  2734 	/**
       
  2735 	 * Strips any invalid characters from the query.
       
  2736 	 *
       
  2737 	 * @since 4.2.0
       
  2738 	 * @access protected
       
  2739 	 *
       
  2740 	 * @param string $query Query to convert.
       
  2741 	 * @return string|WP_Error The converted query, or a WP_Error object if the conversion fails.
       
  2742 	 */
       
  2743 	protected function strip_invalid_text_from_query( $query ) {
       
  2744 		// We don't need to check the collation for queries that don't read data.
       
  2745 		$trimmed_query = ltrim( $query, "\r\n\t (" );
       
  2746 		if ( preg_match( '/^(?:SHOW|DESCRIBE|DESC|EXPLAIN|CREATE)\s/i', $trimmed_query ) ) {
       
  2747 			return $query;
       
  2748 		}
       
  2749 
       
  2750 		$table = $this->get_table_from_query( $query );
       
  2751 		if ( $table ) {
       
  2752 			$charset = $this->get_table_charset( $table );
       
  2753 			if ( is_wp_error( $charset ) ) {
       
  2754 				return $charset;
       
  2755 			}
       
  2756 
       
  2757 			// We can't reliably strip text from tables containing binary/blob columns
       
  2758 			if ( 'binary' === $charset ) {
       
  2759 				return $query;
       
  2760 			}
       
  2761 		} else {
       
  2762 			$charset = $this->charset;
       
  2763 		}
       
  2764 
       
  2765 		$data = array(
       
  2766 			'value'   => $query,
       
  2767 			'charset' => $charset,
       
  2768 			'ascii'   => false,
       
  2769 			'length'  => false,
       
  2770 		);
       
  2771 
       
  2772 		$data = $this->strip_invalid_text( array( $data ) );
       
  2773 		if ( is_wp_error( $data ) ) {
       
  2774 			return $data;
       
  2775 		}
       
  2776 
       
  2777 		return $data[0]['value'];
       
  2778 	}
       
  2779 
       
  2780 	/**
       
  2781 	 * Strips any invalid characters from the string for a given table and column.
       
  2782 	 *
       
  2783 	 * @since 4.2.0
       
  2784 	 * @access public
       
  2785 	 *
       
  2786 	 * @param string $table  Table name.
       
  2787 	 * @param string $column Column name.
       
  2788 	 * @param string $value  The text to check.
       
  2789 	 * @return string|WP_Error The converted string, or a WP_Error object if the conversion fails.
       
  2790 	 */
       
  2791 	public function strip_invalid_text_for_column( $table, $column, $value ) {
       
  2792 		if ( ! is_string( $value ) ) {
       
  2793 			return $value;
       
  2794 		}
       
  2795 
       
  2796 		$charset = $this->get_col_charset( $table, $column );
       
  2797 		if ( ! $charset ) {
       
  2798 			// Not a string column.
       
  2799 			return $value;
       
  2800 		} elseif ( is_wp_error( $charset ) ) {
       
  2801 			// Bail on real errors.
       
  2802 			return $charset;
       
  2803 		}
       
  2804 
       
  2805 		$data = array(
       
  2806 			$column => array(
       
  2807 				'value'   => $value,
       
  2808 				'charset' => $charset,
       
  2809 				'length'  => $this->get_col_length( $table, $column ),
       
  2810 			)
       
  2811 		);
       
  2812 
       
  2813 		$data = $this->strip_invalid_text( $data );
       
  2814 		if ( is_wp_error( $data ) ) {
       
  2815 			return $data;
       
  2816 		}
       
  2817 
       
  2818 		return $data[ $column ]['value'];
       
  2819 	}
       
  2820 
       
  2821 	/**
       
  2822 	 * Find the first table name referenced in a query.
       
  2823 	 *
       
  2824 	 * @since 4.2.0
       
  2825 	 * @access protected
       
  2826 	 *
       
  2827 	 * @param string $query The query to search.
       
  2828 	 * @return string|false $table The table name found, or false if a table couldn't be found.
       
  2829 	 */
       
  2830 	protected function get_table_from_query( $query ) {
       
  2831 		// Remove characters that can legally trail the table name.
       
  2832 		$query = rtrim( $query, ';/-#' );
       
  2833 
       
  2834 		// Allow (select...) union [...] style queries. Use the first query's table name.
       
  2835 		$query = ltrim( $query, "\r\n\t (" );
       
  2836 
       
  2837 		/*
       
  2838 		 * Strip everything between parentheses except nested selects and use only 1,000
       
  2839 		 * chars of the query.
       
  2840 		 */
       
  2841 		$query = preg_replace( '/\((?!\s*select)[^(]*?\)/is', '()', substr( $query, 0, 1000 ) );
       
  2842 
       
  2843 		// Quickly match most common queries.
       
  2844 		if ( preg_match( '/^\s*(?:'
       
  2845 				. 'SELECT.*?\s+FROM'
       
  2846 				. '|INSERT(?:\s+LOW_PRIORITY|\s+DELAYED|\s+HIGH_PRIORITY)?(?:\s+IGNORE)?(?:\s+INTO)?'
       
  2847 				. '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?'
       
  2848 				. '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?'
       
  2849 				. '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:\s+FROM)?'
       
  2850 				. ')\s+((?:[0-9a-zA-Z$_.`]|[\xC2-\xDF][\x80-\xBF])+)/is', $query, $maybe ) ) {
       
  2851 			return str_replace( '`', '', $maybe[1] );
       
  2852 		}
       
  2853 
       
  2854 		// SHOW TABLE STATUS and SHOW TABLES
       
  2855 		if ( preg_match( '/^\s*(?:'
       
  2856 				. 'SHOW\s+TABLE\s+STATUS.+(?:LIKE\s+|WHERE\s+Name\s*=\s*)'
       
  2857 				. '|SHOW\s+(?:FULL\s+)?TABLES.+(?:LIKE\s+|WHERE\s+Name\s*=\s*)'
       
  2858 				. ')\W((?:[0-9a-zA-Z$_.`]|[\xC2-\xDF][\x80-\xBF])+)\W/is', $query, $maybe ) ) {
       
  2859 			return str_replace( '`', '', $maybe[1] );
       
  2860 		}
       
  2861 
       
  2862 		// Big pattern for the rest of the table-related queries.
       
  2863 		if ( preg_match( '/^\s*(?:'
       
  2864 				. '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM'
       
  2865 				. '|DESCRIBE|DESC|EXPLAIN|HANDLER'
       
  2866 				. '|(?:LOCK|UNLOCK)\s+TABLE(?:S)?'
       
  2867 				. '|(?:RENAME|OPTIMIZE|BACKUP|RESTORE|CHECK|CHECKSUM|ANALYZE|REPAIR).*\s+TABLE'
       
  2868 				. '|TRUNCATE(?:\s+TABLE)?'
       
  2869 				. '|CREATE(?:\s+TEMPORARY)?\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?'
       
  2870 				. '|ALTER(?:\s+IGNORE)?\s+TABLE'
       
  2871 				. '|DROP\s+TABLE(?:\s+IF\s+EXISTS)?'
       
  2872 				. '|CREATE(?:\s+\w+)?\s+INDEX.*\s+ON'
       
  2873 				. '|DROP\s+INDEX.*\s+ON'
       
  2874 				. '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE'
       
  2875 				. '|(?:GRANT|REVOKE).*ON\s+TABLE'
       
  2876 				. '|SHOW\s+(?:.*FROM|.*TABLE)'
       
  2877 				. ')\s+\(*\s*((?:[0-9a-zA-Z$_.`]|[\xC2-\xDF][\x80-\xBF])+)\s*\)*/is', $query, $maybe ) ) {
       
  2878 			return str_replace( '`', '', $maybe[1] );
       
  2879 		}
       
  2880 
       
  2881 		return false;
  1564 	}
  2882 	}
  1565 
  2883 
  1566 	/**
  2884 	/**
  1567 	 * Load the column metadata from the last query.
  2885 	 * Load the column metadata from the last query.
  1568 	 *
  2886 	 *
  1572 	 */
  2890 	 */
  1573 	protected function load_col_info() {
  2891 	protected function load_col_info() {
  1574 		if ( $this->col_info )
  2892 		if ( $this->col_info )
  1575 			return;
  2893 			return;
  1576 
  2894 
  1577 		for ( $i = 0; $i < @mysql_num_fields( $this->result ); $i++ ) {
  2895 		if ( $this->use_mysqli ) {
  1578 			$this->col_info[ $i ] = @mysql_fetch_field( $this->result, $i );
  2896 			for ( $i = 0; $i < @mysqli_num_fields( $this->result ); $i++ ) {
       
  2897 				$this->col_info[ $i ] = @mysqli_fetch_field( $this->result );
       
  2898 			}
       
  2899 		} else {
       
  2900 			for ( $i = 0; $i < @mysql_num_fields( $this->result ); $i++ ) {
       
  2901 				$this->col_info[ $i ] = @mysql_fetch_field( $this->result, $i );
       
  2902 			}
  1579 		}
  2903 		}
  1580 	}
  2904 	}
  1581 
  2905 
  1582 	/**
  2906 	/**
  1583 	 * Retrieve column metadata from the last query.
  2907 	 * Retrieve column metadata from the last query.
  1586 	 *
  2910 	 *
  1587 	 * @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
  2911 	 * @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
  1588 	 * @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
  2912 	 * @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
  1589 	 * @return mixed Column Results
  2913 	 * @return mixed Column Results
  1590 	 */
  2914 	 */
  1591 	function get_col_info( $info_type = 'name', $col_offset = -1 ) {
  2915 	public function get_col_info( $info_type = 'name', $col_offset = -1 ) {
  1592 		$this->load_col_info();
  2916 		$this->load_col_info();
  1593 
  2917 
  1594 		if ( $this->col_info ) {
  2918 		if ( $this->col_info ) {
  1595 			if ( $col_offset == -1 ) {
  2919 			if ( $col_offset == -1 ) {
  1596 				$i = 0;
  2920 				$i = 0;
  1609 	/**
  2933 	/**
  1610 	 * Starts the timer, for debugging purposes.
  2934 	 * Starts the timer, for debugging purposes.
  1611 	 *
  2935 	 *
  1612 	 * @since 1.5.0
  2936 	 * @since 1.5.0
  1613 	 *
  2937 	 *
  1614 	 * @return true
  2938 	 * @return bool
  1615 	 */
  2939 	 */
  1616 	function timer_start() {
  2940 	public function timer_start() {
  1617 		$this->time_start = microtime( true );
  2941 		$this->time_start = microtime( true );
  1618 		return true;
  2942 		return true;
  1619 	}
  2943 	}
  1620 
  2944 
  1621 	/**
  2945 	/**
  1623 	 *
  2947 	 *
  1624 	 * @since 1.5.0
  2948 	 * @since 1.5.0
  1625 	 *
  2949 	 *
  1626 	 * @return float Total time spent on the query, in seconds
  2950 	 * @return float Total time spent on the query, in seconds
  1627 	 */
  2951 	 */
  1628 	function timer_stop() {
  2952 	public function timer_stop() {
  1629 		return ( microtime( true ) - $this->time_start );
  2953 		return ( microtime( true ) - $this->time_start );
  1630 	}
  2954 	}
  1631 
  2955 
  1632 	/**
  2956 	/**
  1633 	 * Wraps errors in a nice header and footer and dies.
  2957 	 * Wraps errors in a nice header and footer and dies.
  1638 	 *
  2962 	 *
  1639 	 * @param string $message The Error message
  2963 	 * @param string $message The Error message
  1640 	 * @param string $error_code Optional. A Computer readable string to identify the error.
  2964 	 * @param string $error_code Optional. A Computer readable string to identify the error.
  1641 	 * @return false|void
  2965 	 * @return false|void
  1642 	 */
  2966 	 */
  1643 	function bail( $message, $error_code = '500' ) {
  2967 	public function bail( $message, $error_code = '500' ) {
  1644 		if ( !$this->show_errors ) {
  2968 		if ( !$this->show_errors ) {
  1645 			if ( class_exists( 'WP_Error' ) )
  2969 			if ( class_exists( 'WP_Error' ) )
  1646 				$this->error = new WP_Error($error_code, $message);
  2970 				$this->error = new WP_Error($error_code, $message);
  1647 			else
  2971 			else
  1648 				$this->error = $message;
  2972 				$this->error = $message;
  1658 	 * @uses $wp_version
  2982 	 * @uses $wp_version
  1659 	 * @uses $required_mysql_version
  2983 	 * @uses $required_mysql_version
  1660 	 *
  2984 	 *
  1661 	 * @return WP_Error
  2985 	 * @return WP_Error
  1662 	 */
  2986 	 */
  1663 	function check_database_version() {
  2987 	public function check_database_version() {
  1664 		global $wp_version, $required_mysql_version;
  2988 		global $wp_version, $required_mysql_version;
  1665 		// Make sure the server has the required MySQL version
  2989 		// Make sure the server has the required MySQL version
  1666 		if ( version_compare($this->db_version(), $required_mysql_version, '<') )
  2990 		if ( version_compare($this->db_version(), $required_mysql_version, '<') )
  1667 			return new WP_Error('database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ));
  2991 			return new WP_Error('database_version', sprintf( __( '<strong>ERROR</strong>: WordPress %1$s requires MySQL %2$s or higher' ), $wp_version, $required_mysql_version ));
  1668 	}
  2992 	}
  1676 	 * @deprecated 3.5.0
  3000 	 * @deprecated 3.5.0
  1677 	 * @deprecated Use wpdb::has_cap( 'collation' )
  3001 	 * @deprecated Use wpdb::has_cap( 'collation' )
  1678 	 *
  3002 	 *
  1679 	 * @return bool True if collation is supported, false if version does not
  3003 	 * @return bool True if collation is supported, false if version does not
  1680 	 */
  3004 	 */
  1681 	function supports_collation() {
  3005 	public function supports_collation() {
  1682 		_deprecated_function( __FUNCTION__, '3.5', 'wpdb::has_cap( \'collation\' )' );
  3006 		_deprecated_function( __FUNCTION__, '3.5', 'wpdb::has_cap( \'collation\' )' );
  1683 		return $this->has_cap( 'collation' );
  3007 		return $this->has_cap( 'collation' );
  1684 	}
  3008 	}
  1685 
  3009 
  1686 	/**
  3010 	/**
  1703 
  3027 
  1704 	/**
  3028 	/**
  1705 	 * Determine if a database supports a particular feature.
  3029 	 * Determine if a database supports a particular feature.
  1706 	 *
  3030 	 *
  1707 	 * @since 2.7.0
  3031 	 * @since 2.7.0
       
  3032 	 * @since 4.1.0 Support was added for the 'utf8mb4' feature.
       
  3033 	 *
  1708 	 * @see wpdb::db_version()
  3034 	 * @see wpdb::db_version()
  1709 	 *
  3035 	 *
  1710 	 * @param string $db_cap The feature to check for.
  3036 	 * @param string $db_cap The feature to check for. Accepts 'collation',
  1711 	 * @return bool
  3037 	 *                       'group_concat', 'subqueries', 'set_charset',
  1712 	 */
  3038 	 *                       or 'utf8mb4'.
  1713 	function has_cap( $db_cap ) {
  3039 	 * @return bool Whether the database feature is supported, false otherwise.
       
  3040 	 */
       
  3041 	public function has_cap( $db_cap ) {
  1714 		$version = $this->db_version();
  3042 		$version = $this->db_version();
  1715 
  3043 
  1716 		switch ( strtolower( $db_cap ) ) {
  3044 		switch ( strtolower( $db_cap ) ) {
  1717 			case 'collation' :    // @since 2.5.0
  3045 			case 'collation' :    // @since 2.5.0
  1718 			case 'group_concat' : // @since 2.7.0
  3046 			case 'group_concat' : // @since 2.7.0
  1719 			case 'subqueries' :   // @since 2.7.0
  3047 			case 'subqueries' :   // @since 2.7.0
  1720 				return version_compare( $version, '4.1', '>=' );
  3048 				return version_compare( $version, '4.1', '>=' );
  1721 			case 'set_charset' :
  3049 			case 'set_charset' :
  1722 				return version_compare( $version, '5.0.7', '>=' );
  3050 				return version_compare( $version, '5.0.7', '>=' );
  1723 		};
  3051 			case 'utf8mb4' :      // @since 4.1.0
       
  3052 				if ( version_compare( $version, '5.5.3', '<' ) ) {
       
  3053 					return false;
       
  3054 				}
       
  3055 				if ( $this->use_mysqli ) {
       
  3056 					$client_version = mysqli_get_client_info();
       
  3057 				} else {
       
  3058 					$client_version = mysql_get_client_info();
       
  3059 				}
       
  3060 
       
  3061 				/*
       
  3062 				 * libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server.
       
  3063 				 * mysqlnd has supported utf8mb4 since 5.0.9.
       
  3064 				 */
       
  3065 				if ( false !== strpos( $client_version, 'mysqlnd' ) ) {
       
  3066 					$client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $client_version );
       
  3067 					return version_compare( $client_version, '5.0.9', '>=' );
       
  3068 				} else {
       
  3069 					return version_compare( $client_version, '5.5.3', '>=' );
       
  3070 				}
       
  3071 		}
  1724 
  3072 
  1725 		return false;
  3073 		return false;
  1726 	}
  3074 	}
  1727 
  3075 
  1728 	/**
  3076 	/**
  1733 	 *
  3081 	 *
  1734 	 * @since 2.5.0
  3082 	 * @since 2.5.0
  1735 	 *
  3083 	 *
  1736 	 * @return string The name of the calling function
  3084 	 * @return string The name of the calling function
  1737 	 */
  3085 	 */
  1738 	function get_caller() {
  3086 	public function get_caller() {
  1739 		return wp_debug_backtrace_summary( __CLASS__ );
  3087 		return wp_debug_backtrace_summary( __CLASS__ );
  1740 	}
  3088 	}
  1741 
  3089 
  1742 	/**
  3090 	/**
  1743 	 * The database version number.
  3091 	 * The database version number.
  1744 	 *
  3092 	 *
  1745 	 * @since 2.7.0
  3093 	 * @since 2.7.0
  1746 	 *
  3094 	 *
  1747 	 * @return false|string false on failure, version number on success
  3095 	 * @return null|string Null on failure, version number on success.
  1748 	 */
  3096 	 */
  1749 	function db_version() {
  3097 	public function db_version() {
  1750 		return preg_replace( '/[^0-9.].*/', '', mysql_get_server_info( $this->dbh ) );
  3098 		if ( $this->use_mysqli ) {
       
  3099 			$server_info = mysqli_get_server_info( $this->dbh );
       
  3100 		} else {
       
  3101 			$server_info = mysql_get_server_info( $this->dbh );
       
  3102 		}
       
  3103 		return preg_replace( '/[^0-9.].*/', '', $server_info );
  1751 	}
  3104 	}
  1752 }
  3105 }