WordPress meta query with multiple key value pairs and relations

I have the following problem.
On my WordPress page there are small sticky posts and one big sticky post, this is all fine. But there are also regular posts and I need to not display the posts that are marked as sticky or big sticky with a meta value.

I need to query for value is not true or doesn’t exist for home_post key and value is not true or doesn’t exist for big_home_post key.

Read More

The code I came up with is the following:

'meta_query' => array(
    'relation' => 'AND',
    array(
        'relation' => 'OR',
        array(
            'key' => 'big_home_post',
            'value' => true,
            'compare' => '!='
        ),
         array(
            'key' => 'big_home_post',
            'value' => true,
            'compare' => 'NOT EXISTS'
        ),
    ),
    array(
        'relation' => 'OR',
        array(
            'key' => 'home_post',
            'value' => true,
            'compare' => '!='
        ),
         array(
            'key' => 'home_post',
            'value' => true,
            'compare' => 'NOT EXISTS'
        ),
    ),
),

The code is not working.

Maybe the multidimensional array is not built correctly or WordPress doesn’t support this at all.

All help is appreciated

Related posts

Leave a Reply

2 comments

  1. It is not possible to use nested array in meta_query. You need to write your own query for that. I suggest you to following code to achieve your target;

    $query = new WP_Query( array(
        'custom_meta_query_enabled' => true,
    ) );
    
    add_filter( 'posts_join', 'custom_meta_query', 10, 2 );
    function custom_meta_query( $join, $query ) {
        if ( empty( $query->query_vars['custom_meta_query_enabled'] ) )
            return $join;
    
        global $wpdb;
        $new_join = "
            INNER JOIN {$wpdb->postmeta} wppm ON 1=1
                AND wppm.post_id = {$wpdb->posts}.ID
                AND (wppm.meta_key != 'big_home_post' OR (wppm.meta_key = 'big_home_post' AND wppm.meta_value != true)
                AND (wppm.meta_key != 'home_post' OR (wppm.meta_key = 'home_post' AND wppm.meta_value != true)
        ";
        return $join . ' ' . $new_join;
    }
    

    Simply, I have put a control called custom_meta_query_enabled. If you set this field in your WP_Query to true, system query will be overrided with custom join query. In order to use this, you can put it in functions.php