Instantly share code, notes, and snippets.
Last active
January 8, 2016 18:20
-
Star
(1)
1
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save kingkool68/20640d03199305e11973 to your computer and use it in GitHub Desktop.
This plugin features a smarty-pants set of functions to determine what content is related to what.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name:Russell's Related Posts | |
Description: A smarty-pants set of functions to determine what content is related to what | |
Version: 0.1 | |
Author: Russell Heimlich | |
Author URI: http://www.russellheimlich.com | |
*/ | |
/* | |
We get the terms of the current post ordered from most frequent to least frequent. Then we loop over the terms to see if there are any other posts that contain all of the of terms. For each iteration we remove the most obscure term until we have enough post_ids to meet our requirements. Finally we store the results in a transient so the work doesn't need to be done again over and over. | |
*/ | |
function get_rh_related_data( $args, $post_id = '' ) { | |
global $post, $wpdb; | |
$post_id = intval( $post_id ); | |
if( !$post_id && $post->ID ) { | |
$post_id = $post->ID; | |
} | |
if( !$post_id ) { | |
return false; | |
} | |
$defaults = array( | |
'taxonomy' => 'topics', | |
'post_type' => array('post'), | |
'max' => 5, | |
); | |
$options = wp_parse_args( $args, $defaults ); | |
$transient_name = 'rh-related-' . $options['taxonomy'] . '-' . $post_id; | |
$transient_name = apply_filters( 'rh_related_transient_name', $transient_name, $post_id, $options ); | |
if( isset( $_GET['flush-related-links'] ) && is_user_logged_in() ) { | |
echo '<p>Related links flushed! (' . $transient_name . ')</p>'; | |
delete_transient( $transient_name ); | |
} | |
$output = get_transient( $transient_name ); | |
if( $output !== false && !is_preview() ) { | |
//echo $transient_name . ' read!'; | |
return $output; | |
} | |
$args = array( | |
'fields' => 'ids', | |
'orderby' => 'count', | |
'order' => 'ASC', | |
); | |
$orig_terms_set = wp_get_object_terms( $post_id, $options['taxonomy'], $args ); | |
// Make sure each returned term id is an integer. | |
$orig_terms_set = array_map( 'intval', $orig_terms_set ); | |
// Store a copy that we'll be reducing by one item for each iteration. | |
$terms_to_iterate = $orig_terms_set; | |
$post_args = array( | |
'fields' => 'ids', | |
'post_type' => $options['post_type'], | |
'post__not_in' => array( $post_id ), | |
'posts_per_page' => 50, | |
// For Performance. See https://10up.github.io/Engineering-Best-Practices/php/ | |
'no_found_rows' => true, | |
'update_post_meta_cache' => false, | |
); | |
$output = array(); | |
while( count( $terms_to_iterate ) > 1 ) { | |
$post_args['tax_query'] = array( | |
array( | |
'taxonomy' => $options['taxonomy'], | |
'field' => 'id', | |
'terms' => $terms_to_iterate, | |
'operator' => 'AND', | |
) | |
); | |
$posts = get_posts( $post_args ); | |
foreach( $posts as $id ) { | |
$id = intval( $id ); | |
if( !in_array( $id, $output) ) { | |
$output[] = $id; | |
} | |
} | |
array_pop( $terms_to_iterate ); | |
} | |
$post_args['posts_per_page'] = 10; | |
$post_args['tax_query'] = array( | |
array( | |
'taxonomy' => $options['taxonomy'], | |
'field' => 'id', | |
'terms' => $orig_terms_set, | |
) | |
); | |
$posts = get_posts( $post_args ); | |
foreach( $posts as $count => $id ) { | |
$id = intval( $id ); | |
if( !in_array( $id, $output) ) { | |
$output[] = $id; | |
} | |
if( count( $output ) > $options['max'] ) { | |
// We have enough related post IDs now, stop the loop. | |
break; | |
} | |
} | |
$output = apply_filters( 'rh_related_data', $output, $options ); | |
if( !is_preview() ) { | |
//echo $transient_name . ' set!'; | |
set_transient( $transient_name, $output, 24 * HOUR_IN_SECONDS ); | |
} | |
return $output; | |
} | |
function rh_related( $args = array(), $post_id = '' ) { | |
$post_ids = get_rh_related_data( $args, $post_id ); | |
if( !$post_ids ) { | |
return false; | |
} | |
$defaults = array( | |
'post__in' => $post_ids, | |
'orderby' => 'post__in', | |
'post_type' => array('post'), | |
'posts_per_page' => min( array(count($post_ids), 10)), | |
'related_title' => 'Related Posts', | |
'category__in' => '', // Must be an ID | |
'category__not_in' => '', // Must be an ID | |
); | |
$options = wp_parse_args( $args, $defaults ); | |
$related_posts = new WP_Query( $options ); | |
if( $related_posts->have_posts() ): | |
?> | |
<div class="widget"> | |
<h2 class="header"><?php echo $options['related_title']?></h2> | |
<div class="inner with-posts"> | |
<?php while ( $related_posts->have_posts() ): | |
$related_posts->the_post(); | |
?> | |
<a class="post" href="<?php the_permalink();?>"> | |
<div class="meta"> | |
<?php do_action( 'rh_related_before_date', $related_posts ); ?> | |
<span class="date"><?php the_time('M j, Y'); ?></span> | |
<?php do_action( 'rh_related_after_date', $related_posts ); ?> | |
</div> | |
<h2><?php the_title();?></h2> | |
</a> | |
<?php endwhile; | |
wp_reset_postdata(); | |
?> | |
</div> | |
</div> | |
<?php | |
endif; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment