Index: post.php
===================================================================
--- post.php	(revision 19734)
+++ post.php	(working copy)
@@ -3314,7 +3314,7 @@
  * Retrieve a list of pages.
  *
  * The defaults that can be overridden are the following: 'child_of',
- * 'sort_order', 'sort_column', 'post_title', 'hierarchical', 'exclude',
+ * 'sort_order', 'sort_column', 'hierarchical', 'exclude',
  * 'include', 'meta_key', 'meta_value','authors', 'number', and 'offset'.
  *
  * @since 1.5.0
@@ -3324,7 +3324,6 @@
  * @return array List of pages matching defaults or $args
  */
 function &get_pages($args = '') {
-	global $wpdb;
 
 	$defaults = array(
 		'child_of' => 0, 'sort_order' => 'ASC',
@@ -3337,177 +3336,94 @@
 	);
 
 	$r = wp_parse_args( $args, $defaults );
-	extract( $r, EXTR_SKIP );
-	$number = (int) $number;
-	$offset = (int) $offset;
+  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 = -1;
+		$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;
 
-	// Make sure we have a valid post status
-	if ( !is_array( $post_status ) )
-		$post_status = explode( ',', $post_status );
-	if ( array_diff( $post_status, get_post_stati() ) )
-		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 );
+		if ( is_array( $cache ) && isset( $cache[ $key ] ) ) {
+			$pages = apply_filters( 'get_pages', $cache[ $key ], $r );
 			return $pages;
 		}
 	}
 
-	if ( !is_array($cache) )
+	if ( ! is_array( $cache ) )
 		$cache = array();
 
-	$inclusions = '';
-	if ( !empty($include) ) {
-		$child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include
-		$parent = -1;
-		$exclude = '';
-		$meta_key = '';
-		$meta_value = '';
-		$hierarchical = false;
-		$incpages = wp_parse_id_list( $include );
-		if ( ! empty( $incpages ) ) {
-			foreach ( $incpages as $incpage ) {
-				if (empty($inclusions))
-					$inclusions = $wpdb->prepare(' AND ( ID = %d ', $incpage);
-				else
-					$inclusions .= $wpdb->prepare(' OR ID = %d ', $incpage);
-			}
-		}
-	}
-	if (!empty($inclusions))
-		$inclusions .= ')';
+  // TODO Rename $post_authors to $requested_authors
+	if ( ! empty( $authors ) ) {
+		$post_authors = preg_split( '/[\s,]+/',$authors );
 
-	$exclusions = '';
-	if ( !empty($exclude) ) {
-		$expages = wp_parse_id_list( $exclude );
-		if ( ! empty( $expages ) ) {
-			foreach ( $expages as $expage ) {
-				if (empty($exclusions))
-					$exclusions = $wpdb->prepare(' AND ( ID <> %d ', $expage);
-				else
-					$exclusions .= $wpdb->prepare(' AND ID <> %d ', $expage);
-			}
-		}
-	}
-	if (!empty($exclusions))
-		$exclusions .= ')';
-
-	$author_query = '';
-	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) )
+				if ( 0 == intval( $post_author ) ) {
+					$post_author = get_user_by( 'login', $post_author );
+					if ( empty( $post_author ) || empty( $post_author->ID ) )
 						continue;
-					if ( empty($post_author->ID) )
-						continue;
-					$post_author = $post_author->ID;
-				}
-
-				if ( '' == $author_query )
-					$author_query = $wpdb->prepare(' post_author = %d ', $post_author);
-				else
-					$author_query .= $wpdb->prepare(' OR post_author = %d ', $post_author);
-			}
-			if ( '' != $author_query )
-				$author_query = " AND ($author_query)";
+					$author_ids[] = $post_author->ID;
+				} else {
+          $author_ids[] = $post_author;
+        }
+      }
 		}
+    $r['author'] = join( ',', $author_ids );
 	}
 
