X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/38ac4bc40322ecdc4052db4263466573e01fa51f..3d39054f012aefe514b3f5509e32f09fc4feda44:/wp-includes/wp-db.php diff --git a/wp-includes/wp-db.php b/wp-includes/wp-db.php index d0a5a29a..8ebee4c4 100644 --- a/wp-includes/wp-db.php +++ b/wp-includes/wp-db.php @@ -84,19 +84,19 @@ class wpdb { * Amount of queries made * * @since 1.2.0 - * @access private + * @access public * @var int */ - var $num_queries = 0; + public $num_queries = 0; /** * Count of rows returned by previous query * * @since 0.71 - * @access private + * @access public * @var int */ - var $num_rows = 0; + public $num_rows = 0; /** * Count of affected rows by previous query @@ -114,7 +114,7 @@ class wpdb { * @access public * @var int */ - var $insert_id = 0; + public $insert_id = 0; /** * Last query made @@ -176,7 +176,7 @@ class wpdb { * @since 4.2.0 * @access private * @see wpdb::check_safe_collation() - * @var boolean + * @var bool */ private $checking_collation = false; @@ -216,10 +216,10 @@ class wpdb { * security precautions. * * @since 2.5.0 - * @access private + * @access public * @var string */ - var $prefix = ''; + public $prefix = ''; /** * WordPress base table prefix. @@ -266,7 +266,7 @@ class wpdb { * @var array */ var $tables = array( 'posts', 'comments', 'links', 'options', 'postmeta', - 'terms', 'term_taxonomy', 'term_relationships', 'commentmeta' ); + 'terms', 'term_taxonomy', 'term_relationships', 'termmeta', 'commentmeta' ); /** * List of deprecated WordPress tables @@ -382,9 +382,18 @@ class wpdb { */ public $term_taxonomy; - /* - * Global and Multisite tables + /** + * WordPress Term Meta table. + * + * @since 4.4.0 + * @access public + * @var string */ + public $termmeta; + + // + // Global and Multisite tables + // /** * WordPress User Metadata table @@ -607,10 +616,12 @@ class wpdb { * @link https://core.trac.wordpress.org/ticket/3354 * @since 2.0.8 * - * @param string $dbuser MySQL database user + * @global string $wp_version + * + * @param string $dbuser MySQL database user * @param string $dbpassword MySQL database password - * @param string $dbname MySQL database name - * @param string $dbhost MySQL database host + * @param string $dbname MySQL database name + * @param string $dbhost MySQL database host */ public function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) { register_shutdown_function( array( $this, '__destruct' ) ); @@ -652,14 +663,14 @@ class wpdb { * * @see wpdb::__construct() * @since 2.0.8 - * @return bool true + * @return true */ public function __destruct() { return true; } /** - * PHP5 style magic getter, used to lazy-load expensive data. + * Makes private properties readable for backward compatibility. * * @since 3.5.0 * @@ -674,7 +685,7 @@ class wpdb { } /** - * Magic function, for backwards compatibility. + * Makes private properties settable for backward compatibility. * * @since 3.5.0 * @@ -694,7 +705,7 @@ class wpdb { } /** - * Magic function, for backwards compatibility. + * Makes private properties check-able for backward compatibility. * * @since 3.5.0 * @@ -707,7 +718,7 @@ class wpdb { } /** - * Magic function, for backwards compatibility. + * Makes private properties un-settable for backward compatibility. * * @since 3.5.0 * @@ -723,32 +734,66 @@ class wpdb { * @since 3.1.0 */ public function init_charset() { + $charset = ''; + $collate = ''; + if ( function_exists('is_multisite') && is_multisite() ) { - $this->charset = 'utf8'; + $charset = 'utf8'; if ( defined( 'DB_COLLATE' ) && DB_COLLATE ) { - $this->collate = DB_COLLATE; + $collate = DB_COLLATE; } else { - $this->collate = 'utf8_general_ci'; + $collate = 'utf8_general_ci'; } } elseif ( defined( 'DB_COLLATE' ) ) { - $this->collate = DB_COLLATE; + $collate = DB_COLLATE; } if ( defined( 'DB_CHARSET' ) ) { - $this->charset = DB_CHARSET; + $charset = DB_CHARSET; } + $charset_collate = $this->determine_charset( $charset, $collate ); + + $this->charset = $charset_collate['charset']; + $this->collate = $charset_collate['collate']; + } + + /** + * Determines the best charset and collation to use given a charset and collation. + * + * For example, when able, utf8mb4 should be used instead of utf8. + * + * @since 4.6.0 + * @access public + * + * @param string $charset The character set to check. + * @param string $collate The collation to check. + * @return array The most appropriate character set and collation to use. + */ + public function determine_charset( $charset, $collate ) { if ( ( $this->use_mysqli && ! ( $this->dbh instanceof mysqli ) ) || empty( $this->dbh ) ) { - return; + return compact( 'charset', 'collate' ); + } + + if ( 'utf8' === $charset && $this->has_cap( 'utf8mb4' ) ) { + $charset = 'utf8mb4'; } - if ( 'utf8' === $this->charset && $this->has_cap( 'utf8mb4' ) ) { - $this->charset = 'utf8mb4'; + if ( 'utf8mb4' === $charset ) { + // _general_ is outdated, so we can upgrade it to _unicode_, instead. + if ( ! $collate || 'utf8_general_ci' === $collate ) { + $collate = 'utf8mb4_unicode_ci'; + } else { + $collate = str_replace( 'utf8_', 'utf8mb4_', $collate ); + } } - if ( 'utf8mb4' === $this->charset && ( ! $this->collate || stripos( $this->collate, 'utf8_' ) === 0 ) ) { - $this->collate = 'utf8mb4_unicode_ci'; + // _unicode_520_ is a better collation, we should use that when it's available. + if ( $this->has_cap( 'utf8mb4_520' ) && 'utf8mb4_unicode_ci' === $collate ) { + $collate = 'utf8mb4_unicode_520_ci'; } + + return compact( 'charset', 'collate' ); } /** @@ -766,10 +811,14 @@ class wpdb { if ( ! isset( $collate ) ) $collate = $this->collate; if ( $this->has_cap( 'collation' ) && ! empty( $charset ) ) { + $set_charset_succeeded = true; + if ( $this->use_mysqli ) { if ( function_exists( 'mysqli_set_charset' ) && $this->has_cap( 'set_charset' ) ) { - mysqli_set_charset( $dbh, $charset ); - } else { + $set_charset_succeeded = mysqli_set_charset( $dbh, $charset ); + } + + if ( $set_charset_succeeded ) { $query = $this->prepare( 'SET NAMES %s', $charset ); if ( ! empty( $collate ) ) $query .= $this->prepare( ' COLLATE %s', $collate ); @@ -777,8 +826,9 @@ class wpdb { } } else { if ( function_exists( 'mysql_set_charset' ) && $this->has_cap( 'set_charset' ) ) { - mysql_set_charset( $charset, $dbh ); - } else { + $set_charset_succeeded = mysql_set_charset( $charset, $dbh ); + } + if ( $set_charset_succeeded ) { $query = $this->prepare( 'SET NAMES %s', $charset ); if ( ! empty( $collate ) ) $query .= $this->prepare( ' COLLATE %s', $collate ); @@ -830,7 +880,7 @@ class wpdb { $modes = array_change_key_case( $modes, CASE_UPPER ); /** - * Filter the list of incompatible SQL modes to exclude. + * Filters the list of incompatible SQL modes to exclude. * * @since 3.9.0 * @@ -838,7 +888,7 @@ class wpdb { */ $incompatible_modes = (array) apply_filters( 'incompatible_sql_modes', $this->incompatible_modes ); - foreach( $modes as $i => $mode ) { + foreach ( $modes as $i => $mode ) { if ( in_array( $mode, $incompatible_modes ) ) { unset( $modes[ $i ] ); } @@ -858,8 +908,8 @@ class wpdb { * * @since 2.5.0 * - * @param string $prefix Alphanumeric name for the new prefix. - * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not. + * @param string $prefix Alphanumeric name for the new prefix. + * @param bool $set_table_names Optional. Whether the table names, e.g. wpdb::$posts, should be updated or not. * @return string|WP_Error Old prefix or WP_Error on error */ public function set_prefix( $prefix, $set_table_names = true ) { @@ -897,6 +947,7 @@ class wpdb { * * @since 3.0.0 * @access public + * * @param int $blog_id * @param int $site_id Optional. * @return int previous blog id @@ -961,10 +1012,10 @@ class wpdb { * @uses wpdb::$global_tables * @uses wpdb::$ms_global_tables * - * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all. - * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog - * prefix is requested, then the custom users and usermeta tables will be mapped. - * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested. + * @param string $scope Optional. Can be all, global, ms_global, blog, or old tables. Defaults to all. + * @param bool $prefix Optional. Whether to include table prefixes. Default true. If blog + * prefix is requested, then the custom users and usermeta tables will be mapped. + * @param int $blog_id Optional. The blog_id to prefix. Defaults to wpdb::$blogid. Used only when prefix is requested. * @return array Table names. When a prefix is requested, the key is the unprefixed table name. */ public function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) { @@ -1024,33 +1075,57 @@ class wpdb { * * @since 0.71 * - * @param string $db MySQL database name - * @param resource $dbh Optional link identifier. - * @return null Always null. + * @param string $db MySQL database name + * @param resource|null $dbh Optional link identifier. */ public function select( $db, $dbh = null ) { if ( is_null($dbh) ) $dbh = $this->dbh; if ( $this->use_mysqli ) { - $success = @mysqli_select_db( $dbh, $db ); + $success = mysqli_select_db( $dbh, $db ); } else { - $success = @mysql_select_db( $db, $dbh ); + $success = mysql_select_db( $db, $dbh ); } if ( ! $success ) { $this->ready = false; if ( ! did_action( 'template_redirect' ) ) { wp_load_translations_early(); - $this->bail( sprintf( __( '

Can’t select database

-

We were able to connect to the database server (which means your username and password is okay) but not able to select the %1$s database.

- -

If you don\'t know how to set up a database you should contact your host. If all else fails you may find help at the WordPress Support Forums.

' ), htmlspecialchars( $db, ENT_QUOTES ), htmlspecialchars( $this->dbuser, ENT_QUOTES ) ), 'db_select_fail' ); + + $message = '

' . __( 'Can’t select database' ) . "

\n"; + + $message .= '

' . sprintf( + /* translators: %s: database name */ + __( 'We were able to connect to the database server (which means your username and password is okay) but not able to select the %s database.' ), + '' . htmlspecialchars( $db, ENT_QUOTES ) . '' + ) . "

\n"; + + $message .= "\n"; + + $message .= '

' . sprintf( + /* translators: %s: support forums URL */ + __( 'If you don’t know how to set up a database you should contact your host. If all else fails you may find help at the WordPress Support Forums.' ), + __( 'https://wordpress.org/support/' ) + ) . "

\n"; + + $this->bail( $message, 'db_select_fail' ); } - return; } } @@ -1060,7 +1135,7 @@ class wpdb { * Use esc_sql() or wpdb::prepare() instead. * * @since 2.8.0 - * @deprecated 3.6.0 + * @deprecated 3.6.0 Use wpdb::prepare() * @see wpdb::prepare * @see esc_sql() * @access private @@ -1070,7 +1145,7 @@ class wpdb { */ function _weak_escape( $string ) { if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) ) - _deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' ); + _deprecated_function( __METHOD__, '3.6.0', 'wpdb::prepare() or esc_sql()' ); return addslashes( $string ); } @@ -1096,9 +1171,10 @@ class wpdb { $class = get_class( $this ); if ( function_exists( '__' ) ) { - _doing_it_wrong( $class, sprintf( __( '%s must set a database connection for use with escaping.' ), $class ), E_USER_NOTICE ); + /* translators: %s: database access abstraction class, usually wpdb or a class extending wpdb */ + _doing_it_wrong( $class, sprintf( __( '%s must set a database connection for use with escaping.' ), $class ), '3.6.0' ); } else { - _doing_it_wrong( $class, sprintf( '%s must set a database connection for use with escaping.', $class ), E_USER_NOTICE ); + _doing_it_wrong( $class, sprintf( '%s must set a database connection for use with escaping.', $class ), '3.6.0' ); } return addslashes( $string ); } @@ -1134,7 +1210,7 @@ class wpdb { * Use esc_sql() or wpdb::prepare() instead. * * @since 0.71 - * @deprecated 3.6.0 + * @deprecated 3.6.0 Use wpdb::prepare() * @see wpdb::prepare() * @see esc_sql() * @@ -1143,7 +1219,7 @@ class wpdb { */ public function escape( $data ) { if ( func_num_args() === 1 && function_exists( '_deprecated_function' ) ) - _deprecated_function( __METHOD__, '3.6', 'wpdb::prepare() or esc_sql()' ); + _deprecated_function( __METHOD__, '3.6.0', 'wpdb::prepare() or esc_sql()' ); if ( is_array( $data ) ) { foreach ( $data as $k => $v ) { if ( is_array( $v ) ) @@ -1162,9 +1238,10 @@ class wpdb { * Escapes content by reference for insertion into the database, for security * * @uses wpdb::_real_escape() + * * @since 2.3.0 + * * @param string $string to escape - * @return void */ public function escape_by_ref( &$string ) { if ( ! is_float( $string ) ) @@ -1187,24 +1264,23 @@ class wpdb { * Does not support sign, padding, alignment, width or precision specifiers. * Does not support argument numbering/swapping. * - * May be called like {@link http://php.net/sprintf sprintf()} or like {@link http://php.net/vsprintf vsprintf()}. + * May be called like {@link https://secure.php.net/sprintf sprintf()} or like {@link https://secure.php.net/vsprintf vsprintf()}. * * Both %d and %s should be left unquoted in the query string. * * wpdb::prepare( "SELECT * FROM `table` WHERE `column` = %s AND `field` = %d", 'foo', 1337 ) * wpdb::prepare( "SELECT DATE_FORMAT(`field`, '%%c') FROM `table` WHERE `column` = %s", 'foo' ); * - * @link http://php.net/sprintf Description of syntax. + * @link https://secure.php.net/sprintf Description of syntax. * @since 2.3.0 * - * @param string $query Query statement with sprintf()-like placeholders - * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like - * {@link http://php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if - * being called like {@link http://php.net/sprintf sprintf()}. - * @param mixed $args,... further variables to substitute into the query's placeholders if being called like - * {@link http://php.net/sprintf sprintf()}. - * @return null|false|string Sanitized query string, null if there is no query, false if there is an error and string - * if there was something to prepare + * @param string $query Query statement with sprintf()-like placeholders + * @param array|mixed $args The array of variables to substitute into the query's placeholders if being called like + * {@link https://secure.php.net/vsprintf vsprintf()}, or the first variable to substitute into the query's placeholders if + * being called like {@link https://secure.php.net/sprintf sprintf()}. + * @param mixed $args,... further variables to substitute into the query's placeholders if being called like + * {@link https://secure.php.net/sprintf sprintf()}. + * @return string|void Sanitized query string, if there is a query to prepare. */ public function prepare( $query, $args ) { if ( is_null( $query ) ) @@ -1212,7 +1288,7 @@ class wpdb { // This is not meant to be foolproof -- but it will catch obviously incorrect usage. if ( strpos( $query, '%' ) === false ) { - _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9' ); + _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9.0' ); } $args = func_get_args(); @@ -1234,13 +1310,15 @@ class wpdb { * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security. * * Example Prepared Statement: - * $wild = '%'; - * $find = 'only 43% of planets'; - * $like = $wild . $wpdb->esc_like( $find ) . $wild; - * $sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like ); + * + * $wild = '%'; + * $find = 'only 43% of planets'; + * $like = $wild . $wpdb->esc_like( $find ) . $wild; + * $sql = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE '%s'", $like ); * * Example Escape Chain: - * $sql = esc_sql( $wpdb->esc_like( $input ) ); + * + * $sql = esc_sql( $wpdb->esc_like( $input ) ); * * @since 4.0.0 * @access public @@ -1261,7 +1339,7 @@ class wpdb { * @global array $EZSQL_ERROR Stores error information of query and error string * * @param string $str The error to display - * @return false|null False if the showing of errors is disabled. + * @return false|void False if the showing of errors is disabled. */ public function print_error( $str = '' ) { global $EZSQL_ERROR; @@ -1293,19 +1371,29 @@ class wpdb { // If there is an error then take note of it if ( is_multisite() ) { - $msg = "WordPress database error: [$str]\n{$this->last_query}\n"; - if ( defined( 'ERRORLOGFILE' ) ) + $msg = sprintf( + "%s [%s]\n%s\n", + __( 'WordPress database error:' ), + $str, + $this->last_query + ); + + if ( defined( 'ERRORLOGFILE' ) ) { error_log( $msg, 3, ERRORLOGFILE ); - if ( defined( 'DIEONDBERROR' ) ) + } + if ( defined( 'DIEONDBERROR' ) ) { wp_die( $msg ); + } } else { $str = htmlspecialchars( $str, ENT_QUOTES ); $query = htmlspecialchars( $this->last_query, ENT_QUOTES ); - print "
-

WordPress database error: [$str]
- $query

-
"; + printf( + '

%s [%s]
%s

', + __( 'WordPress database error:' ), + $str, + $query + ); } } @@ -1366,7 +1454,6 @@ class wpdb { * Kill cached query results. * * @since 0.71 - * @return void */ public function flush() { $this->last_result = array(); @@ -1403,10 +1490,9 @@ class wpdb { * @since 3.9.0 $allow_bail parameter added. * * @param bool $allow_bail Optional. Allows the function to bail. Default true. - * @return null|bool True with a successful connection, false on failure. + * @return bool True with a successful connection, false on failure. */ public function db_connect( $allow_bail = true ) { - $this->is_mysql = true; /* @@ -1465,7 +1551,7 @@ class wpdb { if ( $attempt_fallback ) { $this->use_mysqli = false; - $this->db_connect(); + return $this->db_connect( $allow_bail ); } } } else { @@ -1485,16 +1571,28 @@ class wpdb { die(); } - $this->bail( sprintf( __( " -

Error establishing a database connection

-

This either means that the username and password information in your wp-config.php file is incorrect or we can't contact the database server at %s. This could mean your host's database server is down.

- -

If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the WordPress Support Forums.

-" ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' ); + $message = '

' . __( 'Error establishing a database connection' ) . "

\n"; + + $message .= '

' . sprintf( + /* translators: 1: wp-config.php. 2: database host */ + __( 'This either means that the username and password information in your %1$s file is incorrect or we can’t contact the database server at %2$s. This could mean your host’s database server is down.' ), + 'wp-config.php', + '' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '' + ) . "

\n"; + + $message .= "\n"; + + $message .= '

' . sprintf( + /* translators: %s: support forums URL */ + __( 'If you’re unsure what these terms mean you should probably contact your host. If you still need help you can always visit the WordPress Support Forums.' ), + __( 'https://wordpress.org/support/' ) + ) . "

\n"; + + $this->bail( $message, 'db_connect_fail' ); return false; } elseif ( $this->dbh ) { @@ -1517,10 +1615,10 @@ class wpdb { } /** - * Check that the connection to the database is still up. If not, try to reconnect. + * Checks that the connection to the database is still up. If not, try to reconnect. * * If this function is unable to reconnect, it will forcibly die, or if after the - * the template_redirect hook has been fired, return false instead. + * the {@see 'template_redirect'} hook has been fired, return false instead. * * If $allow_bail is false, the lack of database connection will need * to be handled manually. @@ -1528,15 +1626,15 @@ class wpdb { * @since 3.9.0 * * @param bool $allow_bail Optional. Allows the function to bail. Default true. - * @return bool|null True if the connection is up. + * @return bool|void True if the connection is up. */ public function check_connection( $allow_bail = true ) { if ( $this->use_mysqli ) { - if ( @mysqli_ping( $this->dbh ) ) { + if ( ! empty( $this->dbh ) && mysqli_ping( $this->dbh ) ) { return true; } } else { - if ( @mysql_ping( $this->dbh ) ) { + if ( ! empty( $this->dbh ) && mysql_ping( $this->dbh ) ) { return true; } } @@ -1577,16 +1675,29 @@ class wpdb { return false; } + wp_load_translations_early(); + + $message = '

' . __( 'Error reconnecting to the database' ) . "

\n"; + + $message .= '

' . sprintf( + /* translators: %s: database host */ + __( 'This means that we lost contact with the database server at %s. This could mean your host’s database server is down.' ), + '' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '' + ) . "

\n"; + + $message .= "\n"; + + $message .= '

' . sprintf( + /* translators: %s: support forums URL */ + __( 'If you’re unsure what these terms mean you should probably contact your host. If you still need help you can always visit the WordPress Support Forums.' ), + __( 'https://wordpress.org/support/' ) + ) . "

\n"; + // We weren't able to reconnect, so we better bail. - $this->bail( sprintf( ( " -

Error reconnecting to the database

-

This means that we lost contact with the database server at %s. This could mean your host's database server is down.

- -

If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the WordPress Support Forums.

-" ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' ); + $this->bail( $message, 'db_connect_fail' ); // Call dead_db() if bail didn't die, because this database is no more. It has ceased to be (at least temporarily). dead_db(); @@ -1609,7 +1720,7 @@ class wpdb { } /** - * Filter the database query. + * Filters the database query. * * Some queries are made before the plugins have been loaded, * and thus cannot be filtered with this method. @@ -1639,18 +1750,28 @@ class wpdb { $this->check_current_query = true; - // Keep track of the last query for debug.. + // Keep track of the last query for debug. $this->last_query = $query; $this->_do_query( $query ); - // MySQL server has gone away, try to reconnect + // MySQL server has gone away, try to reconnect. $mysql_errno = 0; if ( ! empty( $this->dbh ) ) { if ( $this->use_mysqli ) { - $mysql_errno = mysqli_errno( $this->dbh ); + if ( $this->dbh instanceof mysqli ) { + $mysql_errno = mysqli_errno( $this->dbh ); + } else { + // $dbh is defined, but isn't a real connection. + // Something has gone horribly wrong, let's try a reconnect. + $mysql_errno = 2006; + } } else { - $mysql_errno = mysql_errno( $this->dbh ); + if ( is_resource( $this->dbh ) ) { + $mysql_errno = mysql_errno( $this->dbh ); + } else { + $mysql_errno = 2006; + } } } @@ -1663,11 +1784,19 @@ class wpdb { } } - // If there is an error then take note of it.. + // If there is an error then take note of it. if ( $this->use_mysqli ) { - $this->last_error = mysqli_error( $this->dbh ); + if ( $this->dbh instanceof mysqli ) { + $this->last_error = mysqli_error( $this->dbh ); + } else { + $this->last_error = __( 'Unable to retrieve the error message from MySQL' ); + } } else { - $this->last_error = mysql_error( $this->dbh ); + if ( is_resource( $this->dbh ) ) { + $this->last_error = mysql_error( $this->dbh ); + } else { + $this->last_error = __( 'Unable to retrieve the error message from MySQL' ); + } } if ( $this->last_error ) { @@ -1700,12 +1829,12 @@ class wpdb { } else { $num_rows = 0; if ( $this->use_mysqli && $this->result instanceof mysqli_result ) { - while ( $row = @mysqli_fetch_object( $this->result ) ) { + while ( $row = mysqli_fetch_object( $this->result ) ) { $this->last_result[$num_rows] = $row; $num_rows++; } } elseif ( is_resource( $this->result ) ) { - while ( $row = @mysql_fetch_object( $this->result ) ) { + while ( $row = mysql_fetch_object( $this->result ) ) { $this->last_result[$num_rows] = $row; $num_rows++; } @@ -1735,10 +1864,10 @@ class wpdb { $this->timer_start(); } - if ( $this->use_mysqli ) { - $this->result = @mysqli_query( $this->dbh, $query ); - } else { - $this->result = @mysql_query( $query, $this->dbh ); + if ( ! empty( $this->dbh ) && $this->use_mysqli ) { + $this->result = mysqli_query( $this->dbh, $query ); + } elseif ( ! empty( $this->dbh ) ) { + $this->result = mysql_query( $query, $this->dbh ); } $this->num_queries++; @@ -1758,10 +1887,14 @@ class wpdb { * @see wpdb::$field_types * @see wp_set_wpdb_vars() * - * @param string $table table name - * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). - * @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. - * 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. + * @param string $table Table name + * @param array $data Data to insert (in column => value pairs). + * Both $data columns and $data values should be "raw" (neither should be SQL escaped). + * Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case. + * @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. + * 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. * @return int|false The number of rows inserted, or false on error. */ public function insert( $table, $data, $format = null ) { @@ -1779,10 +1912,14 @@ class wpdb { * @see wpdb::$field_types * @see wp_set_wpdb_vars() * - * @param string $table table name - * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). - * @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. - * 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. + * @param string $table Table name + * @param array $data Data to insert (in column => value pairs). + * Both $data columns and $data values should be "raw" (neither should be SQL escaped). + * Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case. + * @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. + * 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. * @return int|false The number of rows affected, or false on error. */ public function replace( $table, $data, $format = null ) { @@ -1800,11 +1937,15 @@ class wpdb { * @see wpdb::$field_types * @see wp_set_wpdb_vars() * - * @param string $table table name - * @param array $data Data to insert (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). - * @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. - * 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. - * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT. + * @param string $table Table name + * @param array $data Data to insert (in column => value pairs). + * Both $data columns and $data values should be "raw" (neither should be SQL escaped). + * Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case. + * @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. + * 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. + * @param string $type Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT. * @return int|false The number of rows affected, or false on error. */ function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) { @@ -1821,6 +1962,11 @@ class wpdb { $formats = $values = array(); foreach ( $data as $value ) { + if ( is_null( $value['value'] ) ) { + $formats[] = 'NULL'; + continue; + } + $formats[] = $value['format']; $values[] = $value['value']; } @@ -1845,12 +1991,23 @@ class wpdb { * @see wpdb::$field_types * @see wp_set_wpdb_vars() * - * @param string $table table name - * @param array $data Data to update (in column => value pairs). Both $data columns and $data values should be "raw" (neither should be SQL escaped). - * @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". - * @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. - * 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. - * @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. + * @param string $table Table name + * @param array $data Data to update (in column => value pairs). + * Both $data columns and $data values should be "raw" (neither should be SQL escaped). + * Sending a null value will cause the column to be set to NULL - the corresponding + * format is ignored in this case. + * @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". + * Sending a null value will create an IS NULL comparison - the corresponding format will be ignored in this case. + * @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. + * 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. + * @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. * @return int|false The number of rows updated, or false on error. */ public function update( $table, $data, $where, $format = null, $where_format = null ) { @@ -1869,10 +2026,20 @@ class wpdb { $fields = $conditions = $values = array(); foreach ( $data as $field => $value ) { + if ( is_null( $value['value'] ) ) { + $fields[] = "`$field` = NULL"; + continue; + } + $fields[] = "`$field` = " . $value['format']; $values[] = $value['value']; } foreach ( $where as $field => $value ) { + if ( is_null( $value['value'] ) ) { + $conditions[] = "`$field` IS NULL"; + continue; + } + $conditions[] = "`$field` = " . $value['format']; $values[] = $value['value']; } @@ -1897,9 +2064,15 @@ class wpdb { * @see wpdb::$field_types * @see wp_set_wpdb_vars() * - * @param string $table table name - * @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". - * @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. + * @param string $table Table name + * @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". + * Sending a null value will create an IS NULL comparison - the corresponding format will be ignored in this case. + * @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. * @return int|false The number of rows updated, or false on error. */ public function delete( $table, $where, $where_format = null ) { @@ -1914,6 +2087,11 @@ class wpdb { $conditions = $values = array(); foreach ( $where as $field => $value ) { + if ( is_null( $value['value'] ) ) { + $conditions[] = "`$field` IS NULL"; + continue; + } + $conditions[] = "`$field` = " . $value['format']; $values[] = $value['value']; } @@ -1941,7 +2119,7 @@ class wpdb { * @param string $table Table name. * @param array $data Field/value pair. * @param mixed $format Format for each field. - * @return array|bool Returns an array of fields that contain paired values + * @return array|false Returns an array of fields that contain paired values * and formats. Returns false for invalid values. */ protected function process_fields( $table, $data, $format ) { @@ -2013,13 +2191,15 @@ class wpdb { * * @param array $data As it comes from the wpdb::process_field_formats() method. * @param string $table Table name. - * @return The same array as $data with additional 'charset' keys. + * @return array|false The same array as $data with additional 'charset' keys. */ protected function process_field_charsets( $data, $table ) { foreach ( $data as $field => $value ) { if ( '%d' === $value['format'] || '%f' === $value['format'] ) { - // We can skip this field if we know it isn't a string. - // This checks %d/%f versus ! %s because it's sprintf() could take more. + /* + * We can skip this field if we know it isn't a string. + * This checks %d/%f versus ! %s because its sprintf() could take more. + */ $value['charset'] = false; } else { $value['charset'] = $this->get_col_charset( $table, $field ); @@ -2042,14 +2222,16 @@ class wpdb { * * @param array $data As it comes from the wpdb::process_field_charsets() method. * @param string $table Table name. - * @return array|False The same array as $data with additional 'length' keys, or false if + * @return array|false The same array as $data with additional 'length' keys, or false if * any of the values were too long for their corresponding field. */ protected function process_field_lengths( $data, $table ) { foreach ( $data as $field => $value ) { if ( '%d' === $value['format'] || '%f' === $value['format'] ) { - // We can skip this field if we know it isn't a string. - // This checks %d/%f versus ! %s because it's sprintf() could take more. + /* + * We can skip this field if we know it isn't a string. + * This checks %d/%f versus ! %s because its sprintf() could take more. + */ $value['length'] = false; } else { $value['length'] = $this->get_col_length( $table, $field ); @@ -2074,14 +2256,14 @@ class wpdb { * @since 0.71 * * @param string|null $query Optional. SQL query. Defaults to null, use the result from the previous query. - * @param int $x Optional. Column of value to return. Indexed from 0. - * @param int $y Optional. Row of value to return. Indexed from 0. + * @param int $x Optional. Column of value to return. Indexed from 0. + * @param int $y Optional. Row of value to return. Indexed from 0. * @return string|null Database query result (as string), or null on failure */ public function get_var( $query = null, $x = 0, $y = 0 ) { $this->func_call = "\$db->get_var(\"$query\", $x, $y)"; - if ( $this->check_safe_collation( $query ) ) { + if ( $this->check_current_query && $this->check_safe_collation( $query ) ) { $this->check_current_query = false; } @@ -2105,16 +2287,18 @@ class wpdb { * * @since 0.71 * - * @param string|null $query SQL query. - * @param string $output Optional. one of ARRAY_A | ARRAY_N | OBJECT constants. Return an associative array (column => value, ...), - * a numerically indexed array (0 => value, ...) or an object ( ->column = value ), respectively. - * @param int $y Optional. Row to return. Indexed from 0. - * @return mixed Database query result in format specified by $output or null on failure + * @param string|null $query SQL query. + * @param string $output Optional. one of ARRAY_A | ARRAY_N | OBJECT constants. + * Return an associative array (column => value, ...), + * a numerically indexed array (0 => value, ...) or + * an object ( ->column = value ), respectively. + * @param int $y Optional. Row to return. Indexed from 0. + * @return array|object|null|void Database query result in format specified by $output or null on failure */ public function get_row( $query = null, $output = OBJECT, $y = 0 ) { $this->func_call = "\$db->get_row(\"$query\",$output,$y)"; - if ( $this->check_safe_collation( $query ) ) { + if ( $this->check_current_query && $this->check_safe_collation( $query ) ) { $this->check_current_query = false; } @@ -2151,11 +2335,11 @@ class wpdb { * @since 0.71 * * @param string|null $query Optional. SQL query. Defaults to previous query. - * @param int $x Optional. Column to return. Indexed from 0. + * @param int $x Optional. Column to return. Indexed from 0. * @return array Database query result. Array indexed from 0 by SQL result row number. */ public function get_col( $query = null , $x = 0 ) { - if ( $this->check_safe_collation( $query ) ) { + if ( $this->check_current_query && $this->check_safe_collation( $query ) ) { $this->check_current_query = false; } @@ -2178,16 +2362,18 @@ class wpdb { * * @since 0.71 * - * @param string $query SQL query. - * @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. - * Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively. - * 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. - * @return mixed Database query results + * @param string $query SQL query. + * @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. + * Each row is an associative array (column => value, ...), a numerically indexed array (0 => value, ...), or an object. ( ->column = value ), respectively. + * 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. + * @return array|object|null Database query results */ public function get_results( $query = null, $output = OBJECT ) { $this->func_call = "\$db->get_results(\"$query\", $output)"; - if ( $this->check_safe_collation( $query ) ) { + if ( $this->check_current_query && $this->check_safe_collation( $query ) ) { $this->check_current_query = false; } @@ -2214,7 +2400,7 @@ class wpdb { } elseif ( $output == ARRAY_A || $output == ARRAY_N ) { // Return an integer-keyed array of... if ( $this->last_result ) { - foreach( (array) $this->last_result as $row ) { + foreach ( (array) $this->last_result as $row ) { if ( $output == ARRAY_N ) { // ...integer-keyed row arrays $new_array[] = array_values( get_object_vars( $row ) ); @@ -2245,7 +2431,7 @@ class wpdb { $tablekey = strtolower( $table ); /** - * Filter the table charset value before the DB is checked. + * Filters the table charset value before the DB is checked. * * Passing a non-null value to the filter will effectively short-circuit * checking the DB for the charset, returning that value instead. @@ -2341,15 +2527,15 @@ class wpdb { * * @param string $table Table name. * @param string $column Column name. - * @return mixed Column character set as a string. False if the column has no - * character set. WP_Error object if there was an error. + * @return string|false|WP_Error Column character set as a string. False if the column has no + * character set. WP_Error object if there was an error. */ public function get_col_charset( $table, $column ) { $tablekey = strtolower( $table ); $columnkey = strtolower( $column ); /** - * Filter the column charset value before the DB is checked. + * Filters the column charset value before the DB is checked. * * Passing a non-null value to the filter will short-circuit * checking the DB for the charset, returning that value instead. @@ -2366,7 +2552,7 @@ class wpdb { } // Skip this entirely if this isn't a MySQL database. - if ( false === $this->is_mysql ) { + if ( empty( $this->is_mysql ) ) { return false; } @@ -2406,16 +2592,16 @@ class wpdb { * * @param string $table Table name. * @param string $column Column name. - * @return mixed array( 'length' => (int), 'type' => 'byte' | 'char' ) - * false if the column has no length (for example, numeric column) - * WP_Error object if there was an error. + * @return array|false|WP_Error array( 'length' => (int), 'type' => 'byte' | 'char' ) + * false if the column has no length (for example, numeric column) + * WP_Error object if there was an error. */ public function get_col_length( $table, $column ) { $tablekey = strtolower( $table ); $columnkey = strtolower( $column ); // Skip this entirely if this isn't a MySQL database. - if ( false === $this->is_mysql ) { + if ( empty( $this->is_mysql ) ) { return false; } @@ -2447,47 +2633,45 @@ class wpdb { 'type' => 'char', 'length' => (int) $length, ); - break; + case 'binary': case 'varbinary': return array( 'type' => 'byte', 'length' => (int) $length, ); - break; + case 'tinyblob': case 'tinytext': return array( 'type' => 'byte', 'length' => 255, // 2^8 - 1 ); - break; + case 'blob': case 'text': return array( 'type' => 'byte', 'length' => 65535, // 2^16 - 1 ); - break; + case 'mediumblob': case 'mediumtext': return array( 'type' => 'byte', 'length' => 16777215, // 2^24 - 1 ); - break; + case 'longblob': case 'longtext': return array( 'type' => 'byte', 'length' => 4294967295, // 2^32 - 1 ); - break; + default: return false; } - - return false; } /** @@ -2559,7 +2743,7 @@ class wpdb { } // If any of the columns don't have one of these collations, it needs more sanity checking. - foreach( $this->col_meta[ $table ] as $col ) { + foreach ( $this->col_meta[ $table ] as $col ) { if ( empty( $col->Collation ) ) { continue; } @@ -2686,11 +2870,21 @@ class wpdb { $charset = $value['charset']; } + if ( $this->charset ) { + $connection_charset = $this->charset; + } else { + if ( $this->use_mysqli ) { + $connection_charset = mysqli_character_set_name( $this->dbh ); + } else { + $connection_charset = mysql_client_encoding(); + } + } + if ( is_array( $value['length'] ) ) { - $queries[ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING $charset ), %.0f ) USING {$this->charset} )", $value['value'], $value['length']['length'] ); + $queries[ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING $charset ), %.0f ) USING $connection_charset )", $value['value'], $value['length']['length'] ); } else if ( 'binary' !== $charset ) { // If we don't have a length, there's no need to convert binary - it will always return the same result. - $queries[ $col ] = $this->prepare( "CONVERT( CONVERT( %s USING $charset ) USING {$this->charset} )", $value['value'] ); + $queries[ $col ] = $this->prepare( "CONVERT( CONVERT( %s USING $charset ) USING $connection_charset )", $value['value'] ); } unset( $data[ $col ]['db'] ); @@ -2713,7 +2907,9 @@ class wpdb { } foreach ( array_keys( $data ) as $column ) { - $data[ $column ]['value'] = $row["x_$column"]; + if ( isset( $row["x_$column"] ) ) { + $data[ $column ]['value'] = $row["x_$column"]; + } } } @@ -2833,7 +3029,7 @@ class wpdb { . '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?' . '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?' . '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:\s+FROM)?' - . ')\s+((?:[0-9a-zA-Z$_.`]|[\xC2-\xDF][\x80-\xBF])+)/is', $query, $maybe ) ) { + . ')\s+((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)/is', $query, $maybe ) ) { return str_replace( '`', '', $maybe[1] ); } @@ -2841,7 +3037,7 @@ class wpdb { if ( preg_match( '/^\s*(?:' . 'SHOW\s+TABLE\s+STATUS.+(?:LIKE\s+|WHERE\s+Name\s*=\s*)' . '|SHOW\s+(?:FULL\s+)?TABLES.+(?:LIKE\s+|WHERE\s+Name\s*=\s*)' - . ')\W((?:[0-9a-zA-Z$_.`]|[\xC2-\xDF][\x80-\xBF])+)\W/is', $query, $maybe ) ) { + . ')\W((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)\W/is', $query, $maybe ) ) { return str_replace( '`', '', $maybe[1] ); } @@ -2860,7 +3056,7 @@ class wpdb { . '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE' . '|(?:GRANT|REVOKE).*ON\s+TABLE' . '|SHOW\s+(?:.*FROM|.*TABLE)' - . ')\s+\(*\s*((?:[0-9a-zA-Z$_.`]|[\xC2-\xDF][\x80-\xBF])+)\s*\)*/is', $query, $maybe ) ) { + . ')\s+\(*\s*((?:[0-9a-zA-Z$_.`-]|[\xC2-\xDF][\x80-\xBF])+)\s*\)*/is', $query, $maybe ) ) { return str_replace( '`', '', $maybe[1] ); } @@ -2879,12 +3075,14 @@ class wpdb { return; if ( $this->use_mysqli ) { - for ( $i = 0; $i < @mysqli_num_fields( $this->result ); $i++ ) { - $this->col_info[ $i ] = @mysqli_fetch_field( $this->result ); + $num_fields = mysqli_num_fields( $this->result ); + for ( $i = 0; $i < $num_fields; $i++ ) { + $this->col_info[ $i ] = mysqli_fetch_field( $this->result ); } } else { - for ( $i = 0; $i < @mysql_num_fields( $this->result ); $i++ ) { - $this->col_info[ $i ] = @mysql_fetch_field( $this->result, $i ); + $num_fields = mysql_num_fields( $this->result ); + for ( $i = 0; $i < $num_fields; $i++ ) { + $this->col_info[ $i ] = mysql_fetch_field( $this->result, $i ); } } } @@ -2894,8 +3092,8 @@ class wpdb { * * @since 0.71 * - * @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 - * @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 + * @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 + * @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 * @return mixed Column Results */ public function get_col_info( $info_type = 'name', $col_offset = -1 ) { @@ -2905,7 +3103,7 @@ class wpdb { if ( $col_offset == -1 ) { $i = 0; $new_array = array(); - foreach( (array) $this->col_info as $col ) { + foreach ( (array) $this->col_info as $col ) { $new_array[$i] = $col->{$info_type}; $i++; } @@ -2921,7 +3119,7 @@ class wpdb { * * @since 1.5.0 * - * @return bool + * @return true */ public function timer_start() { $this->time_start = microtime( true ); @@ -2946,29 +3144,61 @@ class wpdb { * * @since 1.5.0 * - * @param string $message The Error message + * @param string $message The Error message * @param string $error_code Optional. A Computer readable string to identify the error. * @return false|void */ public function bail( $message, $error_code = '500' ) { if ( !$this->show_errors ) { - if ( class_exists( 'WP_Error' ) ) + if ( class_exists( 'WP_Error', false ) ) { $this->error = new WP_Error($error_code, $message); - else + } else { $this->error = $message; + } return false; } wp_die($message); } + + /** + * Closes the current database connection. + * + * @since 4.5.0 + * @access public + * + * @return bool True if the connection was successfully closed, false if it wasn't, + * or the connection doesn't exist. + */ + public function close() { + if ( ! $this->dbh ) { + return false; + } + + if ( $this->use_mysqli ) { + $closed = mysqli_close( $this->dbh ); + } else { + $closed = mysql_close( $this->dbh ); + } + + if ( $closed ) { + $this->dbh = null; + $this->ready = false; + $this->has_connected = false; + } + + return $closed; + } + /** * Whether MySQL database is at least the required minimum version. * * @since 2.5.0 - * @uses $wp_version - * @uses $required_mysql_version * - * @return WP_Error + * @global string $wp_version + * @global string $required_mysql_version + * + * @return WP_Error|void */ public function check_database_version() { global $wp_version, $required_mysql_version; @@ -2982,14 +3212,15 @@ class wpdb { * * Called when WordPress is generating the table scheme. * + * Use `wpdb::has_cap( 'collation' )`. + * * @since 2.5.0 - * @deprecated 3.5.0 - * @deprecated Use wpdb::has_cap( 'collation' ) + * @deprecated 3.5.0 Use wpdb::has_cap() * * @return bool True if collation is supported, false if version does not */ public function supports_collation() { - _deprecated_function( __FUNCTION__, '3.5', 'wpdb::has_cap( \'collation\' )' ); + _deprecated_function( __FUNCTION__, '3.5.0', 'wpdb::has_cap( \'collation\' )' ); return $this->has_cap( 'collation' ); } @@ -3015,14 +3246,15 @@ class wpdb { * Determine if a database supports a particular feature. * * @since 2.7.0 - * @since 4.1.0 Support was added for the 'utf8mb4' feature. + * @since 4.1.0 Added support for the 'utf8mb4' feature. + * @since 4.6.0 Added support for the 'utf8mb4_520' feature. * * @see wpdb::db_version() * * @param string $db_cap The feature to check for. Accepts 'collation', * 'group_concat', 'subqueries', 'set_charset', * or 'utf8mb4'. - * @return bool Whether the database feature is supported, false otherwise. + * @return int|false Whether the database feature is supported, false otherwise. */ public function has_cap( $db_cap ) { $version = $this->db_version(); @@ -3054,6 +3286,8 @@ class wpdb { } else { return version_compare( $client_version, '5.5.3', '>=' ); } + case 'utf8mb4_520' : // @since 4.6.0 + return version_compare( $version, '5.6', '>=' ); } return false; @@ -3067,14 +3301,14 @@ class wpdb { * * @since 2.5.0 * - * @return string The name of the calling function + * @return string|array The name of the calling function */ public function get_caller() { return wp_debug_backtrace_summary( __CLASS__ ); } /** - * The database version number. + * Retrieves the MySQL server version. * * @since 2.7.0 *