Changeset 29027
- Timestamp:
- 07/08/2014 05:15:53 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/query.php
r28987 r29027 2201 2201 2202 2202 /** 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 /** 2203 2294 * Sets the 404 property and saves whether query is feed. 2204 2295 * … … 2703 2794 $where .= $search . $whichauthor . $whichmimetype; 2704 2795 2705 if ( empty($q['order']) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC')) )2796 if ( ! isset( $q['order'] ) ) { 2706 2797 $q['order'] = 'DESC'; 2707 2708 // Order by 2709 if ( empty($q['orderby']) ) { 2710 $orderby = "$wpdb->posts.post_date " . $q['order']; 2798 } else { 2799 $q['order'] = $this->parse_order( $q['order'] ); 2800 } 2801 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 } 2711 2813 } elseif ( 'none' == $q['orderby'] ) { 2712 2814 $orderby = ''; … … 2716 2818 $orderby = "FIELD( {$wpdb->posts}.post_parent, $post_parent__in )"; 2717 2819 } else { 2718 // Used to filter values2719 $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 2728 2820 $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; 2733 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; 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 ); 2825 2826 if ( ! $parsed ) { 2827 continue; 2828 } 2829 2830 $orderby_array[] = $parsed . ' ' . $this->parse_order( $order ); 2761 2831 } 2762 2763 $orderby_array[] = $orderby; 2764 } 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']}"; 2832 $orderby = implode( ', ', $orderby_array ); 2833 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 } 2854 } 2771 2855 } 2772 2856 -
trunk/tests/phpunit/tests/post/query.php
r28622 r29027 762 762 $this->assertNotContains( "post_status <> 'auto-draft'", $q3->request ); 763 763 } 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 } 764 834 }
Note: See TracChangeset
for help on using the changeset viewer.