Created
June 15, 2012 09:59
-
-
Save eteubert/2935700 to your computer and use it in GitHub Desktop.
WordPress: Similar posts by matching tags
This file contains hidden or 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 | |
/** | |
* Return posts with maximum age of one year. | |
* | |
* Usage: | |
* add_filter( 'posts_where', 'wp_query_filter_max_one_year_old' ); | |
* $my_query = new WP_Query( array( ... ) ); | |
* remove_filter( 'posts_where', 'wp_query_filter_max_one_year_old' ); | |
* | |
* @param string $where | |
* @return string | |
*/ | |
function wp_query_filter_max_one_year_old( $where = '' ) { | |
$where .= " AND post_date > '" . date( 'Y-m-d', strtotime( '-356 days' ) ) . "'"; | |
return $where; | |
} | |
/** | |
* Find similar posts based on tags. | |
* | |
* @param int $post_id | |
* @param integer $limit maximum number of posts | |
* @param integer $cache_duration time to cache in seconds. default: 1 week | |
* @return array list of post_ids | |
*/ | |
function get_similar_post_ids_by_tags( $post_id = NULL, $limit = 3, $cache_duration = 604800 ) { | |
if ( ! $post_id ) | |
$post_id = get_the_ID(); | |
$cache_key = "inps_similar_" . $post_id; | |
if ( false === ( $scores = get_transient( $cache_key ) ) ) { | |
$tags = wp_get_post_tags( $post_id ); | |
// fetch all last years posts with at least one matching tag | |
$tag_ids = array_map( function( $t ) { return $t->term_id; }, $tags ); | |
add_filter( 'posts_where', 'wp_query_filter_max_one_year_old' ); | |
$args = array( | |
'tag__in' => $tag_ids, | |
'post__not_in' => array( $post_id ), | |
'posts_per_page' => -1 | |
); | |
$query_similar_posts = new WP_Query( $args ); | |
remove_filter( 'posts_where', 'wp_query_filter_max_one_year_old' ); | |
$scores = array(); | |
// count identical tags for each post | |
while ( $query_similar_posts->have_posts() ) { | |
$p = $query_similar_posts->next_post(); | |
$identical_tags = 0; | |
$this_tags = wp_get_post_tags( $p->ID ); | |
foreach ( $this_tags as $t ) { | |
if ( in_array( $t->term_id, $tag_ids ) ) { | |
$identical_tags++; | |
} | |
} | |
if ( $identical_tags > 0 ) { | |
$scores[] = array( 'post_id' => $p->ID, 'score' => $identical_tags ); | |
} | |
} | |
// sort by score | |
usort( $scores, function ( $a, $b ) { | |
if ( $a[ 'score' ] == $b[ 'score' ] ) { | |
return 0; | |
} | |
return ( $a[ 'score' ] > $b[ 'score' ] ) ? -1 : 1; | |
} ); | |
// take first $limit only | |
$scores = array_slice( $scores, 0, $limit ); | |
// return without scores | |
$scores = array_map( function( $p ){ return $p[ 'post_id' ]; }, $scores ); | |
set_transient( $cache_key, $scores, $cache_duration ); | |
} | |
return $scores; | |
} | |
?> | |
<!-- Example for Theme file --> | |
<?php $similar_posts = get_similar_post_ids_by_tags(); ?> | |
<strong><?php __( 'Related Posts' ) ?></strong> | |
<ul> | |
<?php foreach ( $similar_posts as $similar_post_id ): ?> | |
<li> | |
<a href="<?php echo get_permalink( $similar_post_id ); ?>"><?php echo get_the_title( $similar_post_id ); ?></a> | |
</li> | |
<?php endforeach; ?> | |
</ul> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment