X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/wordpress.git/blobdiff_plain/fa6ee2c363cdfdebcb4b76e4d9c4347a4cb19065..refs/tags/wordpress-4.2:/wp-includes/wp-db.php diff --git a/wp-includes/wp-db.php b/wp-includes/wp-db.php index 6eb0c75d..5e5cd1ee 100644 --- a/wp-includes/wp-db.php +++ b/wp-includes/wp-db.php @@ -43,7 +43,7 @@ define( 'ARRAY_N', 'ARRAY_N' ); * file to your class. The wpdb class will still be included, * so you can extend it or simply use your own. * - * @link http://codex.wordpress.org/Function_Reference/wpdb_Class + * @link https://codex.wordpress.org/Function_Reference/wpdb_Class * * @package WordPress * @subpackage Database @@ -240,7 +240,7 @@ class wpdb { var $ready = false; /** - * {@internal Missing Description}} + * Blog ID. * * @since 3.0.0 * @access public @@ -249,7 +249,7 @@ class wpdb { public $blogid = 0; /** - * {@internal Missing Description}} + * Site ID. * * @since 3.0.0 * @access public @@ -634,8 +634,6 @@ class wpdb { } } - $this->init_charset(); - $this->dbuser = $dbuser; $this->dbpassword = $dbpassword; $this->dbname = $dbname; @@ -727,16 +725,31 @@ class wpdb { public function init_charset() { if ( function_exists('is_multisite') && is_multisite() ) { $this->charset = 'utf8'; - if ( defined( 'DB_COLLATE' ) && DB_COLLATE ) + if ( defined( 'DB_COLLATE' ) && DB_COLLATE ) { $this->collate = DB_COLLATE; - else + } else { $this->collate = 'utf8_general_ci'; + } } elseif ( defined( 'DB_COLLATE' ) ) { $this->collate = DB_COLLATE; } - if ( defined( 'DB_CHARSET' ) ) + if ( defined( 'DB_CHARSET' ) ) { $this->charset = DB_CHARSET; + } + + if ( ( $this->use_mysqli && ! ( $this->dbh instanceof mysqli ) ) + || ( empty( $this->dbh ) || ! ( $this->dbh instanceof mysqli ) ) ) { + return; + } + + if ( 'utf8' === $this->charset && $this->has_cap( 'utf8mb4' ) ) { + $this->charset = 'utf8mb4'; + } + + if ( 'utf8mb4' === $this->charset && ( ! $this->collate || stripos( $this->collate, 'utf8_' ) === 0 ) ) { + $this->collate = 'utf8mb4_unicode_ci'; + } } /** @@ -1376,7 +1389,7 @@ class wpdb { while ( mysqli_more_results( $this->dbh ) ) { mysqli_next_result( $this->dbh ); } - } else if ( is_resource( $this->result ) ) { + } elseif ( is_resource( $this->result ) ) { mysql_free_result( $this->result ); } } @@ -1445,9 +1458,9 @@ class wpdb { if ( $this->has_connected ) { $attempt_fallback = false; - } else if ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL ) { + } elseif ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL ) { $attempt_fallback = false; - } else if ( ! function_exists( 'mysql_connect' ) ) { + } elseif ( ! function_exists( 'mysql_connect' ) ) { $attempt_fallback = false; } @@ -1485,11 +1498,17 @@ class wpdb { " ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' ); return false; - } else if ( $this->dbh ) { + } elseif ( $this->dbh ) { + if ( ! $this->has_connected ) { + $this->init_charset(); + } + $this->has_connected = true; + $this->set_charset( $this->dbh ); - $this->set_sql_mode(); + $this->ready = true; + $this->set_sql_mode(); $this->select( $this->dbname, $this->dbh ); return true; @@ -1620,6 +1639,7 @@ class wpdb { } $this->check_current_query = true; + // Keep track of the last query for debug.. $this->last_query = $query; @@ -1685,7 +1705,7 @@ class wpdb { $this->last_result[$num_rows] = $row; $num_rows++; } - } else if ( is_resource( $this->result ) ) { + } elseif ( is_resource( $this->result ) ) { while ( $row = @mysql_fetch_object( $this->result ) ) { $this->last_result[$num_rows] = $row; $num_rows++; @@ -1926,20 +1946,11 @@ class wpdb { */ protected function process_fields( $table, $data, $format ) { $data = $this->process_field_formats( $data, $format ); - if ( false === $data ) { - return false; - } - $data = $this->process_field_charsets( $data, $table ); if ( false === $data ) { return false; } - $data = $this->process_field_lengths( $data, $table ); - if ( false === $data ) { - return false; - } - $converted_data = $this->strip_invalid_text( $data ); if ( $data !== $converted_data ) { @@ -1986,12 +1997,12 @@ class wpdb { /** * Adds field charsets to field/value/format arrays generated by - * the {@see wpdb::process_field_formats()} method. + * the wpdb::process_field_formats() method. * * @since 4.2.0 * @access protected * - * @param array $data As it comes from the {@see wpdb::process_field_formats()} method. + * @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. */ @@ -2020,40 +2031,6 @@ class wpdb { return $data; } - /** - * For string fields, record the maximum string length that field can safely save. - * - * @since 4.2.1 - * @access protected - * - * @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 - * 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. - $value['length'] = false; - } else { - $value['length'] = $this->get_col_length( $table, $field ); - if ( is_wp_error( $value['length'] ) ) { - return false; - } - } - - if ( false !== $value['length'] && strlen( $value['value'] ) > $value['length'] ) { - return false; - } - - $data[ $field ] = $value; - } - - return $data; - } - /** * Retrieve one variable from the database. * @@ -2229,7 +2206,7 @@ class wpdb { * @access protected * * @param string $table Table name. - * @return string|WP_Error Table character set, {@see WP_Error} object if it couldn't be found. + * @return string|WP_Error Table character set, WP_Error object if it couldn't be found. */ protected function get_table_charset( $table ) { $tablekey = strtolower( $table ); @@ -2269,6 +2246,12 @@ class wpdb { foreach ( $columns as $column ) { if ( ! empty( $column->Collation ) ) { list( $charset ) = explode( '_', $column->Collation ); + + // If the current connection can't support utf8mb4 characters, let's only send 3-byte utf8 characters. + if ( 'utf8mb4' === $charset && ! $this->has_cap( 'utf8mb4' ) ) { + $charset = 'utf8'; + } + $charsets[ strtolower( $charset ) ] = true; } @@ -2323,7 +2306,7 @@ 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. {@see WP_Error} object if there was an error. + * character set. WP_Error object if there was an error. */ public function get_col_charset( $table, $column ) { $tablekey = strtolower( $table ); @@ -2378,77 +2361,6 @@ class wpdb { return $charset; } - /** - * Retrieve the maximum string length allowed in a given column. - * - * @since 4.2.1 - * @access public - * - * @param string $table Table name. - * @param string $column Column name. - * @return mixed Max column length as an int. False if the column has no - * length. 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 ) { - return false; - } - - if ( empty( $this->col_meta[ $tablekey ] ) ) { - // This primes column information for us. - $table_charset = $this->get_table_charset( $table ); - if ( is_wp_error( $table_charset ) ) { - return $table_charset; - } - } - - if ( empty( $this->col_meta[ $tablekey ][ $columnkey ] ) ) { - return false; - } - - $typeinfo = explode( '(', $this->col_meta[ $tablekey ][ $columnkey ]->Type ); - - $type = strtolower( $typeinfo[0] ); - if ( ! empty( $typeinfo[1] ) ) { - $length = trim( $typeinfo[1], ')' ); - } else { - $length = false; - } - - switch( $type ) { - case 'binary': - case 'char': - case 'varbinary': - case 'varchar': - return $length; - break; - case 'tinyblob': - case 'tinytext': - return 255; // 2^8 - 1 - break; - case 'blob': - case 'text': - return 65535; // 2^16 - 1 - break; - case 'mediumblob': - case 'mediumtext': - return 16777215; // 2^24 - 1 - break; - case 'longblob': - case 'longtext': - return 4294967295; // 2^32 - 1 - break; - default: - return false; - } - - return false; - } - /** * Check if a string is ASCII. * @@ -2543,9 +2455,8 @@ class wpdb { * @return array|WP_Error The $data parameter, with invalid characters removed from * each value. This works as a passthrough: any additional keys * such as 'field' are retained in each value array. If we cannot - * remove invalid characters, a {@see WP_Error} object is returned. + * remove invalid characters, a WP_Error object is returned. */ - // If any of the columns don't have one of these collations, it needs more sanity checking. protected function strip_invalid_text( $data ) { // Some multibyte character sets that we can check in PHP. $mb_charsets = array( @@ -2678,7 +2589,7 @@ class wpdb { * @access protected * * @param string $query Query to convert. - * @return string|WP_Error The converted query, or a {@see WP_Error} object if the conversion fails. + * @return string|WP_Error The converted query, or a WP_Error object if the conversion fails. */ protected function strip_invalid_text_from_query( $query ) { $table = $this->get_table_from_query( $query ); @@ -2719,7 +2630,7 @@ class wpdb { * @param string $table Table name. * @param string $column Column name. * @param string $value The text to check. - * @return string|WP_Error The converted string, or a `WP_Error` object if the conversion fails. + * @return string|WP_Error The converted string, or a WP_Error object if the conversion fails. */ public function strip_invalid_text_for_column( $table, $column, $value ) { if ( ! is_string( $value ) || $this->check_ascii( $value ) ) { @@ -2982,7 +2893,25 @@ class wpdb { case 'set_charset' : return version_compare( $version, '5.0.7', '>=' ); case 'utf8mb4' : // @since 4.1.0 - return version_compare( $version, '5.5.3', '>=' ); + if ( version_compare( $version, '5.5.3', '<' ) ) { + return false; + } + if ( $this->use_mysqli ) { + $client_version = mysqli_get_client_info(); + } else { + $client_version = mysql_get_client_info(); + } + + /* + * libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server. + * mysqlnd has supported utf8mb4 since 5.0.9. + */ + if ( false !== strpos( $client_version, 'mysqlnd' ) ) { + $client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $client_version ); + return version_compare( $client_version, '5.0.9', '>=' ); + } else { + return version_compare( $client_version, '5.5.3', '>=' ); + } } return false;