You must use LIKE
on the meta_key
to support the SQL %
pattern. The compare
attribute only applies to the meta value.
Instead you could try to filter it with:
/**
* Match any numbers in given a meta-key for WP_Query
*
* @see https://wordpress.stackexchange.com/a/177331/26350
*/
! is_admin() && add_filter( 'posts_where', function( $where )
{
global $wpdb;
// Replace the following meta key search:
$find = $wpdb->postmeta . ".meta_key = 'modules_%_text'";
// with a LIKE search:
//$to = $wpdb->postmeta . ".meta_key LIKE 'modules_%_text'";
// or a REGEXP search:
$to = $wpdb->postmeta . ".meta_key REGEXP '^modules_[0-9]+_text$'";
// Replace:
if( false !== stripos( $where, $find ) )
$where = str_ireplace( $find, $to, $where );
return $where;
} );
This should modify your meta key search from:
wp_postmeta.meta_key = 'modules_%_text'
to
wp_postmeta.meta_key LIKE 'modules_%_text'
or if you must only match numbers in the meta key:
wp_postmeta.meta_key REGEXP '^modules_[0-9]+_text$'
PS: Here’s another similar question that was posted recently.
Update:
Answering the comment regarding multiple replacements:
/**
* Match any numbers in given array of meta-keys for WP_Query
*
* @see https://wordpress.stackexchange.com/a/177331/26350
*/
! is_admin() && add_filter( 'posts_where', function( $where )
{
global $wpdb;
// Replace the following meta keys:
$a_find = [
$wpdb->postmeta . ".meta_key = 'modules_%_text'",
$wpdb->postmeta . ".meta_key = 'modules_%_images'"
];
// with a LIKE search:
//$a_to = [
// $wpdb->postmeta . ".meta_key LIKE 'modules_%_text'",
// $wpdb->postmeta . ".meta_key LIKE 'modules_%_images'"
//];
// or a REGEXP search:
$a_to = [
$wpdb->postmeta . ".meta_key REGEXP '^modules_[0-9]+_text$'",
$wpdb->postmeta . ".meta_key REGEXP '^modules_[0-9]+_images$'"
];
// Replace:
return str_ireplace( $a_find, $a_to, $where );
} );
where $a_find
and $a_to
are arrays of equal size.