Jplus2
Jplus2

Reputation: 2531

perform meta_query to a custom post meta with array values in pre_get_posts callback

I have a custom post meta that contains array values

code:

update_post_meta($post_id,'custom_meta_key',array('val1','val2','val3','val4'));

Now I want to hook a call back to pre_get_posts to modify the query

code:

add_action('pre_get_posts','foo');

function foo ($q){

    if ( ! $q->is_main_query() ) return;

    if ( ! $q->is_post_type_archive() ) return;

    if ( ! is_admin() ) {

        $q->set('meta_query',array(
            array(
                'key'       =>  'custom_meta_key',
                'value'     =>  array('val1','val3'),
                'compare'   =>  'IN'
            )
        ));

    }

    remove_action( 'pre_get_posts','foo');

}

I want to only get the posts with the 'custom_meta_key' post meta having values of 'val1' or 'val3'

but the result is blank, the page doesn't return any items at all.

this must be because update_post_meta serializes the array upon save? Is what I am trying to achieve possible?

Upvotes: 0

Views: 736

Answers (1)

Jplus2
Jplus2

Reputation: 2531

In order to achieve my goal, I need to change the way I persist post meta.

Instead of using update_post_meta, I have to use add_post_meta

so for this to work

    $q->set('meta_query',array(
        array(
            'key'       =>  'custom_meta_key',
            'value'     =>  array('val1','val3'),
            'compare'   =>  'IN'
        )
    ));

I need to do this

delete_post_meta($post->id,'custom_meta_key');

add_post_meta($post->id,'custom_meta_key','val1');
add_post_meta($post->id,'custom_meta_key','val2');

I executed delete_post_meta first to prevent the values of the post meta from duplicating (I have attached a callback to save_post hook)

then I do add_post_meta for each of the values

now custom_meta_key will have a value of array('val1','val2') and the above code will work.

also, update_post_meta does serializes array, but when used as an argument to WP_Query's meta query, it does not unserialize the array string, that's why my code above on my question didn't worked

I confirmed this by doing this

update_post_meta($post->id,'custom_meta_key',array('val1'))

array(
        'key'       =>  'custom_meta_key',
        'value'     =>  serialize(array('val1')),
        'compare'   =>  'IN'
    )

and it worked

referrences:

update_post_meta

add_post_meta

delete_post_meta

Upvotes: 1

Related Questions