WordPress.org

Make WordPress Core

Ticket #12821: 12821-wp-query.diff

File 12821-wp-query.diff, 9.3 KB (added by mdawaffe, 8 years ago)

WP_Query

  • src/wp-includes/post.php

     
    42424242                'authors' => '', 'parent' => -1, 'exclude_tree' => array(),
    42434243                'number' => '', 'offset' => 0,
    42444244                'post_type' => 'page', 'post_status' => 'publish',
     4245                'suppress_filters' => true,
    42454246        );
    42464247
    42474248        $r = wp_parse_args( $args, $defaults );
     4249        // wp_dropdown_pages() has a 'name' argument, which is not compatible with WP_Query's 'name' argument
     4250        $r = array_intersect_key( $r, $defaults );
    42484251
    4249         $number = (int) $r['number'];
    4250         $offset = (int) $r['offset'];
    42514252        $child_of = (int) $r['child_of'];
    42524253        $hierarchical = $r['hierarchical'];
    4253         $exclude = $r['exclude'];
    4254         $meta_key = $r['meta_key'];
    4255         $meta_value = $r['meta_value'];
    4256         $parent = $r['parent'];
    42574254        $post_status = $r['post_status'];
    42584255
    42594256        // Make sure the post type is hierarchical
     
    42624259                return false;
    42634260        }
    42644261
    4265         if ( $parent > 0 && ! $child_of ) {
     4262        if ( $r['parent'] > 0 && ! $child_of ) {
    42664263                $hierarchical = false;
    42674264        }
    42684265
    42694266        // Make sure we have a valid post status
    42704267        if ( ! is_array( $post_status ) ) {
    4271                 $post_status = explode( ',', $post_status );
     4268                $post_status = preg_split( '/[\s,]+/', $post_status );
    42724269        }
    42734270        if ( array_diff( $post_status, get_post_stati() ) ) {
    42744271                return false;
     
    42914288                return $pages;
    42924289        }
    42934290
    4294         $inclusions = '';
     4291        $r['number'] = (int) $r['number'];
     4292        if ( ! $r['number'] ) {
     4293                $r['posts_per_page'] = -1;
     4294        } else {
     4295                $r['posts_per_page'] = $r['number'];
     4296        }
     4297
    42954298        if ( ! empty( $r['include'] ) ) {
    4296                 $child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include
    4297                 $parent = -1;
    4298                 $exclude = '';
    4299                 $meta_key = '';
    4300                 $meta_value = '';
    4301                 $hierarchical = false;
    43024299                $incpages = wp_parse_id_list( $r['include'] );
    4303                 if ( ! empty( $incpages ) ) {
    4304                         $inclusions = ' AND ID IN (' . implode( ',', $incpages ) .  ')';
    4305                 }
    4306         }
     4300                $r['posts_per_page'] = count( $incpages ); // only the number of posts included
     4301                $r['post__in'] = $incpages;
    43074302
    4308         $exclusions = '';
    4309         if ( ! empty( $exclude ) ) {
    4310                 $expages = wp_parse_id_list( $exclude );
    4311                 if ( ! empty( $expages ) ) {
    4312                         $exclusions = ' AND ID NOT IN (' . implode( ',', $expages ) .  ')';
    4313                 }
     4303                // ignore child_of, parent, meta_key, and meta_value params if using include
     4304                $child_of = 0;
     4305                $r['parent'] = -1;
     4306                $hierarchical = false;
     4307                unset( $r['meta_key'] );
     4308                unset( $r['meta_value'] );
     4309        } elseif ( ! empty( $r['exclude'] ) ) {
     4310                $r['post__not_in'] = wp_parse_id_list( $r['exclude'] );
    43144311        }
    43154312
    4316         $author_query = '';
    43174313        if ( ! empty( $r['authors'] ) ) {
    4318                 $post_authors = preg_split( '/[\s,]+/', $r['authors'] );
     4314                if ( ! is_array( $r['authors'] ) ) {
     4315                        $r['authors'] = preg_split( '/[\s,]+/', $r['authors'] );
     4316                }
    43194317
    4320                 if ( ! empty( $post_authors ) ) {
    4321                         foreach ( $post_authors as $post_author ) {
    4322                                 //Do we have an author id or an author login?
    4323                                 if ( 0 == intval($post_author) ) {
    4324                                         $post_author = get_user_by('login', $post_author);
     4318                if ( ! empty( $r['authors'] ) ) {
     4319                        $r['author__in'] = array();
     4320                        foreach ( $r['authors'] as $post_author ) {
     4321                                // Do we have an author id or an author login?
     4322                                if ( ! intval( $post_author ) ) {
     4323                                        $post_author = get_user_by( 'login', $post_author );
    43254324                                        if ( empty( $post_author ) ) {
    43264325                                                continue;
    43274326                                        }
     
    43314330                                        $post_author = $post_author->ID;
    43324331                                }
    43334332
    4334                                 if ( '' == $author_query ) {
    4335                                         $author_query = $wpdb->prepare(' post_author = %d ', $post_author);
    4336                                 } else {
    4337                                         $author_query .= $wpdb->prepare(' OR post_author = %d ', $post_author);
    4338                                 }
     4333                                $r['author__in'][] = (int) $post_author;
    43394334                        }
    4340                         if ( '' != $author_query ) {
    4341                                 $author_query = " AND ($author_query)";
    4342                         }
    43434335                }
    43444336        }
    43454337
    4346         $join = '';
    4347         $where = "$exclusions $inclusions ";
    4348         if ( '' !== $meta_key || '' !== $meta_value ) {
    4349                 $join = " LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )";
    4350 
    4351                 // meta_key and meta_value might be slashed
    4352                 $meta_key = wp_unslash($meta_key);
    4353                 $meta_value = wp_unslash($meta_value);
    4354                 if ( '' !== $meta_key ) {
    4355                         $where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_key = %s", $meta_key);
    4356                 }
    4357                 if ( '' !== $meta_value ) {
    4358                         $where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_value = %s", $meta_value);
    4359                 }
    4360 
     4338        // meta_key and meta_value might be slashed
     4339        if ( ! empty( $r['meta_key'] ) ) {
     4340                $r['meta_key'] = wp_unslash( $r['meta_key'] );
    43614341        }
    43624342
    4363         if ( is_array( $parent ) ) {
    4364                 $post_parent__in = implode( ',', array_map( 'absint', (array) $parent ) );
    4365                 if ( ! empty( $post_parent__in ) ) {
    4366                         $where .= " AND post_parent IN ($post_parent__in)";
    4367                 }
    4368         } elseif ( $parent >= 0 ) {
    4369                 $where .= $wpdb->prepare(' AND post_parent = %d ', $parent);
     4343        if ( ! empty( $r['meta_value'] ) ) {
     4344                $r['meta_value'] = wp_unslash( $r['meta_value'] );
    43704345        }
    43714346
    4372         if ( 1 == count( $post_status ) ) {
    4373                 $where_post_type = $wpdb->prepare( "post_type = %s AND post_status = %s", $r['post_type'], array_shift( $post_status ) );
     4347        if ( is_array( $r['parent'] ) ) {
     4348                $r['post_parent__in'] = $r['parent'];
    43744349        } else {
    4375                 $post_status = implode( "', '", $post_status );
    4376                 $where_post_type = $wpdb->prepare( "post_type = %s AND post_status IN ('$post_status')", $r['post_type'] );
     4350                $r['parent'] = (int) $r['parent'];
     4351                if ( 0 <= $r['parent'] ) {
     4352                        $r['post_parent'] = $r['parent'];
     4353                }
    43774354        }
    43784355
    4379         $orderby_array = array();
    4380         $allowed_keys = array( 'author', 'post_author', 'date', 'post_date', 'title', 'post_title', 'name', 'post_name', 'modified',
    4381                 'post_modified', 'modified_gmt', 'post_modified_gmt', 'menu_order', 'parent', 'post_parent',
    4382                 'ID', 'rand', 'comment_count' );
     4356        $orderby = array();
     4357        $allowed_keys = array( 'author', 'date', 'title', 'name', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count' );
     4358        foreach ( preg_split( '/[\s,]+/', $r['sort_column'] ) as $sort_column ) {
     4359                if ( 0 === strpos( $sort_column, 'post_' ) ) {
     4360                        $sort_column = substr( $sort_column, 5 );
     4361                }
    43834362
    4384         foreach ( explode( ',', $r['sort_column'] ) as $orderby ) {
    4385                 $orderby = trim( $orderby );
    4386                 if ( ! in_array( $orderby, $allowed_keys ) ) {
    4387                         continue;
     4363                if ( 'modified_gmt' == $orderby ) {
     4364                        _deprecated_argument( __FUNCTION__, 4.1 );
     4365                        $sort_column = 'modified';
    43884366                }
    43894367
    4390                 switch ( $orderby ) {
    4391                         case 'menu_order':
    4392                                 break;
    4393                         case 'ID':
    4394                                 $orderby = "$wpdb->posts.ID";
    4395                                 break;
    4396                         case 'rand':
    4397                                 $orderby = 'RAND()';
    4398                                 break;
    4399                         case 'comment_count':
    4400                                 $orderby = "$wpdb->posts.comment_count";
    4401                                 break;
    4402                         default:
    4403                                 if ( 0 === strpos( $orderby, 'post_' ) ) {
    4404                                         $orderby = "$wpdb->posts." . $orderby;
    4405                                 } else {
    4406                                         $orderby = "$wpdb->posts.post_" . $orderby;
    4407                                 }
     4368                if ( ! in_array( $sort_column, $allowed_keys ) ) {
     4369                        continue;
    44084370                }
    44094371
    4410                 $orderby_array[] = $orderby;
     4372                $orderby[] = $sort_column;
     4373        }
    44114374
     4375        if ( empty( $orderby ) ) {
     4376                $r['orderby'] = 'title';
     4377        } else {
     4378                $r['orderby'] = implode( ' ', array_unique( $orderby ) );
    44124379        }
    4413         $sort_column = ! empty( $orderby_array ) ? implode( ',', $orderby_array ) : "$wpdb->posts.post_title";
    44144380
    4415         $sort_order = strtoupper( $r['sort_order'] );
    4416         if ( '' !== $sort_order && ! in_array( $sort_order, array( 'ASC', 'DESC' ) ) ) {
    4417                 $sort_order = 'ASC';
     4381        $r['order'] = strtoupper( $r['sort_order'] );
     4382        if ( '' !== $r['order'] && ! in_array( $r['order'], array( 'ASC', 'DESC' ) ) ) {
     4383                $r['order'] = 'ASC';
    44184384        }
    44194385
    4420         $query = "SELECT * FROM $wpdb->posts $join WHERE ($where_post_type) $where ";
    4421         $query .= $author_query;
    4422         $query .= " ORDER BY " . $sort_column . " " . $sort_order ;
     4386        $r['ignore_sticky_posts'] = true;
     4387        $r['no_found_rows'] = true;
    44234388
    4424         if ( ! empty( $number ) ) {
    4425                 $query .= ' LIMIT ' . $offset . ',' . $number;
    4426         }
     4389        $page_query = new WP_Query;
     4390        $pages = $page_query->query( $r );
    44274391
    4428         $pages = $wpdb->get_results($query);
    4429 
    44304392        if ( empty($pages) ) {
    44314393                /** This filter is documented in wp-includes/post.php */
    44324394                $pages = apply_filters( 'get_pages', array(), $r );
    44334395                return $pages;
    44344396        }
    44354397
    4436         // Sanitize before caching so it'll only get done once
    4437         $num_pages = count($pages);
    4438         for ($i = 0; $i < $num_pages; $i++) {
    4439                 $pages[$i] = sanitize_post($pages[$i], 'raw');
    4440         }
    4441 
    4442         // Update cache.
    4443         update_post_cache( $pages );
    4444 
    44454398        if ( $child_of || $hierarchical ) {
    44464399                $pages = get_page_children($child_of, $pages);
    44474400        }
     
    44554408                        }
    44564409                }
    44574410
    4458                 $num_pages = count( $pages );
    4459                 for ( $i = 0; $i < $num_pages; $i++ ) {
     4411                foreach ( array_keys( $pages ) as $i ) {
    44604412                        if ( in_array( $pages[$i]->ID, $exclude ) ) {
    44614413                                unset( $pages[$i] );
    44624414                        }
     
    44704422
    44714423        wp_cache_set( $cache_key, $page_structure, 'posts' );
    44724424
    4473         // Convert to WP_Post instances
    4474         $pages = array_map( 'get_post', $pages );
    4475 
    44764425        /**
    44774426         * Filter the retrieved list of pages.
    44784427         *
  • tests/phpunit/tests/post/getPages.php

     
    7171                $pages = get_pages( array( 'number' => 10 ) );
    7272                $this->assertEquals( 10, count( $pages ) );
    7373                $this->assertEquals( $time2, wp_cache_get( 'last_changed', 'posts' ) );
    74                 $this->assertEquals( $num_queries + 1, $wpdb->num_queries );
     74                $this->assertEquals( $num_queries + 3, $wpdb->num_queries );
    7575                foreach ( $pages as $page )
    7676                        $this->assertInstanceOf( 'WP_Post', $page );
    7777