How to make meta_query according to dynamic meta_key values in Wordpress?

1k Views Asked by At

I'm trying to list some users using the get_users function.

An online learning plugin I use saves some data in user metadata as course_COURSEID_access_from. For example; If the course ID is 123, the metadata is saved as: course_123_access_from. And the value of this metadata is a timestamp. For example; 1600724678.

// First day of the month.
$first_day = strtotime( date( 'Y-m-01' ) );
// Last day of the month.
$last_day = strtotime( date( 'Y-m-t' ) );

$args = array(
    'fields'     => 'ID',
    'role'       => 'customer',
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'key' => 'course_%_access_from',
            'value' => array( $first_day, $last_day ),
            'type' => 'numeric',
            'compare' => 'BETWEEN'
        ),
    )
);
$users = get_users($args);

But I can not get any results. Where am I making a mistake?

How can I query on wordpress metadata based on dynamic meta_keys?

2

There are 2 best solutions below

0
On BEST ANSWER

Based on Fabien's answer, I realized that I could solve this problem with a custom SQL query. And I created the following SQL query:

global $wpdb;
$user_ids = $wpdb->get_results( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key LIKE 'course_%_access_from' AND meta_value > $first_day AND meta_value < $last_day" );,

Thanks Fabien.

1
On

try this code :

<?php
function filter_request_sql_where($where)
{
    if (strpos($where, "meta_key = 'course_$_access_from")) {
        $where = str_replace("meta_key = 'course_$_access_from", "meta_key LIKE 'course_%_access_from", $where);
    }
    return $where;
}

add_filter('posts_where', 'filter_request_sql_where');

// First day of the month.
$first_day = strtotime(date('Y-m-01'));
// Last day of the month.
$last_day = strtotime(date('Y-m-t'));

$args = array(
    'fields' => 'ID',
    'role' => 'customer',
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'key' => 'course_$_access_from',
            'value' => array($first_day, $last_day),
            'type' => 'numeric',
            'compare' => 'BETWEEN'
        ),
    )
);
$users = get_users($args);