11

I have a custom post type "Listing" and I want to get all Listings that have a custom field gateway_value != 'Yes', and order the results by another custom field, location_level1_value. I can get the queries to work separately, but I can't combine them:

Query 1 (sort by location):

                $wp_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'post_status' => 'publish',
                    'posts_per_page' => '9',
                    'meta_key' => 'location_level1_value',
                    'orderby' => 'location_level1_value',
                    'order' => 'ASC',
                    'paged' => $paged
                    )
                 );

Query 2 (custom field value != Yes):

                $wp_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'posts_per_page' => '9',
                    'post_status' => 'publish',
                    'meta_key' => 'gateway_value',
                    'meta_value' => 'Yes',
                    'meta_compare' => '!=',
                    'paged' => $paged
                    )
                );

Combined query:

I looked at the codex for help with this, but the following query does not work:

                $wp_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'posts_per_page' => '9',
                    'post_status' => 'publish',
                    'meta_query' => array(
                        array(
                            'key' => 'gateway_value',
                            'value' => 'Yes',
                            'compare' => '!='
                        ),
                        array(
                            'key' => 'location_level1_value'
                        )
                    ),
                    'orderby' => "location_level1_value",
                    'order' => 'ASC',
                    'paged' => $paged
                    )
                );

What am I doing wrong with the combined query?

[UPDATE]: So now that 3.1 has been released, the combined query above still does not work. I do get results, just not sorted correctly.

[UPDATE]: var_dump($wp_query->request) gives the following:
string(527) " SELECT SQL_CALC_FOUND_ROWS wp_7v1oev_posts.* FROM wp_7v1oev_posts INNER JOIN wp_7v1oev_postmeta ON (wp_7v1oev_posts.ID = wp_7v1oev_postmeta.post_id) INNER JOIN wp_7v1oev_postmeta AS mt1 ON (wp_7v1oev_posts.ID = mt1.post_id) WHERE 1=1 AND wp_7v1oev_posts.post_type = 'listing' AND (wp_7v1oev_posts.post_status = 'publish') AND wp_7v1oev_postmeta.meta_key = 'gateway_value' AND CAST(wp_7v1oev_postmeta.meta_value AS CHAR) != 'Yes' AND mt1.meta_key = 'location_level1_value' ORDER BY wp_7v1oev_posts.post_date DESC LIMIT 0, 9"

3
  • 3
    Are you using WordPress 3.1? The meta_query parameter is new in 3.1, due to be released very soon, but the current stable version is still 3.0.5, without this parameter.
    – Jan Fabry
    Feb 17, 2011 at 15:08
  • Er... right, that would probably be why then. Any way to get it to work in 3.0.5? Feb 17, 2011 at 16:11
  • Miljenko has the best answer you should accept his instead of yours.
    – Hugo
    Apr 3, 2012 at 5:24

3 Answers 3

9

You could use the query to filter the content as you intended by using the 'meta_query' with filtering options, and for the order part, just add/modify the following parameters:

  • 'orderby' => 'meta_value'
  • 'meta_key' => 'location_level1_value'
  • 'order' => 'ASC'

    $wp_query = new WP_Query( array (
        'post_type'      => 'listing',
        'posts_per_page' => '9',
        'post_status'    => 'publish',
        'meta_query'     => array(
            array(
                'key'       => 'gateway_value',
                'value'     => 'Yes',
                'compare'   => '!='
            )
        ),
        'orderby'  => 'meta_value',            // this means we will be using a selected 
                                               // meta field to order
    
        'meta_key' => 'location_level1_value', // this states which meta field 
                                               // will be used in the ordering, 
                                               // regardless of the filters
        'order'    => 'ASC',
        'paged'    => $paged
        )
    );
    
2

Just like Jan said in new WordPress 3.1 you can use meta_query but until that will come out you can use your First query to orderby and filter inside your loop like so:

 Global $my_query;
$my_query = new WP_Query( array (
                    'post_type' => 'listing',
                    'post_status' => 'publish',
                    'posts_per_page' => '9',
                    'meta_key' => 'location_level1_value',
                    'orderby' => 'location_level1_value',
                    'order' => 'ASC',
                    'paged' => $paged
                    )
                 );
while ($my_query->have_posts){
    $my_query->the_post();
              //do your loop stuff
} 

and add this code to your functions.php

   //join filter
         add_filter('posts_join', 'listing_join_865' );
         function listing_join_865($join){
Global$ my_query;            
if ('listing' = $my_query->query['post_type']){
                $restriction1 = 'gateway_value';
                return $join .="
                LEFT JOIN $wpdb->postmeta AS $restriction1 ON(
                $wpdb->posts.ID = $restriction1.post_id
                AND $restriction1.meta_key = '$restriction1'
                )";
             }else {
                return $join;
            }
         }
         //where filter
         add_filter('posts_where', 'listing_where_865' );
         function listing_where_865($where){
             global $my_query;
            if ('listing' = $my_query->query['post_type']){
                return $where.= " AND $restriction1.meta_value != 'yes'";
            }else{
                return $where;
            }
         }

now this should work.

11
  • Thanks for this. This works, except I have this odd side effect that my paging doesn't work properly any more. Instead of 9 per page, I have "blank spots" in my grid where the custom posts that have gateway_value == "Yes" would have been without the conditional... Any idea on how to fix that? Feb 17, 2011 at 16:53
  • yea that would mess up the paging so i guess the only way around it would be a custom sql query, give me a few minutes.
    – Bainternet
    Feb 17, 2011 at 17:10
  • Don't worry - I will just use the second query and use the plugin wordpress.org/extend/plugins/post-types-order until 3.1 is released :) Feb 17, 2011 at 17:20
  • dam, i got back just now to see your comment after finding a solution. anyway it's here for future askers.
    – Bainternet
    Feb 17, 2011 at 18:01
  • 1
    @t31os - i usually do that but not when answering from my cell phone.
    – Bainternet
    Feb 17, 2011 at 18:20
1

Apologies for answering my own question:

Looking at [http://core.trac.wordpress.org/ticket/15031][1], seems like this is a known issue. I have fixed (hacked?) it to work using post_filter, like so (just for anyone's reference who might be searching for the same answer):

In functions.php###

add_filter('posts_orderby', 'EV_locationl1' );
function EV_locationl1 ($orderby) {
    global $EV_locationl1_orderby;
    if ($EV_locationl1_orderby) $orderby = $EV_locationl1_orderby;
    return $orderby;
}

Amended wp_query in template file###

$EV_locationl1_orderby = " mt1.meta_value ASC";

$wp_query = new WP_Query( array (
    'post_type' => 'listing',
    'posts_per_page' => '9',
    'post_status' => 'publish',
    'meta_query' => array(
            array(
                    'key' => 'gateway_value',
                    'value' => 'Yes',
                    'compare' => '!='
                    ),
            array(
                    'key' => 'location_level1_value'
            )
        ),
    'order' => $EV_locationl1_orderby,
    'paged' => $paged
    ));

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.