Question

I have a text field and a drop down with country names. If I use OR and only fill in the text field with a person's name it brings back incorrect results. If I type in the name and select a country, I get correct results. If I input a name and purposefully chose the incorrect country that they are not in, I get results for the country I selected. So, something is not working correctly here.

If I use AND and only type in the persons name and leave out the country, I get no results where I would like to at least see some results based on the name search. Neither fields are required, you should be able to only search by 1 or both.

If you search only by location it should show all users for that country and if you only input a name it should show all users with that name in any country and if you search with both fields it should only show you people with that name in the specified country.

$s_query = $_GET['s'];
$country = $_GET['location'];

$args = array(
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key' => 'first_name',
            'value' => $s_query,
            'compare' => 'LIKE'
        ) ,
        array(
            'key' => 'last_name',
            'value' => $s_query,
            'compare' => 'LIKE'
        ),
        array(
            'key' => 'location',
            'value' => $country,
            'compare' => 'LIKE'
        )
    )
);



$wp_user_query = new WP_User_Query($args);


$authors = $wp_user_query->get_results();


if (!empty($authors)) {
    echo '<ul>';

    foreach ($authors as $author) {

        $author_info = get_userdata($author->ID);
        echo '<li>' . $author_info->first_name . ' ' . $author_info->last_name . ' - ' . $author->location . '</li>';
    }
    echo '</ul>';
} else {
    echo 'No authors found';
}
Was it helpful?

Solution

Note that the s query arg/string is reserved for posts, so you should use a different name for your custom user search.

So basically, you just need to "play" with the meta query nesting.

Yes, just like common (PHP) arrays can be in a multi-dimensional/multi-level format, so does the meta_query parameter, be it for WP_Query or the WP_User_Query in your case. So you could have a meta query clause in a meta query clause in a meta query clause in... well, you get the idea. :-)

And in this revised version, we're expecting the name parameter ($s_query) to always be in the <first name> <last name> format like John Doe or maybe Jane Doe Jr., so for example, if only the first name is specified, then we search in that meta only — and the location meta if a country value is specified:

// Parse the first and last names into an array.
$names = preg_split( '/ +/', trim( $s_query ), 2 );

// Then, define the meta query variable.
$meta_query = [];

// If a name if specified, add the first and last name queries to the $meta_query.
// So we're using a nested meta query clause to search in either the first and last
// name meta.
if ( $s_query ) {
    $name_query = [];

    if ( ! empty( $names[0] ) ) {
        $name_query[] = [ // child clause
            'key'     => 'first_name',
            'value'   => $names[0],
            'compare' => 'LIKE',
        ];
    }

    if ( ! empty( $names[1] ) ) {
        $name_query[] = [ // child clause
            'key'     => 'last_name',
            'value'   => $names[1],
            'compare' => 'LIKE',
        ];
    }

    // Add a top-level clause for $s_query
    if ( ! empty( $name_query ) ) {
        $name_query['relation'] = 'AND';
        $meta_query[] = $name_query;
    }
}

// If a country is specified, add the country query to the $meta_query.
if ( $country ) {
    $meta_query[] = [ // top-level clause
        'key'     => 'location',
        'value'   => $country,
        'compare' => 'LIKE',
    ];
}

// Now set the relationship for the top-level meta query clauses.
$meta_query['relation'] = ( $s_query && $country ) ? 'AND' : 'OR';

// Then add the meta query to the main query args (for WP_User_Query).
$args = [
    'meta_query' => $meta_query,
];
Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top