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.

Moreso a psuedo-code question than actual code. I have some custom post meta attached to attachments, and created a list table column for this meta. The meta is either 1, or null (not set), but I am trying to enable sorting for said column.

Is there a way to utilize meta_query for WP_Query to essentially LEFT JOIN, where I get all values (1 or null), and then I can utilize orderby=meta_value_num for ordering?

The obvious way it would work is hooking into posts_clauses, adding a JOIN, and doing the orderby as well - just curious if this would be possible while using direct WP_Query functionality!

Thanks.

share|improve this question
    
Why are you adding a custom column (and to which table) when there's the post_meta table anyway? One entry equals one row in this table. –  kaiser Jun 13 '13 at 13:29
    
Media List Table, not database table –  Eric Holmes Jun 13 '13 at 13:30
    
Misread - thanks for clarification. –  kaiser Jun 13 '13 at 13:47

2 Answers 2

You can use pre_get_posts with a callback:

<?php
defined( 'ABSPATH' ) OR exit;
/** Plugin Name: (#102854) Order Posts by Foo */

add_filter( 'pre_get_posts', 'wpse_102854_orderby_foo' );
function wpse_102854_orderby_foo( $query )
{
    if ( 
        ! $query->is_main_query()
        OR ! is_admin()
        OR 'edit.php?post_type=YOUR_POST_TYPE' !== $GLOBALS['parent_file']
        // Other conditions that force an abort, Example:
        // OR 'foo' !== $query->get( 'some_query_var' )
    )
        return $query;

    $query->set( 'orderby', 'meta_value_num' );
    // etc.

    return $query;
}
share|improve this answer
    
Correct. I think this will NOT work however. In order for this to work, meta_query would need to support 'join_type' or something similar. Right now 'Inner Join' is hard coded. wp-includes/meta.php line 731. –  Eric Holmes Jun 13 '13 at 13:55
    
@EricHolmes Take a look at this plugin I wrote, which supports "Match" and "Filter" to get either posts with either ALL taxonomies attached or posts with ANY taxonomy attached. Should get you on the right track. –  kaiser Jun 13 '13 at 14:12
    
Thanks @kaiser, you pointed me in the right direction with relation. Updated my answer below with the correct method using pre_get_posts. –  Eric Holmes Jun 13 '13 at 14:31
up vote 2 down vote accepted

You can do it either way!

Using posts_clauses, manually write your JOIN statement (using $wpdb->prepare() - be safe!) , and add/customize the orderby clause as well.

Using meta_query there are a couple things needed. First, as kaiser mentions, you must use relation within meta_query in order for it to work. Second, even though meta_query is defined, you still need to specify the meta_key argument, or else orderby=meta_value will not work. I assume this is because you can have multiple joins happening at once, which could be using different meta keys.

Here is how I accomplished it:

function handle_my_sortable_column( $query ) {
    global $pagenow;
    if( is_admin() && 'upload.php' == $pagenow && 'my_meta_key' == get_query_var( 'orderby' ) ) {
        $query->set( 'meta_query', array(
            'relation' => 'OR',
            array(
                'key' => my_meta_key',
                'value' => null,
                'compare' => 'EXISTS'
            ),
            array(
                'key' => 'my_meta_key',
                'value' => '', // must be '' value, null does not work
                'compare' => 'NOT EXISTS'
            )
        ) );
        $query->set( 'meta_key', 'my_meta_key' ); // required for orderby
        $query->set( 'orderby', 'meta_value_num' );
    }
}
share|improve this answer
1  
Afaik your only problem is that the relation is set to AND instead to OR. This should be the only thing you need to change. –  kaiser Jun 13 '13 at 14:08
    
Interesting - relation is found under tax_query but not meta_query - testing this now. –  Eric Holmes Jun 13 '13 at 14:15
    
Updating my answer now. –  Eric Holmes Jun 13 '13 at 14:25
1  
Well, that the value needs to be defined empty is even stated in Codex ;) –  kaiser Jun 13 '13 at 14:40
    
it mentions trying both null and ''. Thought I'd point out that bull didn't work for NOT EXISTS but did for EXISTS - strange. –  Eric Holmes Jun 13 '13 at 14:45

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.