Instantly share code, notes, and snippets.
Last active
December 25, 2018 16:01
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save johnregan3/bb6960cc56b0d18225fea38f3665ebc3 to your computer and use it in GitHub Desktop.
WordPress get related posts - 04
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 | |
/* | |
* NOTE: This is a portion of a tutorial: | |
* | |
* @link https://johnregan3.wordpress.com/how-to-get-wordpress-related-posts | |
*/ | |
function jr3_get_related_posts( $post_id = 0, $args = array(), $count = 3 ) { | |
$posts = array(); | |
// 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, return them. Else, we'll continue on. | |
if ( ! empty( $query->posts ) && count( $query->posts ) >= $count ) { | |
return $query->posts; | |
} | |
// Since we're continuing, relabel our results for clarity. | |
$posts = $query->posts; | |
// Update our $args so we don't duplicate any existing posts in the future. | |
$args['post__not_in'] = wp_list_pluck( $posts, 'ID' ); | |
/* | |
* Remove the search for a specific author. | |
* | |
* This action will be repeated soon with the taxonomy args. | |
* Note that we'll make this code more efficient in the next step. | |
*/ | |
unset( $args['author'] ); | |
$posts = jr3_related_posts_get( $args, $posts ); | |
// If we now have enough posts, return them. | |
if ( ! empty( $posts ) && count( $posts ) >= $count ) { | |
// Make sure the new array of posts doesn't exceed the number of posts we need. | |
$posts = array_slice( $posts, 0, $count ); | |
return $posts; | |
} | |
/* | |
* Remove the search for specific taxonomy terms, leaving | |
* only the post type restriction. | |
* | |
* Note that we'll make this code more efficient in the next step. | |
*/ | |
unset( $args['tax_query'] ); | |
$posts = jr3_related_posts_get( $args, $posts ); | |
// Make sure we don't exceed the number of $count. | |
return array_slice( $posts, 0, $count ); | |
} | |
/** | |
* Get some posts using the provided $args. | |
* | |
* @since 1.0.0 | |
* | |
* @param array $args An array of \WP_Query args. | |
* @param array $posts An array of posts. | |
* | |
* @return array An updated array of posts. | |
*/ | |
function jr3_related_posts_get( $args, $posts = array() ) { | |
$new_posts = array(); | |
$query = new WP_Query( $args ); | |
if ( ! empty( $query->posts ) && is_array( $query->posts ) ) { | |
$new_posts = $query->posts; | |
$posts = $posts + $new_posts; | |
} | |
return $posts; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment