Skip to content

Instantly share code, notes, and snippets.

@dbernar1
Created January 20, 2012 05:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dbernar1/1645467 to your computer and use it in GitHub Desktop.
Save dbernar1/1645467 to your computer and use it in GitHub Desktop.
Refactoring of get_pages()
/**
* Retrieve a list of pages.
*
* The defaults that can be overridden are the following: 'child_of',
* 'sort_order', 'sort_column', 'post_title', 'hierarchical', 'exclude',
* 'include', 'meta_key', 'meta_value','authors', 'number', and 'offset'.
*
* @since 1.5.0
* @uses $wpdb
*
* @param mixed $args Optional. Array or string of options that overrides defaults.
* @return array List of pages matching defaults or $args
*/
function &get_pages($args = '') {
$defaults = array(
'child_of' => 0, 'sort_order' => 'ASC',
'sort_column' => 'post_title', 'hierarchical' => 1,
'exclude' => array(), 'include' => array(),
'meta_key' => '', 'meta_value' => '',
'authors' => '', 'parent' => '', 'exclude_tree' => '',
'number' => '', 'offset' => 0,
'post_type' => 'page', 'post_status' => 'publish',
);
$r = wp_parse_args( $args, $defaults );
extract( $r, EXTR_SKIP );
//ignore child_of, parent, exclude, meta_key, and meta_value params if using include
if ( !empty($include) ) {
$child_of = 0;
$parent = '';
$exclude = '';
$meta_key = '';
$meta_value = '';
$hierarchical = false;
}
// Make sure the post type is hierarchical
// TODO extract this to something like is_a_hierarchical_post_type( $post_type )
$hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) );
if ( !in_array( $post_type, $hierarchical_post_types ) )
return false;
$sort_order = strtoupper( $sort_order );
if ( empty( $sort_order ) && ! in_array( $sort_order, array( 'ASC', 'DESC' ) ) )
$sort_order = 'ASC';
// Check whether we have cached the results of the same query
$cache = array();
$key = md5( serialize( compact(array_keys($defaults)) ) );
if ( $cache = wp_cache_get( 'get_pages', 'posts' ) ) {
if ( is_array( $cache ) && isset( $cache[ $key ] ) ) {
$pages = apply_filters( 'get_pages', $cache[ $key ], $r );
return $pages;
}
}
if ( ! is_array( $cache ) )
$cache = array();
// TODO Break up the collection of ids_of_requested_pages_to_include from the creation of the SQL string based on it.
// TODO Rename $post_authors to $requested_authors
if ( ! empty( $authors ) ) {
$post_authors = preg_split( '/[\s,]+/',$authors );
if ( ! empty( $post_authors ) ) {
foreach ( $post_authors as $post_author ) {
//Do we have an author id or an author login?
if ( 0 == intval( $post_author ) ) {
$post_author = get_user_by( 'login', $post_author );
if ( empty( $post_author ) || empty( $post_author->ID ) )
continue;
$author_ids[] = $post_author->ID;
} else {
$author_ids[] = $post_author;
}
}
}
$r['author'] = join( ',', $author_ids );
}
// get_pages() API supports both post_author and author for sorting, and WP_Query only supports the version without the post_ prefix
// TODO get_pages had this additional sorting field. Figure out what to do about this one: $allowed_keys = array( 'modified_gmt', 'post_modified_gmt' );
$sort_column = str_replace( array( 'post_', ',' ), array( '', ' ' ), $sort_column );
// Do the translations
/* get_pages => WP_Query mapping:
* sort_order => order
* sort_column => orderby
* authors => author / author_name
* number => posts_per_page
* include => post__in
* exclude => post__not_in
*
*/
if ( ! empty( $r['number'] ) && empty( $r['posts_per_page'] ) )
$r['posts_per_page'] = $r['number'];
if ( ! empty( $include ) ) {
$incposts = wp_parse_id_list( $include );
$r['posts_per_page'] = count($incposts); // only the number of posts included
$r['post__in'] = $incposts;
} elseif ( ! empty( $exclude ) )
$r['post__not_in'] = wp_parse_id_list( $exclude );
if ( ! empty( $sort_order ) )
$r['order'] = $sort_order;
if ( ! empty( $sort_column ) )
$r['orderby'] = $sort_column;
$r['ignore_sticky_posts'] = true;
$r['no_found_rows'] = true;
$get_pages = new WP_Query;
$pages = $get_pages->query( $r );
if ( empty($pages) ) {
$pages = apply_filters('get_pages', array(), $r);
return $pages;
}
// Update cache.
update_page_cache($pages);
if ( $child_of || $hierarchical )
$pages = & get_page_children($child_of, $pages);
if ( !empty($exclude_tree) ) {
$exclude = (int) $exclude_tree;
$children = get_page_children($exclude, $pages);
$excludes = array();
foreach ( $children as $child )
$excludes[] = $child->ID;
$excludes[] = $exclude;
$num_pages = count($pages);
for ( $i = 0; $i < $num_pages; $i++ ) {
if ( in_array($pages[$i]->ID, $excludes) )
unset($pages[$i]);
}
}
// TODO rename $key to unique_id_for_a_given_set_of_params
$cache[ $key ] = $pages;
wp_cache_set( 'get_pages', $cache, 'posts' );
$pages = apply_filters('get_pages', $pages, $r);
return $pages;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment