WordPress.org

Make WordPress Core

Ticket #17065: 17065.2.diff

File 17065.2.diff, 6.1 KB (added by wonderboymusic, 6 years ago)
  • src/wp-includes/query.php

     
    21162116        }
    21172117
    21182118        /**
     2119         * If the passed orderby value is allowed, convert the alias to a properly-prefixed orderby value
     2120         *
     2121         * @since 4.0.0
     2122         *
     2123         * @global wpdb $wpdb
     2124         * @param string $orderby Alias for the field to order by.
     2125         * @return string Table-prefixed value to used in the ORDER clause.
     2126         */
     2127        protected function parse_orderby( $orderby ) {
     2128                global $wpdb;
     2129
     2130                // Used to filter values
     2131                $allowed_keys = array( 'name', 'author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count', 'type' );
     2132                $meta_key = $this->get( 'meta_key' );
     2133                if ( ! empty( $meta_key ) ) {
     2134                        $allowed_keys[] = $meta_key;
     2135                        $allowed_keys[] = 'meta_value';
     2136                        $allowed_keys[] = 'meta_value_num';
     2137                }
     2138
     2139                if ( ! in_array( $orderby, $allowed_keys ) ) {
     2140                        return;
     2141                }
     2142
     2143                switch ( $orderby ) {
     2144                        case 'menu_order':
     2145                                $orderby = "$wpdb->posts.menu_order";
     2146                                break;
     2147                        case 'ID':
     2148                                $orderby = "$wpdb->posts.ID";
     2149                                break;
     2150                        case 'rand':
     2151                                $orderby = 'RAND()';
     2152                                break;
     2153                        case $meta_key:
     2154                        case 'meta_value':
     2155                                $type = $this->get( 'meta_type' );
     2156                                if ( ! empty( $type ) ) {
     2157                                        $meta_type = $this->meta_query->get_cast_for_type( $type );
     2158                                        $orderby = "CAST($wpdb->postmeta.meta_value AS {$meta_type})";
     2159                                } else {
     2160                                        $orderby = "$wpdb->postmeta.meta_value";
     2161                                }
     2162                                break;
     2163                        case 'meta_value_num':
     2164                                $orderby = "$wpdb->postmeta.meta_value+0";
     2165                                break;
     2166                        case 'comment_count':
     2167                                $orderby = "$wpdb->posts.comment_count";
     2168                                break;
     2169                        default:
     2170                                $orderby = "$wpdb->posts.post_" . $orderby;
     2171                }
     2172
     2173                return $orderby;
     2174        }
     2175
     2176        /**
    21192177         * Sets the 404 property and saves whether query is feed.
    21202178         *
    21212179         * @since 2.0.0
     
    26402698                        $q['order'] = 'DESC';
    26412699
    26422700                // Order by
    2643                 if ( empty($q['orderby']) ) {
     2701                if ( empty( $q['orderby'] )
     2702                        && ( ! isset( $this->query['orderby'] ) || ! is_array( $this->query['orderby'] ) ) ) {
    26442703                        $orderby = "$wpdb->posts.post_date " . $q['order'];
    26452704                } elseif ( 'none' == $q['orderby'] ) {
    26462705                        $orderby = '';
     
    26492708                } elseif ( $q['orderby'] == 'post_parent__in' && ! empty( $post_parent__in ) ) {
    26502709                        $orderby = "FIELD( {$wpdb->posts}.post_parent, $post_parent__in )";
    26512710                } else {
    2652                         // Used to filter values
    2653                         $allowed_keys = array( 'name', 'author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count', 'type' );
    2654                         if ( !empty($q['meta_key']) ) {
    2655                                 $allowed_keys[] = $q['meta_key'];
    2656                                 $allowed_keys[] = 'meta_value';
    2657                                 $allowed_keys[] = 'meta_value_num';
    2658                         }
    2659                         $q['orderby'] = urldecode($q['orderby']);
    2660                         $q['orderby'] = addslashes_gpc($q['orderby']);
    2661 
    26622711                        $orderby_array = array();
    2663                         foreach ( explode( ' ', $q['orderby'] ) as $i => $orderby ) {
    2664                                 // Only allow certain values for safety
    2665                                 if ( ! in_array($orderby, $allowed_keys) )
    2666                                         continue;
     2712                        if ( is_array( $q['orderby'] ) ) {
     2713                                foreach ( $q['orderby'] as $_orderby => $order ) {
     2714                                        $orderby = addslashes_gpc( urldecode( $_orderby ) );
     2715                                        $parsed = $this->parse_orderby( $orderby );
     2716                                        if ( ! $parsed ) {
     2717                                                continue;
     2718                                        }
     2719                                        $orderby_array[] = implode( ' ', array( $parsed, $order ) );
     2720                                }
     2721                                $orderby = implode( ', ', $orderby_array );
     2722                        } else {
     2723                                $q['orderby'] = urldecode($q['orderby']);
     2724                                $q['orderby'] = addslashes_gpc($q['orderby']);
    26672725
    2668                                 switch ( $orderby ) {
    2669                                         case 'menu_order':
    2670                                                 $orderby = "$wpdb->posts.menu_order";
    2671                                                 break;
    2672                                         case 'ID':
    2673                                                 $orderby = "$wpdb->posts.ID";
    2674                                                 break;
    2675                                         case 'rand':
    2676                                                 $orderby = 'RAND()';
    2677                                                 break;
    2678                                         case $q['meta_key']:
    2679                                         case 'meta_value':
    2680                                                 if ( isset( $q['meta_type'] ) ) {
    2681                                                         $meta_type = $this->meta_query->get_cast_for_type( $q['meta_type'] );
    2682                                                         $orderby = "CAST($wpdb->postmeta.meta_value AS {$meta_type})";
    2683                                                 } else {
    2684                                                         $orderby = "$wpdb->postmeta.meta_value";
    2685                                                 }
    2686                                                 break;
    2687                                         case 'meta_value_num':
    2688                                                 $orderby = "$wpdb->postmeta.meta_value+0";
    2689                                                 break;
    2690                                         case 'comment_count':
    2691                                                 $orderby = "$wpdb->posts.comment_count";
    2692                                                 break;
    2693                                         default:
    2694                                                 $orderby = "$wpdb->posts.post_" . $orderby;
     2726                                foreach ( explode( ' ', $q['orderby'] ) as $i => $orderby ) {
     2727                                        $parsed = $this->parse_orderby( $orderby );
     2728                                        // Only allow certain values for safety
     2729                                        if ( ! $parsed ) {
     2730                                                continue;
     2731                                        }
     2732
     2733                                        $orderby_array[] = $parsed;
    26952734                                }
     2735                                $orderby = implode( ' ' . $q['order'] . ', ', $orderby_array );
    26962736
    2697                                 $orderby_array[] = $orderby;
     2737                                if ( empty( $orderby ) )
     2738                                        $orderby = "$wpdb->posts.post_date ".$q['order'];
     2739                                else
     2740                                        $orderby .= " {$q['order']}";
    26982741                        }
    2699                         $orderby = implode( ' ' . $q['order'] . ', ', $orderby_array );
    2700 
    2701                         if ( empty( $orderby ) )
    2702                                 $orderby = "$wpdb->posts.post_date ".$q['order'];
    2703                         else
    2704                                 $orderby .= " {$q['order']}";
    27052742                }
    27062743
    27072744                // Order search results by relevance only when another "orderby" is not specified in the query.
  • tests/phpunit/tests/post/query.php

     
    761761                $q3 = new WP_Query( array( 'post_status' => array( 'any', 'auto-draft' ) ) );
    762762                $this->assertNotContains( "post_status <> 'auto-draft'", $q3->request );
    763763        }
     764
     765        /**
     766         *
     767         * @ticket 17065
     768         */
     769        function test_orderby_array() {
     770                global $wpdb;
     771
     772                $q1 = new WP_Query( array(
     773                        'orderby' => array(
     774                                'type' => 'DESC',
     775                                'name' => 'ASC'
     776                        )
     777                ) );
     778                $this->assertContains(
     779                        "ORDER BY $wpdb->posts.post_type DESC, $wpdb->posts.post_name ASC",
     780                        $q1->request
     781                );
     782
     783                $q2 = new WP_Query( array( 'orderby' => array() ) );
     784                $this->assertNotContains( 'ORDER BY', $q2->request );
     785                $this->assertNotContains( 'ORDER', $q2->request );
     786
     787                $q3 = new WP_Query( array( 'post_type' => 'post' ) );
     788                $this->assertContains(
     789                        "ORDER BY $wpdb->posts.post_date DESC",
     790                        $q3->request
     791                );
     792        }
    764793}
     794 No newline at end of file