Skip to content

Instantly share code, notes, and snippets.

@bendoh
Last active March 24, 2022 10:05
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bendoh/bb3d62e5e0d470f00f9a to your computer and use it in GitHub Desktop.
Save bendoh/bb3d62e5e0d470f00f9a to your computer and use it in GitHub Desktop.
Fix sticky posts in WordPress. Deals with issues in trac #27282
/**
* Provide a flag for whether or not the request really wanted ignore sticky
* posts.
*/
add_filter( 'query_vars', function( $v ) {
$v[] = 'really_ignore_sticky_posts';
return $v;
} );
/**
* Yes, always ignore sticky posts, but save the requested value in
* really_ignore_sticky_posts query var
*/
add_filter( 'parse_query', function( $query ) {
// But do you really mean it, paw?
$query->query_vars['really_ignore_sticky_posts'] = isset( $query->query_vars['ignore_sticky_posts'] ) && $query->query_vars['ignore_sticky_posts'];
$query->query_vars['ignore_sticky_posts'] = true;
} );
/**
* Manipulate query to have sticky posts function correctly without adding to
* the original post results.
*/
add_filter( 'posts_clauses', function( $clauses, $query ) {
global $wpdb;
if( !$query->query_vars['post__in'] && $query->is_home && !$query->query_vars['really_ignore_sticky_posts'] ) {
$sticky_posts = get_option('sticky_posts');
// Grab only published sticky posts of our desired post type(s)
$stickies_query = new WP_Query( array(
'post__in' => $sticky_posts,
'post_type' => $query->query_vars['post_type'],
'post_status' => 'publish',
'fields' => 'ids',
'posts_per_page' => count( $sticky_posts )
) );
$queried_stickies = $stickies_query->posts;
if( !empty( $queried_stickies ) ) {
$post__in_sticky = implode(',', array_map( 'absint', $queried_stickies ) );
$clauses['where'] = "AND ((1=1 " . $clauses['where'] . ") OR {$wpdb->posts}.ID IN ($post__in_sticky))";
$sticky_orderby = "FIELD( {$wpdb->posts}.ID, $post__in_sticky ) DESC";
if( $clauses['orderby'] ) {
$clauses['orderby'] = $sticky_orderby . ', ' . $clauses['orderby'];
}
else {
$clauses['orderby'] = $sticky_orderby;
}
}
}
return $clauses;
}, 10, 2 );
@bendoh
Copy link
Author

bendoh commented Apr 7, 2015

Fixes issues with sticky posts as described in trac ticket https://core.trac.wordpress.org/ticket/27282

@diniscorreia
Copy link

Hey Benjamin,

I think there might be a bug - if I don't have any sticky posts, I'll get an error (memory exhausted).
Any ideias?

@diniscorreia
Copy link

So, not sure if this is the best/an actual fix, but I made sure there were sticky posts and the issue resolved:

if( !$query->query_vars['post__in'] && $query->is_home && get_option('sticky_posts' && !$query->query_vars['really_ignore_sticky_posts'] )

@Taigistal
Copy link

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment