WordPress.org

Make WordPress Core

Opened 9 months ago

Closed 9 months ago

Last modified 9 months ago

#24794 closed enhancement (duplicate)

get_adjacent_post()'s categories properties don't play well with CPT

Reported by: RubenBristian Owned by:
Milestone: Priority: normal
Severity: normal Version: 3.1
Component: Posts, Post Types Keywords:
Focuses: Cc:

Description

Hi

Please bear with me here, as it's the first ticket i create ever so i don't know if i have done it right or wrong or if i posted something that's not an error because my lack of knowledge :)

The issue is simple: let's consider that i have a CPT called "portfolio" and i want to use get_adjacent_post() with it.. The basic function works fine, but when i try to exclude some categories or filter the posts which are in the same category, the object returned by the function is empty. This is because the database query is for the "category", while my cpt's categories are actually "portfolio_category".

I'm not sure if this has been raised before, since i have searched a lot on the internet on this topic and i wasn't able to find anything concrete.

The issue:

get_adjacent_post(); // returns a perfectly normal object which contains the data of the next post
get_adjacent_post(true); // returns an empty object, even if there are a lot more posts in the same category
get_adjacent_post(false, '34'); // returns an empty object, even if there are more posts in other categories except 3

The solution would be to add a new variable to the get_adjacent_post() function (and on the other function which depend on it) and let developers choose the custom post type:

function get_adjacent_post( $in_same_cat = false, $excluded_categories = '', $previous = true, $cpt_title = '' ) {
	global $wpdb;

	if ( ! $post = get_post() )
		return null;

	$current_post_date = $post->post_date;

	$join = '';
	$posts_in_ex_cats_sql = '';
	if ( $in_same_cat || ! empty( $excluded_categories ) ) {
		$join = " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id";

		if ( $in_same_cat ) {
			if ( ! is_object_in_taxonomy( $post->post_type, $cpt_title . 'category' ) )
				return '';
			$cat_array = wp_get_object_terms($post->ID, $cpt_title . 'category', array('fields' => 'ids'));
			if ( ! $cat_array || is_wp_error( $cat_array ) )
				return '';
			$join .= " AND tt.taxonomy = '" . $cpt_title . "category' AND tt.term_id IN (" . implode(',', $cat_array) . ")";
		}

		$posts_in_ex_cats_sql = "AND tt.taxonomy = '" . $cpt_title . "category'";
		if ( ! empty( $excluded_categories ) ) {
			if ( ! is_array( $excluded_categories ) ) {
				// back-compat, $excluded_categories used to be IDs separated by " and "
				if ( strpos( $excluded_categories, ' and ' ) !== false ) {
					_deprecated_argument( __FUNCTION__, '3.3', sprintf( __( 'Use commas instead of %s to separate excluded categories.' ), "'and'" ) );
					$excluded_categories = explode( ' and ', $excluded_categories );
				} else {
					$excluded_categories = explode( ',', $excluded_categories );
				}
			}

			$excluded_categories = array_map( 'intval', $excluded_categories );

			if ( ! empty( $cat_array ) ) {
				$excluded_categories = array_diff($excluded_categories, $cat_array);
				$posts_in_ex_cats_sql = '';
			}

			if ( !empty($excluded_categories) ) {
				$posts_in_ex_cats_sql = " AND tt.taxonomy = '" . $cpt_title . "category' AND tt.term_id NOT IN (" . implode($excluded_categories, ',') . ')';
			}
		}
	}

	$adjacent = $previous ? 'previous' : 'next';
	$op = $previous ? '<' : '>';
	$order = $previous ? 'DESC' : 'ASC';

	$join  = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_cat, $excluded_categories );
	$where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare("WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $posts_in_ex_cats_sql", $current_post_date, $post->post_type), $in_same_cat, $excluded_categories );
	$sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" );

	$query = "SELECT p.id FROM $wpdb->posts AS p $join $where $sort";
	$query_key = 'adjacent_post_' . md5($query);
	$result = wp_cache_get($query_key, 'counts');
	if ( false !== $result ) {
		if ( $result )
			$result = get_post( $result );
		return $result;
	}

	$result = $wpdb->get_var( $query );
	if ( null === $result )
		$result = '';

	wp_cache_set($query_key, $result, 'counts');

	if ( $result )
		$result = get_post( $result );

	return $result;
}

The in my code, i'll simply have to use:

get_adjacent_post(false, '34', true, 'portfolio_'); // and this returns the correct object

Change History (2)

comment:1 RubenBristian9 months ago

  • Resolution set to duplicate
  • Status changed from new to closed

Duplicate of #17807.

comment:2 helen9 months ago

  • Keywords has-patch removed
  • Milestone Awaiting Review deleted
  • Version changed from 3.5.2 to 3.1
Note: See TracTickets for help on using tickets.