Skip to content

Instantly share code, notes, and snippets.

@folletto
Created March 12, 2015 18:04
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 folletto/0dae2aff28d281929698 to your computer and use it in GitHub Desktop.
Save folletto/0dae2aff28d281929698 to your computer and use it in GitHub Desktop.
Iterate on related posts
function loop_related_posts( $posts_per_page = 3, $category = null, $post_ID = 0 ) {
/****************************************************************************************************
* Get the post related to the current-looping post's matching tags.
* Creates its own loop.
*
* USAGE:
* <?php while ( loop_related_posts( 3 ) ) : ?>
* your standard template code
* <?php endwhile; ?>
*/
global $wpdb;
global $post;
static $current_post = false;
static $results = array();
// ****** Terminate command.
// Done on new loop to allow everything setup correctly in the last loop.
if ( !$current_post === false && $current_post >= count( $results ) ) {
$current_post = false;
wp_reset_postdata();
return $current_post;
}
if ( $current_post === false ) {
// ****** Get current post data
$post_ID = intval( $post_ID );
if ( $post_ID == 0 ) {
$post_ID = (int)$post->ID;
}
// ****** Cache
$cachekey = 'relatedposts-' . $post_id . '-' . md5( $posts_per_page . "other" );
$results = wp_cache_get( $cachekey, "theme-relatedposts" );
// ****** No cache? Query!
if ( $results === false ) {
// ****** Set variables
if ( $category ) $category = "AND tm.name = '{$category}'";
$tags = get_the_tags( $post_ID );
if ( $tags == false || $post_ID == 0 ) return false; // --> EXIT
// ****** SQL Tags list
$taglist = array();
foreach ( $tags as $tag ) { $taglist[] = '"' . $tag->term_id . '"'; };
$taglist = join( $taglist, ', ' );
// ****** Toggle Extended Content Query
$is_extended_content = '';
if ( true ) $is_extended_content = ', p.post_content';
$results = $wpdb->get_results(
"SELECT DISTINCT COUNT(tr.object_id) AS rank, p.ID, p.post_title, p.post_excerpt, p.comment_count, p.post_name, p.post_date {$is_extended_content}
FROM {$wpdb->posts} AS p
INNER JOIN {$wpdb->term_relationships} AS tr ON p.ID = tr.object_id
INNER JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN {$wpdb->terms} AS tm ON tm.term_id = tt.term_id
WHERE
tt.taxonomy = 'post_tag'
AND (tt.term_id IN ({$taglist}))
AND p.post_status = 'publish'
AND p.post_type = 'post'
AND p.ID != {$post_ID}
AND p.post_date < '" . current_time('mysql') . "'
GROUP BY tr.object_id
ORDER BY rank DESC
LIMIT 0, {$posts_per_page}
");
// ****** Cache
wp_cache_set($cachekey, $results, "theme-relatedposts");
}
if ( !$results ) return false; // --> EXIT
// ****** We have data, first loop is on!
$current_post = 0;
}
if ( $current_post !== false ) { // This isn't 'else' because can be initialized just above.
// ****** Loop
$current_post++;
$post = $results[$current_post - 1];
setup_postdata( $post );
}
return $current_post;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment