wpdb::get_table_charset()protectedWP 4.2.0

Retrieves the character set for the given table.

Method of the class: wpdb{}

Hooks from the method

Return

String|WP_Error. Table character set, WP_Error object if it couldn't be found.

Usage

// protected - for code of main (parent) or child class
$result = $this->get_table_charset( $table );
$table(string) (required)
Table name.

Changelog

Since 4.2.0 Introduced.

wpdb::get_table_charset() code WP 6.4.3

protected function get_table_charset( $table ) {
	$tablekey = strtolower( $table );

	/**
	 * Filters the table charset value before the DB is checked.
	 *
	 * Returning a non-null value from the filter will effectively short-circuit
	 * checking the DB for the charset, returning that value instead.
	 *
	 * @since 4.2.0
	 *
	 * @param string|WP_Error|null $charset The character set to use, WP_Error object
	 *                                      if it couldn't be found. Default null.
	 * @param string               $table   The name of the table being checked.
	 */
	$charset = apply_filters( 'pre_get_table_charset', null, $table );
	if ( null !== $charset ) {
		return $charset;
	}

	if ( isset( $this->table_charset[ $tablekey ] ) ) {
		return $this->table_charset[ $tablekey ];
	}

	$charsets = array();
	$columns  = array();

	$table_parts = explode( '.', $table );
	$table       = '`' . implode( '`.`', $table_parts ) . '`';
	$results     = $this->get_results( "SHOW FULL COLUMNS FROM $table" );
	if ( ! $results ) {
		return new WP_Error( 'wpdb_get_table_charset_failure', __( 'Could not retrieve table charset.' ) );
	}

	foreach ( $results as $column ) {
		$columns[ strtolower( $column->Field ) ] = $column;
	}

	$this->col_meta[ $tablekey ] = $columns;

	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;
		}

		list( $type ) = explode( '(', $column->Type );

		// A binary/blob means the whole query gets treated like this.
		if ( in_array( strtoupper( $type ), array( 'BINARY', 'VARBINARY', 'TINYBLOB', 'MEDIUMBLOB', 'BLOB', 'LONGBLOB' ), true ) ) {
			$this->table_charset[ $tablekey ] = 'binary';
			return 'binary';
		}
	}

	// utf8mb3 is an alias for utf8.
	if ( isset( $charsets['utf8mb3'] ) ) {
		$charsets['utf8'] = true;
		unset( $charsets['utf8mb3'] );
	}

	// Check if we have more than one charset in play.
	$count = count( $charsets );
	if ( 1 === $count ) {
		$charset = key( $charsets );
	} elseif ( 0 === $count ) {
		// No charsets, assume this table can store whatever.
		$charset = false;
	} else {
		// More than one charset. Remove latin1 if present and recalculate.
		unset( $charsets['latin1'] );
		$count = count( $charsets );
		if ( 1 === $count ) {
			// Only one charset (besides latin1).
			$charset = key( $charsets );
		} elseif ( 2 === $count && isset( $charsets['utf8'], $charsets['utf8mb4'] ) ) {
			// Two charsets, but they're utf8 and utf8mb4, use utf8.
			$charset = 'utf8';
		} else {
			// Two mixed character sets. ascii.
			$charset = 'ascii';
		}
	}

	$this->table_charset[ $tablekey ] = $charset;
	return $charset;
}