@@ -3227,21 +3227,15 @@ protected function get_table_charset( $table ) {
32273227 }
32283228
32293229 $ charsets = array ();
3230- $ columns = array ( );
3230+ $ columns = $ this -> get_cols_meta ( $ table );
32313231
3232- $ table_parts = explode ( '. ' , $ table );
3233- $ table = '` ' . implode ( '`.` ' , $ table_parts ) . '` ' ;
3234- $ results = $ this ->get_results ( "SHOW FULL COLUMNS FROM $ table " );
3235- if ( ! $ results ) {
3236- return new WP_Error ( 'wpdb_get_table_charset_failure ' , __ ( 'Could not retrieve table charset. ' ) );
3232+ if ( is_wp_error ( $ columns ) ) {
3233+ return $ columns ;
32373234 }
3238-
3239- foreach ( $ results as $ column ) {
3240- $ columns [ strtolower ( $ column ->Field ) ] = $ column ;
3235+ if ( empty ( $ columns ) ) {
3236+ $ columns = array ();
32413237 }
32423238
3243- $ this ->col_meta [ $ tablekey ] = $ columns ;
3244-
32453239 foreach ( $ columns as $ column ) {
32463240 if ( ! empty ( $ column ->Collation ) ) {
32473241 list ( $ charset ) = explode ( '_ ' , $ column ->Collation );
@@ -3291,6 +3285,109 @@ protected function get_table_charset( $table ) {
32913285 return $ charset ;
32923286 }
32933287
3288+ /**
3289+ * Retrieves the column metadata for the given column.
3290+ *
3291+ * @since 6.9.1
3292+ *
3293+ * @param string $table Table name.
3294+ * @return object|false|WP_Error Column meta set as an object. False if the column was
3295+ * not found. WP_Error object if there was an error.
3296+ */
3297+ public function get_cols_meta ( $ table ) {
3298+ $ tablekey = strtolower ( $ table );
3299+
3300+ /**
3301+ * Filters the columns meta value before the DB is checked.
3302+ *
3303+ * Passing a non-null value to the filter will short-circuit
3304+ * checking the DB for the meta, returning that value instead.
3305+ *
3306+ * @since 6.9.1
3307+ *
3308+ * @param array<object>|null|false|WP_Error $meta The meta to use. Default null.
3309+ * @param string $table The name of the table being checked.
3310+ */
3311+ $ col_meta = apply_filters ( 'pre_get_cols_meta ' , null , $ table );
3312+ if ( null !== $ col_meta ) {
3313+ return $ col_meta ;
3314+ }
3315+
3316+ // Skip this entirely if this isn't a MySQL database.
3317+ if ( empty ( $ this ->is_mysql ) ) {
3318+ return false ;
3319+ }
3320+
3321+ // If no column information, fetch it from the database.
3322+ if ( empty ( $ this ->col_meta [ $ tablekey ] ) ) {
3323+ $ columns = array ();
3324+
3325+ $ table_parts = explode ( '. ' , $ table );
3326+ $ table = '` ' . implode ( '`.` ' , $ table_parts ) . '` ' ;
3327+ $ results = $ this ->get_results ( "SHOW FULL COLUMNS FROM $ table " );
3328+ if ( ! $ results ) {
3329+ return new WP_Error ( 'wpdb_get_cols_meta_failure ' , __ ( 'Could not retrieve column metadata. ' ) );
3330+ }
3331+
3332+ foreach ( $ results as $ column ) {
3333+ $ columns [ strtolower ( $ column ->Field ) ] = $ column ;
3334+ }
3335+
3336+ $ this ->col_meta [ $ tablekey ] = $ columns ;
3337+ }
3338+
3339+ // If this table data doesn't exist, return false.
3340+ if ( empty ( $ this ->col_meta [ $ tablekey ] ) ) {
3341+ return false ;
3342+ }
3343+
3344+ return $ this ->col_meta [ $ tablekey ];
3345+ }
3346+
3347+ /**
3348+ * Retrieves the column metadata for the given column.
3349+ *
3350+ * @since 6.9.1
3351+ *
3352+ * @param string $table Table name.
3353+ * @param string $column Column name.
3354+ * @return object|false|WP_Error Column character set as a string. False if the column has
3355+ * no character set. WP_Error object if there was an error.
3356+ */
3357+ public function get_col_meta ( $ table , $ column ) {
3358+ $ columnkey = strtolower ( $ column );
3359+
3360+ /**
3361+ * Filters the column meta value before the DB is checked.
3362+ *
3363+ * Passing a non-null value to the filter will short-circuit
3364+ * checking the DB for the meta, returning that value instead.
3365+ *
3366+ * @since 6.9.1
3367+ *
3368+ * @param object|null|false|WP_Error $meta The meta to use. Default null.
3369+ * @param string $table The name of the table being checked.
3370+ * @param string $column The name of the column being checked.
3371+ */
3372+ $ col_meta = apply_filters ( 'pre_get_col_meta ' , null , $ table , $ column );
3373+ if ( null !== $ col_meta ) {
3374+ return $ col_meta ;
3375+ }
3376+
3377+ $ cols_meta = $ this ->get_cols_meta ( $ table );
3378+
3379+ if ( is_wp_error ( $ cols_meta ) ) {
3380+ return $ cols_meta ;
3381+ }
3382+
3383+ // If this column doesn't exist, return false.
3384+ if ( empty ( $ cols_meta [ $ columnkey ] ) ) {
3385+ return false ;
3386+ }
3387+
3388+ return $ cols_meta [ $ columnkey ];
3389+ }
3390+
32943391 /**
32953392 * Retrieves the character set for the given column.
32963393 *
@@ -3302,9 +3399,6 @@ protected function get_table_charset( $table ) {
33023399 * no character set. WP_Error object if there was an error.
33033400 */
33043401 public function get_col_charset ( $ table , $ column ) {
3305- $ tablekey = strtolower ( $ table );
3306- $ columnkey = strtolower ( $ column );
3307-
33083402 /**
33093403 * Filters the column charset value before the DB is checked.
33103404 *
@@ -3322,35 +3416,23 @@ public function get_col_charset( $table, $column ) {
33223416 return $ charset ;
33233417 }
33243418
3325- // Skip this entirely if this isn't a MySQL database.
3326- if ( empty ( $ this ->is_mysql ) ) {
3327- return false ;
3328- }
3419+ $ col_meta = $ this ->get_col_meta ( $ table , $ column );
33293420
3330- if ( empty ( $ this ->table_charset [ $ tablekey ] ) ) {
3331- // This primes column information for us.
3332- $ table_charset = $ this ->get_table_charset ( $ table );
3333- if ( is_wp_error ( $ table_charset ) ) {
3334- return $ table_charset ;
3335- }
3336- }
3337-
3338- // If still no column information, return the table charset.
3339- if ( empty ( $ this ->col_meta [ $ tablekey ] ) ) {
3340- return $ this ->table_charset [ $ tablekey ];
3421+ if ( is_wp_error ( $ col_meta ) ) {
3422+ return $ col_meta ;
33413423 }
33423424
33433425 // If this column doesn't exist, return the table charset.
3344- if ( empty ( $ this -> col_meta [ $ tablekey ][ $ columnkey ] ) ) {
3345- return $ this ->table_charset [ $ tablekey ] ;
3426+ if ( empty ( $ col_meta ) ) {
3427+ return $ this ->get_table_charset ( $ table ) ;
33463428 }
33473429
33483430 // Return false when it's not a string column.
3349- if ( empty ( $ this -> col_meta [ $ tablekey ][ $ columnkey ] ->Collation ) ) {
3431+ if ( empty ( $ col_meta ->Collation ) ) {
33503432 return false ;
33513433 }
33523434
3353- list ( $ charset ) = explode ( '_ ' , $ this -> col_meta [ $ tablekey ][ $ columnkey ] ->Collation );
3435+ list ( $ charset ) = explode ( '_ ' , $ col_meta ->Collation );
33543436 return $ charset ;
33553437 }
33563438
@@ -3372,27 +3454,17 @@ public function get_col_charset( $table, $column ) {
33723454 * }
33733455 */
33743456 public function get_col_length ( $ table , $ column ) {
3375- $ tablekey = strtolower ( $ table );
3376- $ columnkey = strtolower ( $ column );
3377-
3378- // Skip this entirely if this isn't a MySQL database.
3379- if ( empty ( $ this ->is_mysql ) ) {
3380- return false ;
3381- }
3457+ $ col_meta = $ this ->get_col_meta ( $ table , $ column );
33823458
3383- if ( empty ( $ this ->col_meta [ $ tablekey ] ) ) {
3384- // This primes column information for us.
3385- $ table_charset = $ this ->get_table_charset ( $ table );
3386- if ( is_wp_error ( $ table_charset ) ) {
3387- return $ table_charset ;
3388- }
3459+ if ( is_wp_error ( $ col_meta ) ) {
3460+ return $ col_meta ;
33893461 }
33903462
3391- if ( empty ( $ this -> col_meta [ $ tablekey ][ $ columnkey ] ) ) {
3463+ if ( empty ( $ col_meta ) ) {
33923464 return false ;
33933465 }
33943466
3395- $ typeinfo = explode ( '( ' , $ this -> col_meta [ $ tablekey ][ $ columnkey ] ->Type );
3467+ $ typeinfo = explode ( '( ' , $ col_meta ->Type );
33963468
33973469 $ type = strtolower ( $ typeinfo [0 ] );
33983470 if ( ! empty ( $ typeinfo [1 ] ) ) {
@@ -3510,8 +3582,9 @@ protected function check_safe_collation( $query ) {
35103582 return true ;
35113583 }
35123584
3513- $ table = strtolower ( $ table );
3514- if ( empty ( $ this ->col_meta [ $ table ] ) ) {
3585+ $ cols_meta = $ this ->get_cols_meta ( $ table );
3586+
3587+ if ( is_wp_error ( $ cols_meta ) || empty ( $ cols_meta ) ) {
35153588 return false ;
35163589 }
35173590
@@ -3525,7 +3598,7 @@ protected function check_safe_collation( $query ) {
35253598 'utf8mb4_general_ci ' ,
35263599 );
35273600
3528- foreach ( $ this -> col_meta [ $ table ] as $ col ) {
3601+ foreach ( $ cols_meta as $ col ) {
35293602 if ( empty ( $ col ->Collation ) ) {
35303603 continue ;
35313604 }
0 commit comments