Make WordPress Core


Ignore:
Timestamp:
01/31/2015 03:47:51 PM (10 years ago)
Author:
boonebgorges
Message:

Improve support for ordering WP_Query results by postmeta.

WP_Meta_Query clauses now support a 'name' parameter. When building a
WP_Query object, the value of 'orderby' can reference this 'name', so that
it's possible to order by any clause in a meta_query, not just the first one
(as when using 'orderby=meta_value'). This improvement also makes it possible
to order by multiple meta query clauses (or by any other eligible field plus
a meta query clause), using the array syntax for 'orderby' introduced in [29027].

Props Funkatronic, boonebgorges.
Fixes #31045.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/query.php

    r31219 r31312  
    22342234        $primary_meta_key = '';
    22352235        $primary_meta_query = false;
    2236         if ( ! empty( $this->meta_query->queries ) ) {
    2237             $primary_meta_query = reset( $this->meta_query->queries );
     2236        $meta_clauses = $this->meta_query->get_clauses();
     2237        if ( ! empty( $meta_clauses ) ) {
     2238            $primary_meta_query = reset( $meta_clauses );
    22382239
    22392240            if ( ! empty( $primary_meta_query['key'] ) ) {
     
    22442245            $allowed_keys[] = 'meta_value';
    22452246            $allowed_keys[] = 'meta_value_num';
     2247            $allowed_keys   = array_merge( $allowed_keys, array_keys( $meta_clauses ) );
    22462248        }
    22472249
     
    22612263            case 'menu_order':
    22622264            case 'comment_count':
    2263                 $orderby = "$wpdb->posts.{$orderby}";
     2265                $orderby_clause = "$wpdb->posts.{$orderby}";
    22642266                break;
    22652267            case 'rand':
    2266                 $orderby = 'RAND()';
     2268                $orderby_clause = 'RAND()';
    22672269                break;
    22682270            case $primary_meta_key:
    22692271            case 'meta_value':
    22702272                if ( ! empty( $primary_meta_query['type'] ) ) {
    2271                     $sql_type = $this->meta_query->get_cast_for_type( $primary_meta_query['type'] );
    2272                     $orderby = "CAST($wpdb->postmeta.meta_value AS {$sql_type})";
     2273                    $orderby_clause = "CAST({$primary_meta_query['alias']}.meta_value AS {$primary_meta_query['cast']})";
    22732274                } else {
    2274                     $orderby = "$wpdb->postmeta.meta_value";
     2275                    $orderby_clause = "{$primary_meta_query['alias']}.meta_value";
    22752276                }
    22762277                break;
    22772278            case 'meta_value_num':
    2278                 $orderby = "$wpdb->postmeta.meta_value+0";
     2279                $orderby_clause = "{$primary_meta_query['alias']}.meta_value+0";
    22792280                break;
    22802281            default:
    2281                 $orderby = "$wpdb->posts.post_" . $orderby;
     2282                if ( array_key_exists( $orderby, $meta_clauses ) ) {
     2283                    // $orderby corresponds to a meta_query clause.
     2284                    $meta_clause = $meta_clauses[ $orderby ];
     2285                    $orderby_clause = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})";
     2286                } else {
     2287                    // Default: order by post field.
     2288                    $orderby_clause = "$wpdb->posts.post_" . sanitize_key( $orderby );
     2289                }
     2290
    22822291                break;
    22832292        }
    22842293
    2285         return $orderby;
     2294        return $orderby_clause;
    22862295    }
    22872296
     
    28132822
    28142823        $where .= $search . $whichauthor . $whichmimetype;
     2824
     2825        if ( ! empty( $this->meta_query->queries ) ) {
     2826            $clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this );
     2827            $join   .= $clauses['join'];
     2828            $where  .= $clauses['where'];
     2829        }
    28152830
    28162831        $rand = ( isset( $q['orderby'] ) && 'rand' === $q['orderby'] );
     
    30293044
    30303045            $where .= ')';
    3031         }
    3032 
    3033         if ( !empty( $this->meta_query->queries ) ) {
    3034             $clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this );
    3035             $join .= $clauses['join'];
    3036             $where .= $clauses['where'];
    30373046        }
    30383047
Note: See TracChangeset for help on using the changeset viewer.