X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/899389d1e4043331309c0433543419258b230b60..3d39054f012aefe514b3f5509e32f09fc4feda44:/wp-includes/wp-db.php diff --git a/wp-includes/wp-db.php b/wp-includes/wp-db.php index e749f517..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,33 +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; } - if ( ( $this->use_mysqli && ! ( $this->dbh instanceof mysqli ) ) - || ( empty( $this->dbh ) || ! ( $this->dbh instanceof mysqli ) ) ) { - return; + $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 compact( 'charset', 'collate' ); } - if ( 'utf8' === $this->charset && $this->has_cap( 'utf8mb4' ) ) { - $this->charset = 'utf8mb4'; + if ( 'utf8' === $charset && $this->has_cap( 'utf8mb4' ) ) { + $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' ); } /** @@ -767,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 ); @@ -778,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 ); @@ -831,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 * @@ -839,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 ] ); } @@ -859,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 ) { @@ -898,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 @@ -962,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 ) { @@ -1025,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( __( '
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.
%2$s
have permission to use the %1$s
database?username_%1$s
. Could that be the problem?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 = '' . 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 ) . '
'
+ ) . "
' . htmlspecialchars( $this->dbuser, ENT_QUOTES ) . '
',
+ '' . htmlspecialchars( $db, ENT_QUOTES ) . '
'
+ ) . "username_%1$s
. Could that be the problem?' ),
+ htmlspecialchars( $db, ENT_QUOTES )
+ ). "' . 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; } } @@ -1061,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 @@ -1071,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 ); } @@ -1097,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 ); } @@ -1135,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() * @@ -1144,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 ) ) @@ -1163,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 ) ) @@ -1188,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 ) ) @@ -1213,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(); @@ -1235,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 @@ -1262,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; @@ -1294,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
%s [%s]%s
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 = '' . 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 ) . '
'
+ ) . "
' . 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 ) { @@ -1518,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. @@ -1529,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; } } @@ -1578,16 +1675,29 @@ class wpdb { return false; } + wp_load_translations_early(); + + $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 ) . '
'
+ ) . "
' . 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( ( " -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(); @@ -1610,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. @@ -1640,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; + } } } @@ -1664,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 ) { @@ -1701,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++; } @@ -1736,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++; @@ -1759,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 ) { @@ -1780,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 ) { @@ -1801,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' ) { @@ -1822,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']; } @@ -1846,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 ) { @@ -1870,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']; } @@ -1898,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 ) { @@ -1915,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']; } @@ -1942,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 ) { @@ -2014,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 ); @@ -2043,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 ); @@ -2075,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; } @@ -2106,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; } @@ -2152,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; } @@ -2179,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; } @@ -2215,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 ) ); @@ -2246,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. @@ -2342,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. @@ -2367,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; } @@ -2407,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; } @@ -2448,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; } /** @@ -2560,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; } @@ -2595,8 +2778,13 @@ class wpdb { if ( is_array( $value['length'] ) ) { $length = $value['length']['length']; + $truncate_by_byte_length = 'byte' === $value['length']['type']; } else { $length = false; + // Since we have no length, we'll never truncate. + // Initialize the variable to false. true would take us + // through an unnecessary (for this case) codepath below. + $truncate_by_byte_length = false; } // There's no charset to work with. @@ -2609,8 +2797,6 @@ class wpdb { continue; } - $truncate_by_byte_length = 'byte' === $value['length']['type']; - $needs_validation = true; if ( // latin1 can store any byte sequence @@ -2676,56 +2862,55 @@ class wpdb { $queries = array(); foreach ( $data as $col => $value ) { if ( ! empty( $value['db'] ) ) { - if ( ! isset( $queries[ $value['charset'] ] ) ) { - $queries[ $value['charset'] ] = array(); - } - // We're going to need to truncate by characters or bytes, depending on the length value we have. if ( 'byte' === $value['length']['type'] ) { - // Split the CONVERT() calls by charset, so we can make sure the connection is right - $queries[ $value['charset'] ][ $col ] = $this->prepare( "CONVERT( LEFT( CONVERT( %s USING binary ), %d ) USING {$value['charset']} )", $value['value'], $value['length']['length'] ); + // Using binary causes LEFT() to truncate by bytes. + $charset = 'binary'; + } else { + $charset = $value['charset']; + } + + if ( $this->charset ) { + $connection_charset = $this->charset; } else { - $queries[ $value['charset'] ][ $col ] = $this->prepare( "LEFT( CONVERT( %s USING {$value['charset']} ), %d )", $value['value'], $value['length']['length'] ); + 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 $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 $connection_charset )", $value['value'] ); } unset( $data[ $col ]['db'] ); } } - $connection_charset = $this->charset; - foreach ( $queries as $charset => $query ) { + $sql = array(); + foreach ( $queries as $column => $query ) { if ( ! $query ) { continue; } - // Change the charset to match the string(s) we're converting - if ( $charset !== $connection_charset ) { - $connection_charset = $charset; - $this->set_charset( $this->dbh, $charset ); - } - - $this->check_current_query = false; - - $sql = array(); - foreach ( $query as $column => $column_query ) { - $sql[] = $column_query . " AS x_$column"; - } + $sql[] = $query . " AS x_$column"; + } - $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A ); - if ( ! $row ) { - $this->set_charset( $this->dbh, $connection_charset ); - return new WP_Error( 'wpdb_strip_invalid_text_failure' ); - } + $this->check_current_query = false; + $row = $this->get_row( "SELECT " . implode( ', ', $sql ), ARRAY_A ); + if ( ! $row ) { + return new WP_Error( 'wpdb_strip_invalid_text_failure' ); + } - foreach ( array_keys( $query ) as $column ) { + foreach ( array_keys( $data ) as $column ) { + if ( isset( $row["x_$column"] ) ) { $data[ $column ]['value'] = $row["x_$column"]; } } - - // Don't forget to change the charset back! - if ( $connection_charset !== $this->charset ) { - $this->set_charset( $this->dbh ); - } } return $data; @@ -2834,11 +3019,8 @@ class wpdb { // Allow (select...) union [...] style queries. Use the first query's table name. $query = ltrim( $query, "\r\n\t (" ); - /* - * Strip everything between parentheses except nested selects and use only 1,000 - * chars of the query. - */ - $query = preg_replace( '/\((?!\s*select)[^(]*?\)/is', '()', substr( $query, 0, 1000 ) ); + // Strip everything between parentheses except nested selects. + $query = preg_replace( '/\((?!\s*select)[^(]*?\)/is', '()', $query ); // Quickly match most common queries. if ( preg_match( '/^\s*(?:' @@ -2847,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] ); } @@ -2855,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] ); } @@ -2874,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] ); } @@ -2893,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 ); } } } @@ -2908,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 ) { @@ -2919,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++; } @@ -2935,7 +3119,7 @@ class wpdb { * * @since 1.5.0 * - * @return bool + * @return true */ public function timer_start() { $this->time_start = microtime( true ); @@ -2960,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; @@ -2996,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' ); } @@ -3029,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(); @@ -3068,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; @@ -3081,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 *