| | 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 | /** |
| 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 | | |
| 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 ); |
| 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 | } |