Make WordPress Core

Ticket #17065: 17065.7.diff

File 17065.7.diff, 8.2 KB (added by wonderboymusic, 11 years ago)
  • src/wp-includes/query.php

     
    22002200        }
    22012201
    22022202        /**
     2203         * If the passed orderby value is allowed, convert the alias to a
     2204         * properly-prefixed orderby value.
     2205         *
     2206         * @since 4.0.0
     2207         * @access protected
     2208         *
     2209         * @global wpdb $wpdb WordPress database access abstraction object.
     2210         *
     2211         * @param string $orderby Alias for the field to order by.
     2212         * @return string|bool Table-prefixed value to used in the ORDER clause. False otherwise.
     2213         */
     2214        protected function parse_orderby( $orderby ) {
     2215                global $wpdb;
     2216
     2217                // Used to filter values.
     2218                $allowed_keys = array(
     2219                        'post_name', 'post_author', 'post_date', 'post_title', 'post_modified',
     2220                        'post_parent', 'post_type', 'name', 'author', 'date', 'title', 'modified',
     2221                        'parent', 'type', 'ID', 'menu_order', 'comment_count', 'rand',
     2222                );
     2223
     2224                $meta_key = $this->get( 'meta_key' );
     2225                if ( ! empty( $meta_key ) ) {
     2226                        $allowed_keys[] = $meta_key;
     2227                        $allowed_keys[] = 'meta_value';
     2228                        $allowed_keys[] = 'meta_value_num';
     2229                }
     2230
     2231                if ( ! in_array( $orderby, $allowed_keys ) ) {
     2232                        return false;
     2233                }
     2234
     2235                switch ( $orderby ) {
     2236                        case 'post_name':
     2237                        case 'post_author':
     2238                        case 'post_date':
     2239                        case 'post_title':
     2240                        case 'post_modified':
     2241                        case 'post_parent':
     2242                        case 'post_type':
     2243                        case 'ID':
     2244                        case 'menu_order':
     2245                        case 'comment_count':
     2246                                $orderby = "$wpdb->posts.{$orderby}";
     2247                                break;
     2248                        case 'rand':
     2249                                $orderby = 'RAND()';
     2250                                break;
     2251                        case $meta_key:
     2252                        case 'meta_value':
     2253                                $type = $this->get( 'meta_type' );
     2254                                if ( ! empty( $type ) ) {
     2255                                        $meta_type = $this->meta_query->get_cast_for_type( $type );
     2256                                        $orderby = "CAST($wpdb->postmeta.meta_value AS {$meta_type})";
     2257                                } else {
     2258                                        $orderby = "$wpdb->postmeta.meta_value";
     2259                                }
     2260                                break;
     2261                        case 'meta_value_num':
     2262                                $orderby = "$wpdb->postmeta.meta_value+0";
     2263                                break;
     2264                        default:
     2265                                $orderby = "$wpdb->posts.post_" . $orderby;
     2266                                break;
     2267                }
     2268
     2269                return $orderby;
     2270        }
     2271
     2272        /**
     2273         * Parse an 'order' query variable and cast it to ASC or DESC as necessary.
     2274         *
     2275         * @since 4.0.0
     2276         * @access protected
     2277         *
     2278         * @param string $order The 'order' query variable.
     2279         * @return string The sanitized 'order' query variable.
     2280         */
     2281        protected function parse_order( $order ) {
     2282                if ( ! is_string( $order ) || empty( $order ) ) {
     2283                        return 'DESC';
     2284                }
     2285
     2286                if ( 'ASC' === strtoupper( $order ) ) {
     2287                        return 'ASC';
     2288                } else {
     2289                        return 'DESC';
     2290                }
     2291        }
     2292
     2293        /**
    22032294         * Sets the 404 property and saves whether query is feed.
    22042295         *
    22052296         * @since 2.0.0
     
    27022793
    27032794                $where .= $search . $whichauthor . $whichmimetype;
    27042795
    2705                 if ( empty($q['order']) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC')) )
     2796                if ( ! isset( $q['order'] ) ) {
    27062797                        $q['order'] = 'DESC';
     2798                } else {
     2799                        $q['order'] = $this->parse_order( $q['order'] );
     2800                }
    27072801
    2708                 // Order by
    2709                 if ( empty($q['orderby']) ) {
    2710                         $orderby = "$wpdb->posts.post_date " . $q['order'];
     2802                // Order by.
     2803                if ( empty( $q['orderby'] ) ) {
     2804                        /*
     2805                         * Boolean false or empty array blanks out ORDER BY,
     2806                         * while leaving the value unset or otherwise empty sets the default.
     2807                         */
     2808                        if ( isset( $q['orderby'] ) && ( is_array( $q['orderby'] ) || false === $q['orderby'] ) ) {
     2809                                $orderby = '';
     2810                        } else {
     2811                                $orderby = "$wpdb->posts.post_date " . $q['order'];
     2812                        }
    27112813                } elseif ( 'none' == $q['orderby'] ) {
    27122814                        $orderby = '';
    27132815                } elseif ( $q['orderby'] == 'post__in' && ! empty( $post__in ) ) {
     
    27152817                } elseif ( $q['orderby'] == 'post_parent__in' && ! empty( $post_parent__in ) ) {
    27162818                        $orderby = "FIELD( {$wpdb->posts}.post_parent, $post_parent__in )";
    27172819                } else {
    2718                         // Used to filter values
    2719                         $allowed_keys = array( 'name', 'author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count', 'type' );
    2720                         if ( !empty($q['meta_key']) ) {
    2721                                 $allowed_keys[] = $q['meta_key'];
    2722                                 $allowed_keys[] = 'meta_value';
    2723                                 $allowed_keys[] = 'meta_value_num';
    2724                         }
    2725                         $q['orderby'] = urldecode($q['orderby']);
    2726                         $q['orderby'] = addslashes_gpc($q['orderby']);
    2727 
    27282820                        $orderby_array = array();
    2729                         foreach ( explode( ' ', $q['orderby'] ) as $i => $orderby ) {
    2730                                 // Only allow certain values for safety
    2731                                 if ( ! in_array($orderby, $allowed_keys) )
    2732                                         continue;
     2821                        if ( is_array( $q['orderby'] ) ) {
     2822                                foreach ( $q['orderby'] as $_orderby => $order ) {
     2823                                        $orderby = addslashes_gpc( urldecode( $_orderby ) );
     2824                                        $parsed  = $this->parse_orderby( $orderby );
    27332825
    2734                                 switch ( $orderby ) {
    2735                                         case 'menu_order':
    2736                                                 $orderby = "$wpdb->posts.menu_order";
    2737                                                 break;
    2738                                         case 'ID':
    2739                                                 $orderby = "$wpdb->posts.ID";
    2740                                                 break;
    2741                                         case 'rand':
    2742                                                 $orderby = 'RAND()';
    2743                                                 break;
    2744                                         case $q['meta_key']:
    2745                                         case 'meta_value':
    2746                                                 if ( isset( $q['meta_type'] ) ) {
    2747                                                         $meta_type = $this->meta_query->get_cast_for_type( $q['meta_type'] );
    2748                                                         $orderby = "CAST($wpdb->postmeta.meta_value AS {$meta_type})";
    2749                                                 } else {
    2750                                                         $orderby = "$wpdb->postmeta.meta_value";
    2751                                                 }
    2752                                                 break;
    2753                                         case 'meta_value_num':
    2754                                                 $orderby = "$wpdb->postmeta.meta_value+0";
    2755                                                 break;
    2756                                         case 'comment_count':
    2757                                                 $orderby = "$wpdb->posts.comment_count";
    2758                                                 break;
    2759                                         default:
    2760                                                 $orderby = "$wpdb->posts.post_" . $orderby;
     2826                                        if ( ! $parsed ) {
     2827                                                continue;
     2828                                        }
     2829
     2830                                        $orderby_array[] = $parsed . ' ' . $this->parse_order( $order );
    27612831                                }
     2832                                $orderby = implode( ', ', $orderby_array );
    27622833
    2763                                 $orderby_array[] = $orderby;
     2834                        } else {
     2835                                $q['orderby'] = urldecode( $q['orderby'] );
     2836                                $q['orderby'] = addslashes_gpc( $q['orderby'] );
     2837
     2838                                foreach ( explode( ' ', $q['orderby'] ) as $i => $orderby ) {
     2839                                        $parsed = $this->parse_orderby( $orderby );
     2840                                        // Only allow certain values for safety.
     2841                                        if ( ! $parsed ) {
     2842                                                continue;
     2843                                        }
     2844
     2845                                        $orderby_array[] = $parsed;
     2846                                }
     2847                                $orderby = implode( ' ' . $q['order'] . ', ', $orderby_array );
     2848
     2849                                if ( empty( $orderby ) ) {
     2850                                        $orderby = "$wpdb->posts.post_date ".$q['order'];
     2851                                } else {
     2852                                        $orderby .= " {$q['order']}";
     2853                                }
    27642854                        }
    2765                         $orderby = implode( ' ' . $q['order'] . ', ', $orderby_array );
    2766 
    2767                         if ( empty( $orderby ) )
    2768                                 $orderby = "$wpdb->posts.post_date ".$q['order'];
    2769                         else
    2770                                 $orderby .= " {$q['order']}";
    27712855                }
    27722856
    27732857                // 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
     793                $q4 = new WP_Query( array( 'post_type' => 'post' ) );
     794                $this->assertContains(
     795                        "ORDER BY $wpdb->posts.post_date DESC",
     796                        $q4->request
     797                );
     798        }
     799
     800        /**
     801         *
     802         * @ticket 17065
     803         */
     804        function test_order() {
     805                global $wpdb;
     806
     807                $q1 = new WP_Query( array(
     808                        'orderby' => array(
     809                                'post_type' => 'foo'
     810                        )
     811                ) );
     812                $this->assertContains(
     813                        "ORDER BY $wpdb->posts.post_type DESC",
     814                        $q1->request
     815                );
     816
     817                $q2 = new WP_Query( array(
     818                        'orderby' => 'title',
     819                        'order'   => 'foo'
     820                ) );
     821                $this->assertContains(
     822                        "ORDER BY $wpdb->posts.post_title DESC",
     823                        $q2->request
     824                );
     825
     826                $q3 = new WP_Query( array(
     827                        'order' => 'asc'
     828                ) );
     829                $this->assertContains(
     830                        "ORDER BY $wpdb->posts.post_date ASC",
     831                        $q3->request
     832                );
     833        }
    764834}
     835 No newline at end of file