-	$join = '';
-	$where = "$exclusions $inclusions ";
-	if ( ! empty( $meta_key ) || ! empty( $meta_value ) ) {
-		$join = " LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )";
+  // get_pages() API supports both post_author and author for sorting, and WP_Query only supports the version without the post_ prefix
+  // get_pages accepts comma-separated list of sort_columns, and WP_Query accepts a space-separated one
+	// 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 );
 
-		// meta_key and meta_value might be slashed
-		$meta_key = stripslashes($meta_key);
-		$meta_value = stripslashes($meta_value);
-		if ( ! empty( $meta_key ) )
-			$where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_key = %s", $meta_key);
-		if ( ! empty( $meta_value ) )
-			$where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_value = %s", $meta_value);
+	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 ( $parent >= 0 )
-		$where .= $wpdb->prepare(' AND post_parent = %d ', $parent);
+  if ( ! empty( $sort_column ) )
+    $r['orderby'] = $sort_column;
+  if ( $parent >= 0 )
+    $r['post_parent'] = $parent;
 
-	if ( 1 == count( $post_status ) ) {
-		$where_post_type = $wpdb->prepare( "post_type = %s AND post_status = %s", $post_type, array_shift( $post_status ) );
-	} else {
-		$post_status = implode( "', '", $post_status );
-		$where_post_type = $wpdb->prepare( "post_type = %s AND post_status IN ('$post_status')", $post_type );
-	}
+	$r['ignore_sticky_posts'] = true;
+	$r['no_found_rows'] = true;
 
-	$orderby_array = array();
-	$allowed_keys = array('author', 'post_author', 'date', 'post_date', 'title', 'post_title', 'name', 'post_name', 'modified',
-						  'post_modified', 'modified_gmt', 'post_modified_gmt', 'menu_order', 'parent', 'post_parent',
-						  'ID', 'rand', 'comment_count');
-	foreach ( explode( ',', $sort_column ) as $orderby ) {
-		$orderby = trim( $orderby );
-		if ( !in_array( $orderby, $allowed_keys ) )
-			continue;
+  $get_pages = new WP_Query;
+	$pages = $get_pages->query( $r );
 
-		switch ( $orderby ) {
-			case 'menu_order':
-				break;
-			case 'ID':
-				$orderby = "$wpdb->posts.ID";
-				break;
-			case 'rand':
-				$orderby = 'RAND()';
-				break;
-			case 'comment_count':
-				$orderby = "$wpdb->posts.comment_count";
-				break;
-			default:
-				if ( 0 === strpos( $orderby, 'post_' ) )
-					$orderby = "$wpdb->posts." . $orderby;
-				else
-					$orderby = "$wpdb->posts.post_" . $orderby;
-		}
-
-		$orderby_array[] = $orderby;
-
-	}
-	$sort_column = ! empty( $orderby_array ) ? implode( ',', $orderby_array ) : "$wpdb->posts.post_title";
-
-	$sort_order = strtoupper( $sort_order );
-	if ( '' !== $sort_order && !in_array( $sort_order, array( 'ASC', 'DESC' ) ) )
-		$sort_order = 'ASC';
-
-	$query = "SELECT * FROM $wpdb->posts $join WHERE ($where_post_type) $where ";
-	$query .= $author_query;
-	$query .= " ORDER BY " . $sort_column . " " . $sort_order ;
-
-	if ( !empty($number) )
-		$query .= ' LIMIT ' . $offset . ',' . $number;
-
-	$pages = $wpdb->get_results($query);
-
 	if ( empty($pages) ) {
 		$pages = apply_filters('get_pages', array(), $r);
 		return $pages;
 	}
 
-	// Sanitize before caching so it'll only get done once
-	$num_pages = count($pages);
-	for ($i = 0; $i < $num_pages; $i++) {
-		$pages[$i] = sanitize_post($pages[$i], 'raw');
-	}
-
 	// Update cache.
 	update_page_cache($pages);
 
@@ -3528,6 +3444,7 @@
 		}
 	}
 
+  // TODO rename $key to unique_id_for_a_given_set_of_params
 	$cache[ $key ] = $pages;
 	wp_cache_set( 'get_pages', $cache, 'posts' );
 
