User Meta Query with RLIKE
:
If the birth date is stored like dd/mm/yyyy
, in the user meta, then you could find all August birthday users with the following meta query:
'meta_query' => [
[
'key' => 'birthday',
'value' => '/08/',
'compare' => 'RLIKE'
],
]
You could also consider storing the birthday month additionally in the user meta.
Here I’ve listed the available meta comparisons.
Applied to your code snippet:
Part #1
Here’s how you can apply this to your code example:
/**
* Setup the user meta query for the current birth month
*/
add_action( 'pre_get_users', function( $user_query )
{
// User input:
$birthmonth = filter_input( INPUT_GET, 'birthmonth', FILTER_SANITIZE_NUMBER_INT );
// Setup the meta query:
if( $birthmonth )
{
$user_query->query_vars['meta_key'] = 'birthday';
$user_query->query_vars['meta_value'] = zeroise( $birthmonth, 2 );
$user_query->query_vars['meta_compare'] = 'RLIKE';
}
} );
where we use the pre_get_users
hook instead of the pre_user_query
and use the handy zeroise()
function – it’s informative to check out the \WP_Locale
class.
We will use it’s get_month()
method in the second part here below.
Note that in your current attempt of directly modifying the SQL query,
the birthday
field is treated as a part of the wp_users
table.
Also the INNER JOIN
, on the wp_usermeta
table, is missing.
You must also validate/sanitize the user input.
Part #2
The second part is modified to:
/**
* Add a birth month filter to the users table
*/
add_action( 'restrict_manage_users', function()
{
global $wp_locale;
// User input:
$birthmonth = filter_input( INPUT_GET, 'birthmonth', FILTER_SANITIZE_NUMBER_INT );
// Birthmonth select box:
print '<select name="birthmonth" id="birthmonth" onchange="" size="1">';
printf( '<option value="">%s</option>', __( 'Birthmonth' ) );
foreach( range(1,12) as $month )
{
printf(
'<option value="%d" %s>%s</option>',
$month,
selected( $birthmonth, $month ),
$wp_locale->get_month( $month )
);
}
print '</select>';
} );
where we use birthmonth
instead of month
, to avoid name collision.
I also added the default state, without any birthmonth
selected.
Also added the handy selected()
function, to show the current selected option.
The month names are defined in the \WP_Locale
class and the class instance is available through the global $wp_locale
object.