0

I’ve build several search forms with different <select> and <input>.

I use a meta_query and build an array of key/value pair.

Array
(
    [relation] => AND
    [0] => Array
        (
            [relation] => AND
            [0] => Array
                (
                    [fields] => ID
                    [key] => ville
                    [value] => Angers
                    [compare] => LIKE
                    [type] => CHAR
                )

        )

    [1] => Array
        (
            [relation] => OR
        )

    [2] => Array
        (
            [relation] => OR
        )

)

It works, i can filter users or posts (i use WP_User_Query or WP_Query).

The search form is using AJAX, it means that each time a user change a select, the $query_array is updated and the list of results is also updated.

So, let’s say the default value of a select is 0

<option selected="" value="0"> -- City -- </option>

In this case, i reset the meta_key / meta_value :

if (!empty($_POST['city']) && $_POST['city'] != '0') {

        $meta_value_ville = $_POST['city'];
        array_push($query_array_and, array('fields' => 'ID', 'key' => 'ville', 'value' => $meta_value_ville, 'compare' => 'LIKE', 'type' => 'CHAR'));
    } else if ($_POST['city'] === '0') {
        // reset
        array_push($query_array_and, array('fields' => 'ID', 'key' => '', 'value' => '', 'compare' => 'LIKE', 'type' => 'CHAR'));
    }

I empty the key and the value.

The result is

Array
(
    [relation] => AND
    [0] => Array
        (
            [relation] => AND
            [0] => Array
                (
                    [fields] => ID
                    [key] => 
                    [value] => 
                    [compare] => LIKE
                    [type] => CHAR
                )

        )

    [1] => Array
        (
            [relation] => OR
        )

    [2] => Array
        (
            [relation] => OR
        )

)

Is it the best way to do it ? I feel that sometime the list of posts or users is not complete with this method.

1 Answer 1

0

I wouldn't push the meta query entries like that but build it more logical.

So for example:

$meta_query_args = array( 'relation' => 'AND' ); // assuming you want 'AND' search, you're using both in your example

if ( ! empty( $_POST['city'] ) && $_POST['city'] != '0' ) {

    $meta_value_ville = $_POST['city'];

    $meta_query_args['city_clause'] = array(
        'key'     => 'ville',
        'value'   => $meta_value_ville,
        'compare' => 'LIKE',
        'type'    => 'CHAR'
    );
}

// Example, say you also have a country field
if ( ! empty( $_POST['country'] ) && $_POST['country'] != '0' ) {

    $meta_value = $_POST['country'];

    $meta_query_args['country_clause'] = array(
        'key'     => 'country',
        'value'   => $meta_value,
        'compare' => 'LIKE',
        'type'    => 'CHAR'
    );
}

Note 1: I'm no longer pushing date into existing arrays build build it from scratch every time. This saves you all the code of resetting certain meta query arrays.

Note 2: I removed the 'fields' => 'ID' part since this isn't part of the meta_query. You should add this to the WP_Query.

Note 3: Because I'm giving the clauses named index (e.g. city_clause) you can use them in the rest of your WP_Query. Example: You can sort on them now like this:

$q = new WP_Query( array(
    'meta_query' => $meta_query_args,
    'orderby'    => 'city_clause'
) );
1
  • I’m using AND and OR because i use nested arrays to construct complex queries but it’s not a problem. I’ll try to build $meta_query_args from scratch every time. Commented Apr 6, 2017 at 13:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.