]> scripts.mit.edu Git - autoinstalls/wordpress.git/blobdiff - wp-includes/query.php
Wordpress 2.5.1
[autoinstalls/wordpress.git] / wp-includes / query.php
index 564c47b84338de8ee016267e7d60ebd06130f963..8119f2cb5d01aa0dbf489e1e0a679194ce70a70d 100644 (file)
@@ -25,6 +25,11 @@ function &query_posts($query) {
 function wp_reset_query() {
        unset($GLOBALS['wp_query']);
        $GLOBALS['wp_query'] =& $GLOBALS['wp_the_query'];
+       global $wp_query;
+       if ( !empty($wp_query->post) ) {
+               $GLOBALS['post'] = $wp_query->post;
+               setup_postdata($wp_query->post);
+       }
 }
 
 /*
@@ -32,7 +37,7 @@ function wp_reset_query() {
  */
 
 function is_admin () {
-       if ( defined('WP_ADMIN') ) 
+       if ( defined('WP_ADMIN') )
                return WP_ADMIN;
        return false;
 }
@@ -60,11 +65,13 @@ function is_author ($author = '') {
 
        $author_obj = $wp_query->get_queried_object();
 
-       if ( $author == $author_obj->ID )
+       $author = (array) $author;
+
+       if ( in_array( $author_obj->ID, $author ) )
                return true;
-       elseif ( $author == $author_obj->nickname )
+       elseif ( in_array( $author_obj->nickname, $author ) )
                return true;
-       elseif ( $author == $author_obj->user_nicename )
+       elseif ( in_array( $author_obj->user_nicename, $author ) )
                return true;
 
        return false;
@@ -81,11 +88,13 @@ function is_category ($category = '') {
 
        $cat_obj = $wp_query->get_queried_object();
 
-       if ( $category == $cat_obj->term_id )
+       $category = (array) $category;
+
+       if ( in_array( $cat_obj->term_id, $category ) )
                return true;
-       else if ( $category == $cat_obj->name )
+       elseif ( in_array( $cat_obj->name, $category ) )
                return true;
-       elseif ( $category == $cat_obj->slug )
+       elseif ( in_array( $cat_obj->slug, $category ) )
                return true;
 
        return false;
@@ -93,6 +102,7 @@ function is_category ($category = '') {
 
 function is_tag( $slug = '' ) {
        global $wp_query;
+
        if ( !$wp_query->is_tag )
                return false;
 
@@ -100,8 +110,31 @@ function is_tag( $slug = '' ) {
                return true;
 
        $tag_obj = $wp_query->get_queried_object();
-       if ( $slug == $tag_obj->slug )
+
+       $slug = (array) $slug;
+
+       if ( in_array( $tag_obj->slug, $slug ) )
+               return true;
+
+       return false;
+}
+
+function is_tax( $slug = '' ) {
+       global $wp_query;
+       
+       if ( !$wp_query->is_tax )
+               return false;
+
+       if ( empty($slug) )
                return true;
+
+       $term = $wp_query->get_queried_object();
+
+       $slug = (array) $slug;
+
+       if ( in_array( $term->slug, $slug ) )
+               return true;
+
        return false;
 }
 
@@ -129,6 +162,33 @@ function is_feed () {
        return $wp_query->is_feed;
 }
 
+/**
+ * is_front_page() - Is it the front of the site, whether blog view or a WP Page?
+ *
+ * @since 2.5
+ * @uses is_home
+ * @uses get_option
+ *
+ * @return bool True if front of site
+ */
+function is_front_page () {
+       // most likely case
+       if ( 'posts' == get_option('show_on_front') && is_home() )
+               return true;
+       elseif ( 'page' == get_option('show_on_front') && get_option('page_on_front') && is_page(get_option('page_on_front')) )
+               return true;
+       else
+               return false;
+}
+
+/**
+ * is_home() - Is it the blog view homepage?
+ *
+ * @since 2.1
+ * @global object $wp_query
+ *
+ * @return bool True if blog view homepage
+ */
 function is_home () {
        global $wp_query;
 
@@ -152,11 +212,13 @@ function is_page ($page = '') {
 
        $page_obj = $wp_query->get_queried_object();
 
-       if ( $page == $page_obj->ID )
+       $page = (array) $page;
+
+    if ( in_array( $page_obj->ID, $page ) )
                return true;
-       elseif ( $page == $page_obj->post_title )
+       elseif ( in_array( $page_obj->post_title, $page ) )
                return true;
-       else if ( $page == $page_obj->post_name )
+       else if ( in_array( $page_obj->post_name, $page ) )
                return true;
 
        return false;
@@ -206,11 +268,13 @@ function is_single ($post = '') {
 
        $post_obj = $wp_query->get_queried_object();
 
-       if ( $post == $post_obj->ID )
+       $post = (array) $post;
+
+       if ( in_array( $post_obj->ID, $post ) )
                return true;
-       elseif ( $post == $post_obj->post_title )
+       elseif ( in_array( $post_obj->post_title, $post ) )
                return true;
-       elseif ( $post == $post_obj->post_name )
+       elseif ( in_array( $post_obj->post_name, $post ) )
                return true;
 
        return false;
@@ -325,6 +389,7 @@ class WP_Query {
        var $is_author = false;
        var $is_category = false;
        var $is_tag = false;
+       var $is_tax = false;
        var $is_search = false;
        var $is_feed = false;
        var $is_comment_feed = false;
@@ -350,6 +415,7 @@ class WP_Query {
                $this->is_author = false;
                $this->is_category = false;
                $this->is_tag = false;
+               $this->is_tax = false;
                $this->is_search = false;
                $this->is_feed = false;
                $this->is_comment_feed = false;
@@ -453,6 +519,7 @@ class WP_Query {
                $qv['day'] = (int) $qv['day'];
                $qv['w'] = (int) $qv['w'];
                $qv['m'] =  (int) $qv['m'];
+               $qv['cat'] = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // comma separated list of positive or negative integers
                if ( '' !== $qv['hour'] ) $qv['hour'] = (int) $qv['hour'];
                if ( '' !== $qv['minute'] ) $qv['minute'] = (int) $qv['minute'];
                if ( '' !== $qv['second'] ) $qv['second'] = (int) $qv['second'];
@@ -558,7 +625,7 @@ class WP_Query {
                                $this->is_category = true;
                        }
 
-                       if ( !is_array($qv['category___not_in']) || empty($qv['category__not_in']) ) {
+                       if ( !is_array($qv['category__not_in']) || empty($qv['category__not_in']) ) {
                                $qv['category__not_in'] = array();
                        } else {
                                $qv['category__not_in'] = array_map('intval', $qv['category__not_in']);
@@ -585,7 +652,7 @@ class WP_Query {
                                $this->is_tag = true;
                        }
 
-                       if ( !is_array($qv['tag___not_in']) || empty($qv['tag__not_in']) ) {
+                       if ( !is_array($qv['tag__not_in']) || empty($qv['tag__not_in']) ) {
                                $qv['tag__not_in'] = array();
                        } else {
                                $qv['tag__not_in'] = array_map('intval', $qv['tag__not_in']);
@@ -612,6 +679,18 @@ class WP_Query {
                                $this->is_tag = true;
                        }
 
+                       if ( empty($qv['taxonomy']) || empty($qv['term']) ) {
+                               $this->is_tax = false;
+                               foreach ( $GLOBALS['wp_taxonomies'] as $t ) {
+                                       if ( isset($t->query_var) && '' != $qv[$t->query_var] ) {
+                                               $this->is_tax = true;
+                                               break;
+                                       }
+                               }
+                       } else {
+                               $this->is_tax = true;
+                       }
+
                        if ( empty($qv['author']) || ($qv['author'] == '0') ) {
                                $this->is_author = false;
                        } else {
@@ -728,7 +807,7 @@ class WP_Query {
        }
 
        function &get_posts() {
-               global $wpdb, $pagenow, $user_ID;
+               global $wpdb, $user_ID;
 
                do_action_ref_array('pre_get_posts', array(&$this));
 
@@ -741,16 +820,20 @@ class WP_Query {
                $distinct = '';
                $whichcat = '';
                $whichauthor = '';
-               $whichpage = '';
-               $result = '';
+               $whichmimetype = '';
                $where = '';
                $limits = '';
                $join = '';
                $search = '';
                $groupby = '';
+               $post_status_join = false;
 
-               if ( !isset($q['post_type']) )
-                       $q['post_type'] = 'post';
+               if ( !isset($q['post_type']) ) {
+                       if ( $this->is_search )
+                               $q['post_type'] = 'any';
+                       else
+                               $q['post_type'] = 'post';
+               }
                $post_type = $q['post_type'];
                if ( !isset($q['posts_per_page']) || $q['posts_per_page'] == 0 )
                        $q['posts_per_page'] = get_option('posts_per_page');
@@ -789,47 +872,43 @@ class WP_Query {
                        $q['page'] = abs($q['page']);
                }
 
-               $add_hours = intval(get_option('gmt_offset'));
-               $add_minutes = intval(60 * (get_option('gmt_offset') - $add_hours));
-               $wp_posts_post_date_field = "post_date"; // "DATE_ADD(post_date, INTERVAL '$add_hours:$add_minutes' HOUR_MINUTE)";
-
                // If a month is specified in the querystring, load that month
                if ( $q['m'] ) {
                        $q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']);
-                       $where .= ' AND YEAR(post_date)=' . substr($q['m'], 0, 4);
+                       $where .= " AND YEAR($wpdb->posts.post_date)=" . substr($q['m'], 0, 4);
                        if (strlen($q['m'])>5)
-                               $where .= ' AND MONTH(post_date)=' . substr($q['m'], 4, 2);
+                               $where .= " AND MONTH($wpdb->posts.post_date)=" . substr($q['m'], 4, 2);
                        if (strlen($q['m'])>7)
-                               $where .= ' AND DAYOFMONTH(post_date)=' . substr($q['m'], 6, 2);
+                               $where .= " AND DAYOFMONTH($wpdb->posts.post_date)=" . substr($q['m'], 6, 2);
                        if (strlen($q['m'])>9)
-                               $where .= ' AND HOUR(post_date)=' . substr($q['m'], 8, 2);
+                               $where .= " AND HOUR($wpdb->posts.post_date)=" . substr($q['m'], 8, 2);
                        if (strlen($q['m'])>11)
-                               $where .= ' AND MINUTE(post_date)=' . substr($q['m'], 10, 2);
+                               $where .= " AND MINUTE($wpdb->posts.post_date)=" . substr($q['m'], 10, 2);
                        if (strlen($q['m'])>13)
-                               $where .= ' AND SECOND(post_date)=' . substr($q['m'], 12, 2);
+                               $where .= " AND SECOND($wpdb->posts.post_date)=" . substr($q['m'], 12, 2);
                }
 
                if ( '' !== $q['hour'] )
-                       $where .= " AND HOUR(post_date)='" . $q['hour'] . "'";
+                       $where .= " AND HOUR($wpdb->posts.post_date)='" . $q['hour'] . "'";
 
                if ( '' !== $q['minute'] )
-                       $where .= " AND MINUTE(post_date)='" . $q['minute'] . "'";
+                       $where .= " AND MINUTE($wpdb->posts.post_date)='" . $q['minute'] . "'";
 
                if ( '' !== $q['second'] )
-                       $where .= " AND SECOND(post_date)='" . $q['second'] . "'";
+                       $where .= " AND SECOND($wpdb->posts.post_date)='" . $q['second'] . "'";
 
                if ( $q['year'] )
-                       $where .= " AND YEAR(post_date)='" . $q['year'] . "'";
+                       $where .= " AND YEAR($wpdb->posts.post_date)='" . $q['year'] . "'";
 
                if ( $q['monthnum'] )
-                       $where .= " AND MONTH(post_date)='" . $q['monthnum'] . "'";
+                       $where .= " AND MONTH($wpdb->posts.post_date)='" . $q['monthnum'] . "'";
 
                if ( $q['day'] )
-                       $where .= " AND DAYOFMONTH(post_date)='" . $q['day'] . "'";
+                       $where .= " AND DAYOFMONTH($wpdb->posts.post_date)='" . $q['day'] . "'";
 
                if ('' != $q['name']) {
                        $q['name'] = sanitize_title($q['name']);
-                       $where .= " AND post_name = '" . $q['name'] . "'";
+                       $where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'";
                } else if ('' != $q['pagename']) {
                        if ( isset($this->queried_object_id) )
                                $reqpage = $this->queried_object_id;
@@ -847,17 +926,23 @@ class WP_Query {
                                $q['pagename'] = sanitize_title(basename($page_paths));
                                $q['name'] = $q['pagename'];
                                $where .= " AND (ID = '$reqpage')";
+                               $reqpage_obj = get_page($reqpage);
+                               if ( 'attachment' == $reqpage_obj->post_type ) {
+                                       $this->is_attachment = true;
+                                       $this->is_page = true;
+                                       $q['attachment_id'] = $reqpage;
+                               }
                        }
                } elseif ('' != $q['attachment']) {
                        $q['attachment'] = str_replace('%2F', '/', urlencode(urldecode($q['attachment'])));
                        $attach_paths = '/' . trim($q['attachment'], '/');
                        $q['attachment'] = sanitize_title(basename($attach_paths));
                        $q['name'] = $q['attachment'];
-                       $where .= " AND post_name = '" . $q['attachment'] . "'";
+                       $where .= " AND $wpdb->posts.post_name = '" . $q['attachment'] . "'";
                }
 
                if ( $q['w'] )
-                       $where .= " AND WEEK(post_date, 1)='" . $q['w'] . "'";
+                       $where .= " AND WEEK($wpdb->posts.post_date, 1)='" . $q['w'] . "'";
 
                if ( intval($q['comments_popup']) )
                        $q['p'] = intval($q['comments_popup']);
@@ -868,12 +953,12 @@ class WP_Query {
 
                // If a post number is specified, load that post
                if ( $q['p'] )
-                       $where = ' AND ID = ' . $q['p'];
+                       $where = " AND {$wpdb->posts}.ID = " . $q['p'];
 
                if ( $q['page_id'] ) {
                        if  ( ('page' != get_option('show_on_front') ) || ( $q['page_id'] != get_option('page_for_posts') ) ) {
                                $q['p'] = $q['page_id'];
-                               $where = ' AND ID = ' . $q['page_id'];
+                               $where = " AND {$wpdb->posts}.ID = " . $q['page_id'];
                        }
                }
 
@@ -883,8 +968,7 @@ class WP_Query {
                        $q['s'] = stripslashes($q['s']);
                        if ($q['sentence']) {
                                $q['search_terms'] = array($q['s']);
-                       }
-                       else {
+                       } else {
                                preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $q[s], $matches);
                                $q['search_terms'] = array_map(create_function('$a', 'return trim($a, "\\"\'\\n\\r ");'), $matches[0]);
                        }
@@ -892,12 +976,12 @@ class WP_Query {
                        $searchand = '';
                        foreach((array)$q['search_terms'] as $term) {
                                $term = addslashes_gpc($term);
-                               $search .= "{$searchand}((post_title LIKE '{$n}{$term}{$n}') OR (post_content LIKE '{$n}{$term}{$n}'))";
+                               $search .= "{$searchand}(($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}'))";
                                $searchand = ' AND ';
                        }
-                       $term = addslashes_gpc($q['s']);
+                       $term = $wpdb->escape($q['s']);
                        if (!$q['sentence'] && count($q['search_terms']) > 1 && $q['search_terms'][0] != $q['s'] )
-                               $search .= " OR (post_title LIKE '{$n}{$term}{$n}') OR (post_content LIKE '{$n}{$term}{$n}')";
+                               $search .= " OR ($wpdb->posts.post_title LIKE '{$n}{$term}{$n}') OR ($wpdb->posts.post_content LIKE '{$n}{$term}{$n}')";
 
                        if ( !empty($search) )
                                $search = " AND ({$search}) ";
@@ -913,8 +997,11 @@ class WP_Query {
                        $q['cat'] = ''.urldecode($q['cat']).'';
                        $q['cat'] = addslashes_gpc($q['cat']);
                        $cat_array = preg_split('/[,\s]+/', $q['cat']);
+                       $q['cat'] = '';
+                       $req_cats = array();
                        foreach ( $cat_array as $cat ) {
                                $cat = intval($cat);
+                               $req_cats[] = $cat;
                                $in = ($cat > 0);
                                $cat = abs($cat);
                                if ( $in ) {
@@ -925,6 +1012,7 @@ class WP_Query {
                                        $q['category__not_in'] = array_merge($q['category__not_in'], get_term_children($cat, 'category'));
                                }
                        }
+                       $q['cat'] = implode(',', $req_cats);
                }
 
                if ( !empty($q['category__in']) || !empty($q['category__not_in']) || !empty($q['category__and']) ) {
@@ -940,7 +1028,7 @@ class WP_Query {
 
                if ( !empty($q['category__not_in']) ) {
                        $ids = get_objects_in_term($q['category__not_in'], 'category');
-                       if ( is_wp_error( $ids ) ) 
+                       if ( is_wp_error( $ids ) )
                                return $ids;
                        if ( is_array($ids) && count($ids > 0) ) {
                                $out_posts = "'" . implode("', '", $ids) . "'";
@@ -949,7 +1037,7 @@ class WP_Query {
                }
 
                // Category stuff for nice URLs
-               if ( '' != $q['category_name'] ) {
+               if ( '' != $q['category_name'] && !$this->is_singular ) {
                        $reqcat = get_category_by_path($q['category_name']);
                        $q['category_name'] = str_replace('%2F', '/', urlencode(urldecode($q['category_name'])));
                        $cat_paths = '/' . trim($q['category_name'], '/');
@@ -998,14 +1086,7 @@ class WP_Query {
                                }
                        } else {
                                $q['tag'] = sanitize_term_field('slug', $q['tag'], 0, 'post_tag', 'db');
-                               $reqtag = is_term( $q['tag'], 'post_tag' );
-                               if ( !empty($reqtag) )
-                                       $reqtag = $reqtag['term_id'];
-                               else
-                                       $reqtag = 0;
-
-                               $q['tag_id'] = $reqtag;
-                               $q['tag__in'][] = $reqtag;
+                               $q['tag_slug__in'][] = $q['tag'];
                        }
                }
 
@@ -1070,6 +1151,38 @@ class WP_Query {
                        }
                }
 
+               // Taxonomies
+               if ( $this->is_tax ) {
+                       if ( '' != $q['taxonomy'] ) {
+                               $taxonomy = $q['taxonomy'];
+                               $tt[$taxonomy] = $q['term'];
+                               $terms = get_terms($q['taxonomy'], array('slug'=>$q['term']));
+                       } else {
+                               foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t ) {
+                                       if ( isset($t->query_var) && '' != $q[$t->query_var] ) {
+                                               $terms = get_terms($taxonomy, array('slug'=>$q[$t->query_var]));
+                                               if ( !is_wp_error($terms) )
+                                                       break;
+                                       }
+                               }
+                       }
+                       if ( is_wp_error($terms) || empty($terms) ) {
+                               $whichcat = " AND 0 ";
+                       } else {
+                               foreach ( $terms as $term )
+                                       $term_ids[] = $term->term_id;
+                               $post_ids = get_objects_in_term($term_ids, $taxonomy);
+                               if ( !is_wp_error($post_ids) && count($post_ids) ) {
+                                       $whichcat .= " AND $wpdb->posts.ID IN (" . implode(', ', $post_ids) . ") ";
+                                       $post_type = 'any';
+                                       $q['post_status'] = 'publish';
+                                       $post_status_join = true;
+                               } else {
+                                       $whichcat = " AND 0 ";
+                               }
+                       }
+               }
+
                // Author/user stuff
 
                if ( empty($q['author']) || ($q['author'] == '0') ) {
@@ -1087,9 +1200,9 @@ class WP_Query {
                                $andor = 'OR';
                        }
                        $author_array = preg_split('/[,\s]+/', $q['author']);
-                       $whichauthor .= ' AND (post_author '.$eq.' '.intval($author_array[0]);
+                       $whichauthor .= " AND ($wpdb->posts.post_author ".$eq.' '.intval($author_array[0]);
                        for ($i = 1; $i < (count($author_array)); $i = $i + 1) {
-                               $whichauthor .= ' '.$andor.' post_author '.$eq.' '.intval($author_array[$i]);
+                               $whichauthor .= ' '.$andor." $wpdb->posts.post_author ".$eq.' '.intval($author_array[$i]);
                        }
                        $whichauthor .= ')';
                }
@@ -1107,20 +1220,25 @@ class WP_Query {
                        }
                        $q['author_name'] = sanitize_title($q['author_name']);
                        $q['author'] = $wpdb->get_var("SELECT ID FROM $wpdb->users WHERE user_nicename='".$q['author_name']."'");
-                       $whichauthor .= ' AND (post_author = '.intval($q['author']).')';
+                       $whichauthor .= " AND ($wpdb->posts.post_author = ".intval($q['author']).')';
                }
 
-               $where .= $search.$whichcat.$whichauthor;
+               // MIME-Type stuff for attachment browsing
+
+               if ( isset($q['post_mime_type']) && '' != $q['post_mime_type'] )
+                       $whichmimetype = wp_post_mime_type_where($q['post_mime_type']);
+
+               $where .= $search.$whichcat.$whichauthor.$whichmimetype;
 
                if ( empty($q['order']) || ((strtoupper($q['order']) != 'ASC') && (strtoupper($q['order']) != 'DESC')) )
                        $q['order'] = 'DESC';
 
                // Order by
                if ( empty($q['orderby']) ) {
-                       $q['orderby'] = 'post_date '.$q['order'];
+                       $q['orderby'] = "$wpdb->posts.post_date ".$q['order'];
                } else {
                        // Used to filter values
-                       $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order');
+                       $allowed_keys = array('author', 'date', 'category', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand');
                        $q['orderby'] = urldecode($q['orderby']);
                        $q['orderby'] = addslashes_gpc($q['orderby']);
                        $orderby_array = explode(' ',$q['orderby']);
@@ -1130,50 +1248,91 @@ class WP_Query {
                        for ($i = 0; $i < count($orderby_array); $i++) {
                                // Only allow certain values for safety
                                $orderby = $orderby_array[$i];
-                               if ( 'menu_order' != $orderby )
-                                       $orderby = 'post_' . $orderby;
+                               switch ($orderby) {
+                                       case 'menu_order':
+                                               break;
+                                       case 'ID':
+                                               $orderby = "$wpdb->posts.ID";
+                                               break;
+                                       case 'rand':
+                                               $orderby = 'RAND()';
+                                               break;
+                                       default:
+                                               $orderby = "$wpdb->posts.post_" . $orderby;
+                               }
                                if ( in_array($orderby_array[$i], $allowed_keys) )
-                                       $q['orderby'] .= (($i == 0) ? '' : ',') . "$orderby {$q['order']}";
+                                       $q['orderby'] .= (($i == 0) ? '' : ',') . $orderby;
                        }
+                       // append ASC or DESC at the end
+                       if ( !empty($q['orderby']))
+                               $q['orderby'] .= " {$q['order']}";
+
                        if ( empty($q['orderby']) )
-                               $q['orderby'] = 'post_date '.$q['order'];
+                               $q['orderby'] = "$wpdb->posts.post_date ".$q['order'];
                }
 
                if ( $this->is_attachment ) {
-                       $where .= " AND post_type = 'attachment'";
+                       $where .= " AND $wpdb->posts.post_type = 'attachment'";
                } elseif ($this->is_page) {
-                       $where .= " AND post_type = 'page'";
+                       $where .= " AND $wpdb->posts.post_type = 'page'";
                } elseif ($this->is_single) {
-                       $where .= " AND post_type = 'post'";
+                       $where .= " AND $wpdb->posts.post_type = 'post'";
+               } elseif ( 'any' == $post_type ) {
+                       $where .= '';
                } else {
-                       $where .= " AND post_type = '$post_type'";
+                       $where .= " AND $wpdb->posts.post_type = '$post_type'";
                }
 
                if ( isset($q['post_status']) && '' != $q['post_status'] ) {
+                       $statuswheres = array();
                        $q_status = explode(',', $q['post_status']);
                        $r_status = array();
+                       $p_status = array();
                        if ( in_array( 'draft'  , $q_status ) )
-                               $r_status[] = "post_status = 'draft'";
+                               $r_status[] = "$wpdb->posts.post_status = 'draft'";
                        if ( in_array( 'pending', $q_status ) )
-                               $r_status[] = "post_status = 'pending'";
+                               $r_status[] = "$wpdb->posts.post_status = 'pending'";
                        if ( in_array( 'future' , $q_status ) )
-                               $r_status[] = "post_status = 'future'";
+                               $r_status[] = "$wpdb->posts.post_status = 'future'";
                        if ( in_array( 'inherit' , $q_status ) )
-                               $r_status[] = "post_status = 'inherit'";
+                               $r_status[] = "$wpdb->posts.post_status = 'inherit'";
                        if ( in_array( 'private', $q_status ) )
-                               $r_status[] = "post_status = 'private'";
+                               $p_status[] = "$wpdb->posts.post_status = 'private'";
                        if ( in_array( 'publish', $q_status ) )
-                               $r_status[] = "post_status = 'publish'";
-                       if ( !empty($r_status) )
-                               $where .= " AND (" . join( ' OR ', $r_status ) . ")";
+                               $r_status[] = "$wpdb->posts.post_status = 'publish'";
+
+                       if ( empty($q['perm'] ) || 'readable' != $q['perm'] ) {
+                               $r_status = array_merge($r_status, $p_status);
+                               unset($p_status);
+                       }
+
+                       if ( !empty($r_status) ) {
+                               if ( !empty($q['perm'] ) && 'editable' == $q['perm'] && !current_user_can("edit_others_{$post_type}s") )
+                                       $statuswheres[] = "($wpdb->posts.post_author = $user_ID " .  "AND (" . join( ' OR ', $r_status ) . "))";
+                               else
+                                       $statuswheres[] = "(" . join( ' OR ', $r_status ) . ")";
+                       }
+                       if ( !empty($p_status) ) {
+                               if ( !empty($q['perm'] ) && 'readable' == $q['perm'] && !current_user_can("read_private_{$post_type}s") )
+                                       $statuswheres[] = "($wpdb->posts.post_author = $user_ID " .  "AND (" . join( ' OR ', $p_status ) . "))";
+                               else
+                                       $statuswheres[] = "(" . join( ' OR ', $p_status ) . ")";
+                       }
+                       if ( $post_status_join ) {
+                               $join .= " LEFT JOIN $wpdb->posts AS p2 ON ($wpdb->posts.post_parent = p2.ID) ";
+                               foreach ( $statuswheres as $index => $statuswhere )
+                                       $statuswheres[$index] = "($statuswhere OR ($wpdb->posts.post_status = 'inherit' AND " . str_replace($wpdb->posts, 'p2', $statuswhere) . "))";
+                       }
+                       foreach ( $statuswheres as $statuswhere )
+                               $where .= " AND $statuswhere";
                } elseif ( !$this->is_singular ) {
-                       $where .= " AND (post_status = 'publish'";
+                       $where .= " AND ($wpdb->posts.post_status = 'publish'";
 
                        if ( is_admin() )
-                               $where .= " OR post_status = 'future' OR post_status = 'draft' OR post_status = 'pending'";
+                               $where .= " OR $wpdb->posts.post_status = 'future' OR $wpdb->posts.post_status = 'draft' OR $wpdb->posts.post_status = 'pending'";
 
                        if ( is_user_logged_in() ) {
-                               $where .= current_user_can( "read_private_{$post_type}s" ) ? " OR post_status = 'private'" : " OR post_author = $user_ID AND post_status = 'private'";
+                               $where .= current_user_can( "read_private_{$post_type}s" ) ? " OR $wpdb->posts.post_status = 'private'" : " OR $wpdb->posts.post_author = $user_ID AND $wpdb->posts.post_status = 'private'";
                        }
 
                        $where .= ')';
@@ -1186,7 +1345,7 @@ class WP_Query {
 
                // Paging
                if ( empty($q['nopaging']) && !$this->is_singular ) {
-                       $page = abs(intval($q['paged']));
+                       $page = absint($q['paged']);
                        if (empty($page)) {
                                $page = 1;
                        }
@@ -1196,7 +1355,7 @@ class WP_Query {
                                $pgstrt = (intval($page) -1) * $q['posts_per_page'] . ', ';
                                $limits = 'LIMIT '.$pgstrt.$q['posts_per_page'];
                        } else { // we're ignoring $page and using 'offset'
-                               $q['offset'] = abs(intval($q['offset']));
+                               $q['offset'] = absint($q['offset']);
                                $pgstrt = $q['offset'] . ', ';
                                $limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
                        }
@@ -1237,20 +1396,30 @@ class WP_Query {
                // Apply post-paging filters on where and join.  Only plugins that
                // manipulate paging queries should use these hooks.
 
-               // Announce current selection parameters.  For use by caching plugins.
-               do_action( 'posts_selection', $where . $groupby . $q['orderby'] . $limits . $join );
-
                $where = apply_filters('posts_where_paged', $where);
                $groupby = apply_filters('posts_groupby', $groupby);
-               if ( ! empty($groupby) )
-                       $groupby = 'GROUP BY ' . $groupby;
                $join = apply_filters('posts_join_paged', $join);
                $orderby = apply_filters('posts_orderby', $q['orderby']);
-               if ( !empty( $orderby ) )
-                       $orderby = 'ORDER BY ' . $orderby;
                $distinct = apply_filters('posts_distinct', $distinct);
                $fields = apply_filters('posts_fields', "$wpdb->posts.*");
                $limits = apply_filters( 'post_limits', $limits );
+
+               // Announce current selection parameters.  For use by caching plugins.
+               do_action( 'posts_selection', $where . $groupby . $orderby . $limits . $join );
+
+               // Filter again for the benefit of caching plugins.  Regular plugins should use the hooks above.
+               $where = apply_filters('posts_where_request', $where);
+               $groupby = apply_filters('posts_groupby_request', $groupby);
+               $join = apply_filters('posts_join_request', $join);
+               $orderby = apply_filters('posts_orderby_request', $orderby);
+               $distinct = apply_filters('posts_distinct_request', $distinct);
+               $fields = apply_filters('posts_fields_request', $fields);
+               $limits = apply_filters( 'post_limits_request', $limits );
+
+               if ( ! empty($groupby) )
+                       $groupby = 'GROUP BY ' . $groupby;
+               if ( !empty( $orderby ) )
+                       $orderby = 'ORDER BY ' . $orderby;
                $found_rows = '';
                if ( !empty($limits) )
                        $found_rows = 'SQL_CALC_FOUND_ROWS';
@@ -1262,9 +1431,9 @@ class WP_Query {
                // Raw results filter.  Prior to status checks.
                $this->posts = apply_filters('posts_results', $this->posts);
 
-               if ( $this->is_comment_feed && $this->is_singular ) {
+               if ( !empty($this->posts) && $this->is_comment_feed && $this->is_singular ) {
                        $cjoin = apply_filters('comment_feed_join', '');
-                       $cwhere = apply_filters('comment_feed_where', "WHERE comment_post_ID = {$this->posts[0]->ID} AND comment_approved = '1'");
+                       $cwhere = apply_filters('comment_feed_where', "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'");
                        $comments_request = "SELECT $wpdb->comments.* FROM $wpdb->comments $cjoin $cwhere ORDER BY comment_date_gmt DESC LIMIT " . get_option('posts_per_rss');
                        $this->comments = $wpdb->get_results($comments_request);
                        $this->comment_count = count($this->comments);
@@ -1416,6 +1585,14 @@ class WP_Query {
                                return $tag;
                        $this->queried_object = &$tag;
                        $this->queried_object_id = (int) $tag_id;
+               } else if ($this->is_tax) {
+                       $tax = $this->get('taxonomy');
+                       $slug = $this->get('term');
+                       $term = &get_terms($tax, array('slug'=>$slug));
+                       if ( is_wp_error($term) )
+                               return $term;
+                       $this->queried_object = $term;
+                       $this->queried_object_id = $term->term_id;
                } else if ($this->is_posts_page) {
                        $this->queried_object = & get_page(get_option('page_for_posts'));
                        $this->queried_object_id = (int) $this->queried_object->ID;
@@ -1492,8 +1669,7 @@ function wp_old_slug_redirect () {
 
 // Setup global post data.
 function setup_postdata($post) {
-       global $id, $postdata, $authordata, $day, $currentmonth, $page, $pages, $multipage, $more, $numpages, $wp_query;
-       global $pagenow;
+       global $id, $authordata, $day, $currentmonth, $page, $pages, $multipage, $more, $numpages;
 
        $id = (int) $post->ID;
 
@@ -1505,7 +1681,7 @@ function setup_postdata($post) {
        $page = get_query_var('page');
        if ( !$page )
                $page = 1;
-       if ( is_single() || is_page() )
+       if ( is_single() || is_page() || is_feed() )
                $more = 1;
        $content = $post->post_content;
        if ( preg_match('/<!--nextpage-->/', $content) ) {