X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/53f4633144ed68c8b8fb5861f992b5489894a940..3d39054f012aefe514b3f5509e32f09fc4feda44:/wp-includes/wp-db.php diff --git a/wp-includes/wp-db.php b/wp-includes/wp-db.php index 9ce6519b..8ebee4c4 100644 --- a/wp-includes/wp-db.php +++ b/wp-includes/wp-db.php @@ -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 @@ -661,7 +670,7 @@ class wpdb { } /** - * PHP5 style magic getter, used to lazy-load expensive data. + * Makes private properties readable for backward compatibility. * * @since 3.5.0 * @@ -676,7 +685,7 @@ class wpdb { } /** - * Magic function, for backwards compatibility. + * Makes private properties settable for backward compatibility. * * @since 3.5.0 * @@ -696,7 +705,7 @@ class wpdb { } /** - * Magic function, for backwards compatibility. + * Makes private properties check-able for backward compatibility. * * @since 3.5.0 * @@ -709,7 +718,7 @@ class wpdb { } /** - * Magic function, for backwards compatibility. + * Makes private properties un-settable for backward compatibility. * * @since 3.5.0 * @@ -725,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' === $this->charset && $this->has_cap( 'utf8mb4' ) ) { - $this->charset = 'utf8mb4'; + if ( 'utf8' === $charset && $this->has_cap( 'utf8mb4' ) ) { + $charset = 'utf8mb4'; } - if ( 'utf8mb4' === $this->charset && ( ! $this->collate || stripos( $this->collate, 'utf8_' ) === 0 ) ) { - $this->collate = 'utf8mb4_unicode_ci'; + 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 ); + } } + + // _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' ); } /** @@ -768,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 ); @@ -779,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 ); @@ -832,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 * @@ -840,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 ] ); } @@ -1035,22 +1083,48 @@ class wpdb { $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' ); } } } @@ -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 ) ) @@ -1189,22 +1264,22 @@ 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()}. + * {@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 http://php.net/sprintf sprintf()}. + * {@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 ) { @@ -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 @@ -1474,7 +1551,7 @@ class wpdb { if ( $attempt_fallback ) { $this->use_mysqli = false; - $this->db_connect(); + return $this->db_connect( $allow_bail ); } } } else { @@ -1494,16 +1571,28 @@ class wpdb { die(); } - $this->bail( sprintf( __( " -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 ) { @@ -1526,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. @@ -1541,11 +1630,11 @@ class wpdb { */ 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; } } @@ -1586,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(); @@ -1618,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. @@ -1648,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; + } } } @@ -1672,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 ) { @@ -1709,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++; } @@ -1744,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++; @@ -1770,6 +1890,7 @@ class wpdb { * @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). @@ -1794,6 +1915,7 @@ class wpdb { * @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). @@ -1818,6 +1940,7 @@ class wpdb { * @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). @@ -1839,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']; } @@ -1866,9 +1994,12 @@ class wpdb { * @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). @@ -1895,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']; } @@ -1927,6 +2068,7 @@ class wpdb { * @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). @@ -1945,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']; } @@ -2049,8 +2196,10 @@ class wpdb { 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 ); @@ -2079,8 +2228,10 @@ class wpdb { 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 ); @@ -2249,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 ) ); @@ -2280,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. @@ -2384,7 +2535,7 @@ class wpdb { $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. @@ -2401,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; } @@ -2450,7 +2601,7 @@ class wpdb { $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; } @@ -2482,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; } /** @@ -2594,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; } @@ -2721,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'] ); @@ -2870,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] ); } @@ -2878,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] ); } @@ -2897,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] ); } @@ -2916,14 +3075,14 @@ class wpdb { return; if ( $this->use_mysqli ) { - $num_fields = @mysqli_num_fields( $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 ); + $this->col_info[ $i ] = mysqli_fetch_field( $this->result ); } } else { - $num_fields = @mysql_num_fields( $this->result ); + $num_fields = mysql_num_fields( $this->result ); for ( $i = 0; $i < $num_fields; $i++ ) { - $this->col_info[ $i ] = @mysql_fetch_field( $this->result, $i ); + $this->col_info[ $i ] = mysql_fetch_field( $this->result, $i ); } } } @@ -2944,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++; } @@ -2991,15 +3150,46 @@ class wpdb { */ 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. * @@ -3022,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' ); } @@ -3055,7 +3246,8 @@ 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() * @@ -3094,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; @@ -3114,7 +3308,7 @@ class wpdb { } /** - * The database version number. + * Retrieves the MySQL server version. * * @since 2.7.0 *