Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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"

share|improve this question
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 '11 at 15:08
    
Er... right, that would probably be why then. Any way to get it to work in 3.0.5? –  Amanda Feb 17 '11 at 16:11
    
Miljenko has the best answer you should accept his instead of yours. –  Hugo Apr 3 '12 at 5:24

3 Answers 3

up vote 4 down vote accepted

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
        )
    );
    
share|improve this answer

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
    ));
share|improve this answer

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.

share|improve this answer
    
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? –  Amanda Feb 17 '11 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 '11 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 :) –  Amanda Feb 17 '11 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 '11 at 18:01
1  
@t31os - i usually do that but not when answering from my cell phone. –  Bainternet Feb 17 '11 at 18:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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