From d01ad4ca08f12a00a39407a9e7927a18bd17255e Mon Sep 17 00:00:00 2001
From: Martin Shopland <martin.shopland@redbrickstudios.co.uk>
Date: Mon, 24 Sep 2012 19:20:11 +0100
Subject: [PATCH] New sticky posts functionality rolled into core.

---
 wp-includes/query.php |   66 +++++++++++-------------------------------------
 1 files changed, 15 insertions(+), 51 deletions(-)

diff --git a/wp-includes/query.php b/wp-includes/query.php
index 5f6ccdd..f7fe62a 100644
--- a/wp-includes/query.php
+++ b/wp-includes/query.php
@@ -2558,7 +2558,16 @@ class WP_Query {
 				$where = "AND 0";
 		}
 
-		$pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' );
+		// Sticky Posts
+		// Treated as separate clause so as not to upset existing plugins.
+		$sticky_posts = get_option('sticky_posts');
+		if ( $this->is_home && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
+			$sticky = '(' . $wpdb->posts . '.ID IN (' . implode(',', $sticky_posts) . ')) DESC';
+		} else {
+			$sticky = '';
+		}
+
+		$pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits', 'sticky' );
 
 		// Apply post-paging filters on where and join. Only plugins that
 		// manipulate paging queries should use these hooks.
@@ -2570,6 +2579,7 @@ class WP_Query {
 			$distinct	= apply_filters_ref_array( 'posts_distinct',	array( $distinct, &$this ) );
 			$limits		= apply_filters_ref_array( 'post_limits',		array( $limits, &$this ) );
 			$fields		= apply_filters_ref_array( 'posts_fields',		array( $fields, &$this ) );
+			$sticky		= apply_filters_ref_array( 'posts_sticky',		array( $sticky, &$this ) );
 
 			// Filter all clauses at once, for convenience
 			$clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) );
@@ -2589,6 +2599,7 @@ class WP_Query {
 			$distinct	= apply_filters_ref_array( 'posts_distinct_request',	array( $distinct, &$this ) );
 			$fields		= apply_filters_ref_array( 'posts_fields_request',		array( $fields, &$this ) );
 			$limits		= apply_filters_ref_array( 'post_limits_request',		array( $limits, &$this ) );
+			$sticky		= apply_filters_ref_array( 'posts_sticky_request',		array( $sticky, &$this ) );
 
 			// Filter all clauses at once, for convenience
 			$clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) );
@@ -2596,6 +2607,9 @@ class WP_Query {
 				$$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';
 		}
 
+		if ( !empty($sticky))
+			$orderby = empty($orderby) ? $sticky : $sticky . ',' . $orderby;
+
 		if ( ! empty($groupby) )
 			$groupby = 'GROUP BY ' . $groupby;
 		if ( !empty( $orderby ) )
@@ -2703,56 +2717,6 @@ class WP_Query {
 				$this->posts[0] = apply_filters_ref_array('the_preview', array( $this->posts[0], &$this ));
 		}
 
-		// Put sticky posts at the top of the posts array
-		$sticky_posts = get_option('sticky_posts');
-		if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
-			$num_posts = count($this->posts);
-			$sticky_offset = 0;
-			// Loop over posts and relocate stickies to the front.
-			for ( $i = 0; $i < $num_posts; $i++ ) {
-				if ( in_array($this->posts[$i]->ID, $sticky_posts) ) {
-					$sticky_post = $this->posts[$i];
-					// Remove sticky from current position
-					array_splice($this->posts, $i, 1);
-					// Move to front, after other stickies
-					array_splice($this->posts, $sticky_offset, 0, array($sticky_post));
-					// Increment the sticky offset. The next sticky will be placed at this offset.
-					$sticky_offset++;
-					// Remove post from sticky posts array
-					$offset = array_search($sticky_post->ID, $sticky_posts);
-					unset( $sticky_posts[$offset] );
-				}
-			}
-
-			// If any posts have been excluded specifically, Ignore those that are sticky.
-			if ( !empty($sticky_posts) && !empty($q['post__not_in']) )
-				$sticky_posts = array_diff($sticky_posts, $q['post__not_in']);
-
-			// Fetch sticky posts that weren't in the query results
-			if ( !empty($sticky_posts) ) {
-				$stickies__in = implode(',', array_map( 'absint', $sticky_posts ));
-				// honor post type(s) if not set to any
-				$stickies_where = '';
-				if ( 'any' != $post_type && '' != $post_type ) {
-					if ( is_array( $post_type ) ) {
-						$post_types = join( "', '", $post_type );
-					} else {
-						$post_types = $post_type;
-					}
-					$stickies_where = "AND $wpdb->posts.post_type IN ('" . $post_types . "')";
-				}
-
-				$stickies = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE $wpdb->posts.ID IN ($stickies__in) $stickies_where" );
-				foreach ( $stickies as $sticky_post ) {
-					// Ignore sticky posts the current user cannot read or are not published.
-					if ( 'publish' != $sticky_post->post_status )
-						continue;
-					array_splice($this->posts, $sticky_offset, 0, array($sticky_post));
-					$sticky_offset++;
-				}
-			}
-		}
-
 		if ( !$q['suppress_filters'] )
 			$this->posts = apply_filters_ref_array('the_posts', array( $this->posts, &$this ) );
 
-- 
1.7.0.2.msysgit.0

