|
<?php |
|
/** |
|
* Get related posts. |
|
* |
|
* To set the count of posts returned, add a "posts_per_page" value to the $args array. |
|
* The default number of posts returned is three. |
|
* |
|
* @since 1.0.0 |
|
* |
|
* @param int $post_id A \WP_Post ID. |
|
* @param array $args Array of \WP_Query args. |
|
* @param $count int The number of posts to retrieve. |
|
* |
|
* @return array An array of posts. |
|
*/ |
|
function jr3_get_related_posts( $post_id = 0, $args = array(), $count = 3 ) { |
|
|
|
// Make sure we have a good post_id. If not, grab the current post. |
|
if ( empty( $post_id ) || ! is_numeric( $post_id ) ) { |
|
$post_id = get_the_ID(); |
|
} |
|
|
|
// If we still don't have a good ID, bail. |
|
if ( empty( $post_id ) ) { |
|
return array(); |
|
} |
|
|
|
/* |
|
* Start by filtering the input $args. |
|
* wp_parse_args() allows us to set default arguments |
|
* that can be overriden by input. |
|
* |
|
* Note that we get the post type of the requested post, |
|
* and we set the author of the current post. |
|
*/ |
|
$args = wp_parse_args( $args, array( |
|
'posts_per_page' => 20, // For Sanity. |
|
'orderby' => 'title', |
|
'post_type' => get_post_type( $post_id ), |
|
'post_status' => 'publish', |
|
'author' => get_post_field( 'post_author', $post_id ), |
|
'no_found_rows' => true, // Speeds up query. |
|
) ); |
|
|
|
/* |
|
* Set up taxonomy queries. |
|
* This will get us related posts on the same topic(s). |
|
*/ |
|
$post = get_post( $post_id ); |
|
|
|
// Get all taxonomies (e.g., "Tags," "Categories") that this post has. |
|
$taxonomies = get_object_taxonomies( $post, 'names' ); |
|
|
|
/* |
|
* Sanity check. |
|
* Limit the number of taxonomies to prevent getting creating a heavy query. |
|
*/ |
|
$taxonomies = array_slice( $taxonomies, 0, 3 ); |
|
|
|
/* |
|
* Get each term associated with the post and set |
|
* a taxonomy query for it. |
|
*/ |
|
foreach ( $taxonomies as $taxonomy ) { |
|
|
|
// Get each term (e.g., single tag or single category) that this post has. |
|
$terms = get_the_terms( $post_id, $taxonomy ); |
|
if ( empty( $terms ) ) { |
|
continue; |
|
} |
|
|
|
// Get the slug of each term in the list. |
|
$term_list = wp_list_pluck( $terms, 'slug' ); |
|
$args['tax_query'][] = array( |
|
'taxonomy' => $taxonomy, |
|
'field' => 'slug', |
|
'terms' => $term_list, |
|
); |
|
} |
|
|
|
/* |
|
* If we have more than one taxonomy, use "OR" |
|
* to basically say the posts can use any of the terms. |
|
* |
|
* Otherwise, "AND" will mean we will only look for posts |
|
* that contain all of the same terms of the current post, which |
|
* can be quite specific and restrictive. |
|
*/ |
|
if ( isset( $args['tax_query'] ) && count( $args['tax_query'] ) > 1 ) { |
|
$args['tax_query']['relation'] = 'OR'; |
|
} |
|
|
|
// Make sure the current post is not part of what we get back. |
|
$args['post__not_in'] = array( $post_id ); |
|
|
|
// Run the query. |
|
$query = new WP_Query( $args ); |
|
|
|
// If we have posts, let's return them. |
|
if ( ! empty( $query->posts ) && is_array( $query->posts ) ) { |
|
return $query->posts; |
|
} |
|
|
|
// If no posts, return an empty array. |
|
return array(); |
|
} |