get_adjacent_post() – Retrieves the adjacent post.

You appear to be a bot. Output may be restricted

Description

Retrieves the adjacent post.

Can either be next or previous post.

Usage

$WP_Post|null|string = get_adjacent_post( $in_same_term, $excluded_terms, $previous, $taxonomy );

Parameters

$in_same_term
( bool ) optional – Optional. Whether post should be in the same taxonomy term. Default false.
$excluded_terms
( int[]|string ) optional – Optional. Array or comma-separated list of excluded term IDs. Default empty string.
$previous
( bool ) optional default: 1 – Optional. Whether to retrieve previous post. Default true.
$taxonomy
( string ) optional default: category – Optional. Taxonomy, if $in_same_term is true. Default 'category'.

Returns

WP_Post|null|string Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists.

Source

File name: wordpress/wp-includes/link-template.php
Lines:

1 to 100 of 205
function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
  global $wpdb;

  $post = get_post();

  if ( ! $post || ! taxonomy_exists( $taxonomy ) ) {
    return null;
  }

  $current_post_date = $post->post_date;

  $join     = '';
  $where    = '';
  $adjacent = $previous ? 'previous' : 'next';

  if ( ! empty( $excluded_terms ) && ! is_array( $excluded_terms ) ) {
    // Back-compat, $excluded_terms used to be $excluded_categories with IDs separated by " and ".
    if ( str_contains( $excluded_terms, ' and ' ) ) {
      _deprecated_argument(
        get_adjacent_post,
        '3.3.0',
        sprintf(
          /* translators: %s: The word 'and'. */
          __( 'Use commas instead of %s to separate excluded terms.' ),
          "'and'"
        )
      );
      $excluded_terms = explode( ' and ', $excluded_terms );
    } else {
      $excluded_terms = explode( ',', $excluded_terms );
    }

    $excluded_terms = array_map( 'intval', $excluded_terms );
  }

  
/**
 * Filters the IDs of terms excluded from adjacent post queries.
 *
 * The dynamic portion of the hook name, `$adjacent`, refers to the type
 * of adjacency, 'next' or 'previous'.
 *
 * Possible hook names include:
 *
 *  - `get_next_post_excluded_terms`
 *  - `get_previous_post_excluded_terms`
 *
 * @since 4.4.0
 *
 * @param int[]|string $excluded_terms Array of excluded term IDs. Empty string if none were provided.
 */
  $excluded_terms = apply_filters( "get_{$adjacent}_post_excluded_terms", $excluded_terms );

  if ( $in_same_term || ! empty( $excluded_terms ) ) {
    if ( $in_same_term ) {
      $join  .= " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id";
      $where .= $wpdb->prepare( 'AND tt.taxonomy = %s', $taxonomy );

      if ( ! is_object_in_taxonomy( $post->post_type, $taxonomy ) ) {
        return '';
      }
      $term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );

      // Remove any exclusions from the term array to include.
      $term_array = array_diff( $term_array, (array) $excluded_terms );
      $term_array = array_map( 'intval', $term_array );

      if ( ! $term_array || is_wp_error( $term_array ) ) {
        return '';
      }

      $where .= ' AND tt.term_id IN (' . implode( ',', $term_array ) . ')';
    }

    if ( ! empty( $excluded_terms ) ) {
      $where .= " AND p.ID NOT IN ( SELECT tr.object_id FROM $wpdb->term_relationships tr LEFT JOIN $wpdb->term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) WHERE tt.term_id IN (" . implode( ',', array_map( 'intval', $excluded_terms ) ) . ') )';
    }
  }

  // 'post_status' clause depends on the current user.
  if ( is_user_logged_in() ) {
    $user_id = get_current_user_id();

    $post_type_object = get_post_type_object( $post->post_type );
    if ( empty( $post_type_object ) ) {
      $post_type_cap    = $post->post_type;
      $read_private_cap = 'read_private_' . $post_type_cap . 's';
    } else {
      $read_private_cap = $post_type_object->cap->read_private_posts;
    }

    /*
		 * Results should include private posts belonging to the current user, or private posts where the
		 * current user has the 'read_private_posts' cap.
		 */
    $private_states = get_post_stati( array( 'private' => true ) );
    $where         .= " AND ( p.post_status = 'publish'";
    foreach ( $private_states as $state ) {
      if ( current_user_can( $read_private_cap ) ) {
        $where .= $wpdb->prepare( ' OR p.post_status = %s', $state );
      } else {
 

 View on GitHub View on Trac