Make WordPress Core


Ignore:
Timestamp:
03/21/2023 12:47:20 PM (3 months ago)
Author:
spacedmonkey
Message:

Posts, Post Types: Use WP_Query internally in get_pages.

Convert get_pages to use WP_Query internally. Using WP_Query means that a lot of code has been removed however existing parameters supported by get_pages are transformed in to query arguments. The custom caching solution found in the old version of this function is replaced with the caching found in WP_Query (added in [53941]). This change adds consistency to the codebase, as improvements and changes to WP_Query will filter down to the get_pages function.

Props mikeschinkel, spacedmonkey, nacin, scribu, filosofo, jane, garyc40, markoheijnen, grandslambert, kevinB, wlindley, dbernar1, atimmer, mdawaffe, helen, benjibee, johnbillion, peterwilsoncc, costdev, flixos90, joemcgill.
Fixes #12821.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/post.php

    r55526 r55569  
    58875887 * Retrieves an array of pages (or hierarchical post type items).
    58885888 *
    5889  * @global wpdb $wpdb WordPress database abstraction object.
    5890  *
    58915889 * @since 1.5.0
     5890 * @since 6.3.0 Use WP_Query internally.
    58925891 *
    58935892 * @param array|string $args {
     
    59295928 */
    59305929function get_pages( $args = array() ) {
    5931     global $wpdb;
    5932 
    59335930    $defaults = array(
    59345931        'child_of'     => 0,
     
    59795976    }
    59805977
    5981     // $args can be whatever, only use the args defined in defaults to compute the key.
    5982     $key          = md5( serialize( wp_array_slice_assoc( $parsed_args, array_keys( $defaults ) ) ) );
    5983     $last_changed = wp_cache_get_last_changed( 'posts' );
    5984 
    5985     $cache_key = "get_pages:$key:$last_changed";
    5986     $cache     = wp_cache_get( $cache_key, 'post-queries' );
    5987     if ( false !== $cache ) {
    5988         _prime_post_caches( $cache, false, false );
    5989 
    5990         // Convert to WP_Post instances.
    5991         $pages = array_map( 'get_post', $cache );
    5992         /** This filter is documented in wp-includes/post.php */
    5993         $pages = apply_filters( 'get_pages', $pages, $parsed_args );
    5994 
    5995         return $pages;
    5996     }
    5997 
    5998     $inclusions = '';
     5978    $query_args = array(
     5979        'orderby'                => 'post_title',
     5980        'order'                  => 'ASC',
     5981        'post__not_in'           => wp_parse_id_list( $exclude ),
     5982        'meta_key'               => $meta_key,
     5983        'meta_value'             => $meta_value,
     5984        'posts_per_page'         => -1,
     5985        'offset'                 => $offset,
     5986        'post_type'              => $parsed_args['post_type'],
     5987        'post_status'            => $post_status,
     5988        'update_post_term_cache' => false,
     5989        'update_post_meta_cache' => false,
     5990        'ignore_sticky_posts'    => true,
     5991        'no_found_rows'          => true,
     5992    );
     5993
    59995994    if ( ! empty( $parsed_args['include'] ) ) {
    6000         $child_of     = 0; // Ignore child_of, parent, exclude, meta_key, and meta_value params if using include.
    6001         $parent       = -1;
    6002         $exclude      = '';
    6003         $meta_key     = '';
    6004         $meta_value   = '';
    6005         $hierarchical = false;
    6006         $incpages     = wp_parse_id_list( $parsed_args['include'] );
    6007         if ( ! empty( $incpages ) ) {
    6008             $inclusions = ' AND ID IN (' . implode( ',', $incpages ) . ')';
    6009         }
    6010     }
    6011 
    6012     $exclusions = '';
    6013     if ( ! empty( $exclude ) ) {
    6014         $expages = wp_parse_id_list( $exclude );
    6015         if ( ! empty( $expages ) ) {
    6016             $exclusions = ' AND ID NOT IN (' . implode( ',', $expages ) . ')';
    6017         }
    6018     }
    6019 
    6020     $author_query = '';
     5995        $child_of = 0; // Ignore child_of, parent, exclude, meta_key, and meta_value params if using include.
     5996        $parent   = -1;
     5997        unset( $query_args['post__not_in'], $query_args['meta_key'], $query_args['meta_value'] );
     5998        $hierarchical           = false;
     5999        $query_args['post__in'] = wp_parse_id_list( $parsed_args['include'] );
     6000    }
     6001
    60216002    if ( ! empty( $parsed_args['authors'] ) ) {
    60226003        $post_authors = wp_parse_list( $parsed_args['authors'] );
    60236004
    60246005        if ( ! empty( $post_authors ) ) {
     6006            $query_args['author__in'] = array();
    60256007            foreach ( $post_authors as $post_author ) {
    60266008                // Do we have an author id or an author login?
     
    60356017                    $post_author = $post_author->ID;
    60366018                }
    6037 
    6038                 if ( '' === $author_query ) {
    6039                     $author_query = $wpdb->prepare( ' post_author = %d ', $post_author );
    6040                 } else {
    6041                     $author_query .= $wpdb->prepare( ' OR post_author = %d ', $post_author );
    6042                 }
     6019                $query_args['author__in'][] = $post_author;
    60436020            }
    6044             if ( '' !== $author_query ) {
    6045                 $author_query = " AND ($author_query)";
    6046             }
    6047         }
    6048     }
    6049 
    6050     $join  = '';
    6051     $where = "$exclusions $inclusions ";
    6052     if ( '' !== $meta_key || '' !== $meta_value ) {
    6053         $join = " LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )";
    6054 
    6055         // meta_key and meta_value might be slashed.
    6056         $meta_key   = wp_unslash( $meta_key );
    6057         $meta_value = wp_unslash( $meta_value );
    6058         if ( '' !== $meta_key ) {
    6059             $where .= $wpdb->prepare( " AND $wpdb->postmeta.meta_key = %s", $meta_key );
    6060         }
    6061         if ( '' !== $meta_value ) {
    6062             $where .= $wpdb->prepare( " AND $wpdb->postmeta.meta_value = %s", $meta_value );
    60636021        }
    60646022    }
    60656023
    60666024    if ( is_array( $parent ) ) {
    6067         $post_parent__in = implode( ',', array_map( 'absint', (array) $parent ) );
     6025        $post_parent__in = array_map( 'absint', (array) $parent );
    60686026        if ( ! empty( $post_parent__in ) ) {
    6069             $where .= " AND post_parent IN ($post_parent__in)";
     6027            $query_args['post_parent__in'] = $post_parent__in;
    60706028        }
    60716029    } elseif ( $parent >= 0 ) {
    6072         $where .= $wpdb->prepare( ' AND post_parent = %d ', $parent );
    6073     }
    6074 
    6075     if ( 1 === count( $post_status ) ) {
    6076         $where_post_type = $wpdb->prepare( 'post_type = %s AND post_status = %s', $parsed_args['post_type'], reset( $post_status ) );
    6077     } else {
    6078         $post_status     = implode( "', '", $post_status );
    6079         $where_post_type = $wpdb->prepare( "post_type = %s AND post_status IN ('$post_status')", $parsed_args['post_type'] );
    6080     }
    6081 
    6082     $orderby_array = array();
    6083     $allowed_keys  = array(
    6084         'author',
    6085         'post_author',
    6086         'date',
    6087         'post_date',
    6088         'title',
    6089         'post_title',
    6090         'name',
    6091         'post_name',
    6092         'modified',
    6093         'post_modified',
    6094         'modified_gmt',
    6095         'post_modified_gmt',
    6096         'menu_order',
    6097         'parent',
    6098         'post_parent',
    6099         'ID',
    6100         'rand',
    6101         'comment_count',
    6102     );
    6103 
    6104     foreach ( explode( ',', $parsed_args['sort_column'] ) as $orderby ) {
    6105         $orderby = trim( $orderby );
    6106         if ( ! in_array( $orderby, $allowed_keys, true ) ) {
    6107             continue;
    6108         }
    6109 
    6110         switch ( $orderby ) {
    6111             case 'menu_order':
    6112                 break;
    6113             case 'ID':
    6114                 $orderby = "$wpdb->posts.ID";
    6115                 break;
    6116             case 'rand':
    6117                 $orderby = 'RAND()';
    6118                 break;
    6119             case 'comment_count':
    6120                 $orderby = "$wpdb->posts.comment_count";
    6121                 break;
    6122             default:
    6123                 if ( 0 === strpos( $orderby, 'post_' ) ) {
    6124                     $orderby = "$wpdb->posts." . $orderby;
    6125                 } else {
    6126                     $orderby = "$wpdb->posts.post_" . $orderby;
    6127                 }
    6128         }
    6129 
    6130         $orderby_array[] = $orderby;
    6131 
    6132     }
    6133     $sort_column = ! empty( $orderby_array ) ? implode( ',', $orderby_array ) : "$wpdb->posts.post_title";
    6134 
    6135     $sort_order = strtoupper( $parsed_args['sort_order'] );
    6136     if ( '' !== $sort_order && ! in_array( $sort_order, array( 'ASC', 'DESC' ), true ) ) {
    6137         $sort_order = 'ASC';
    6138     }
    6139 
    6140     $query  = "SELECT * FROM $wpdb->posts $join WHERE ($where_post_type) $where ";
    6141     $query .= $author_query;
    6142     $query .= ' ORDER BY ' . $sort_column . ' ' . $sort_order;
     6030        $query_args['post_parent'] = $parent;
     6031    }
     6032
     6033    $orderby = wp_parse_list( $parsed_args['sort_column'] );
     6034    $orderby = array_map( 'trim', $orderby );
     6035    if ( $orderby ) {
     6036        $query_args['orderby'] = array_fill_keys( $orderby, $parsed_args['sort_order'] );
     6037    }
     6038
     6039    $order = $parsed_args['sort_order'];
     6040    if ( $order ) {
     6041        $query_args['order'] = $order;
     6042    }
    61436043
    61446044    if ( ! empty( $number ) ) {
    6145         $query .= ' LIMIT ' . $offset . ',' . $number;
    6146     }
    6147 
    6148     $pages = $wpdb->get_results( $query );
    6149 
    6150     if ( empty( $pages ) ) {
    6151         wp_cache_set( $cache_key, array(), 'post-queries' );
    6152 
    6153         /** This filter is documented in wp-includes/post.php */
    6154         $pages = apply_filters( 'get_pages', array(), $parsed_args );
    6155 
    6156         return $pages;
    6157     }
    6158 
    6159     // Sanitize before caching so it'll only get done once.
    6160     $num_pages = count( $pages );
    6161     for ( $i = 0; $i < $num_pages; $i++ ) {
    6162         $pages[ $i ] = sanitize_post( $pages[ $i ], 'raw' );
    6163     }
    6164 
    6165     // Update cache.
    6166     update_post_cache( $pages );
     6045        $query_args['posts_per_page'] = $number;
     6046    }
     6047
     6048    $query = new WP_Query( $query_args );
     6049    $pages = $query->get_posts();
    61676050
    61686051    if ( $child_of || $hierarchical ) {
     
    61866069        }
    61876070    }
    6188 
    6189     $page_structure = array();
    6190     foreach ( $pages as $page ) {
    6191         $page_structure[] = $page->ID;
    6192     }
    6193 
    6194     wp_cache_set( $cache_key, $page_structure, 'post-queries' );
    6195 
    6196     // Convert to WP_Post instances.
    6197     $pages = array_map( 'get_post', $pages );
    61986071
    61996072    /**
Note: See TracChangeset for help on using the changeset viewer.