2

I'm working on a form for filtering a list of posts using custom fields created with the Advanced Custom Fields plugin. Because of the form, I'm using the pre_get_posts action to change the query via GET requests. (following code references are either PHP or dumped from print_r())

I set the meta_query like this:

$query->set('meta_query',$filter);

and $filter looks like this:

Array
(
    [0] => Array
        (
            [key] => delivery_method
            [value] => Array
                (
                    [0] => Online
                    [1] => Scheduled

                )

            [compare] => IN
        )
)

The custom field that I am querying is structured like this:

Array (
    [delivery_method] => Array (
        [0] => Online
        [1] => Scheduled
    )
)

When I look for posts with [compare] => IN (as above), no posts are returned. When I look for posts with [compare] => NOT IN, all of the posts are returned.

I am trying to return only those posts which have a specific "delivery method". Is there a way to compare the two arrays that I missed? or do I have to somehow explode one of the arrays and compare individual values against an array?

2

The ACF Documentation recommends checking the values individually rather than simultaneously using an array.

The following code is from the ACF Documentation for the Checkbox field type:

http://www.advancedcustomfields.com/resources/field-types/checkbox/

/*
*  Query posts for a checkbox value.
*  This method uses the meta_query LIKE to match the string "red" to the database value a:2:{i:0;s:3:"red";i:1;s:4:"blue";} (serialized array)
*  The above value suggests that the user selected "red" and "blue" from the checkbox choices
*/

$posts = get_posts(array(
    'meta_query' => array(
        array(
            'key' => 'field_name', // name of custom field
            'value' => '"red"', // matches exaclty "red", not just red. This prevents a match for "acquired"
            'compare' => 'LIKE'
        )
    )
));

Therefore the query in pre_get_posts should look like this:

$filter = array(
    array(
        'key' => 'delivery_method'
        'value' => '"Online"'
        'compare' => 'LIKE'
    ),
    array(
        'key' => 'delivery_method'
        'value' => '"Scheduled"'
        'compare' => 'LIKE'
    )
)

$query->set('meta_query',$filter);
1

If I am correct, you have a field that contain an array, to be clear, something that you can save using:

add_post_meta( $postid, 'delivery_method', array('Online', 'Scheduled') );

Then you want to query posts where field 'delivery_method' = array( 'Online', 'Scheduled').

The problem is that a meta query like the yours:

$meta_query = array(
  array(
    'key' => 'delivery_method',
    'value' => array( 'Online', 'Scheduled' ),
    'compare' => 'IN'
  )
);

returns posts having the 'deliver_method' key set to 'Online' (string) or 'Scheduled' (string) or both, but your post has the key 'deliver_method' saved as array, so its value is serialized by WordPress before being saved in database, and you can't query for a serialized value using an unserialized array...

So, if you want to store different delivery methods, it's fairly better if you use multiple values for same key, instead of a key with multiple values, e.g.

add_post_meta( $postid, 'delivery_method', 'Online' );
add_post_meta( $postid, 'delivery_method', 'Scheduled' );

In this way, using proper args, you'll be able to get posts having one of the methods, or both, depending on your needs.

I sincerly don't know how to implement this using ACF, and however the plugin-specific way is off topic for this site, but I think the concept is simple and you can simply apply on that plugin.

A dirty hack for the specific case is query using as value the serialized value

$meta_query = array(
  array(
    'key' => 'delivery_method',
    'value' => serialize ( array( 'Online', 'Scheduled' ) )
  )
);

This meta query returns the posts having both methods saved as array.

  • This would work, but I realized that it would pull only those posts with both "Online" and "Scheduled". It would not pull those with either "Online" or "Scheduled". – camara_tech Apr 10 '14 at 15:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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