get_adjacent_post (获取相邻文章)

描述

获取上篇或下一篇相邻的文章。

语法

get_adjacent_post( bool $in_same_term = false, array|string $excluded_terms = '', bool $previous = true, string $taxonomy = 'category' )

参数

$in_same_term:(bool) (Optional)( Default value: false) 文章是否在同一分类

$excluded_terms:(array|string) (Optional) (Default value: '') 排除分类的ID

$previous:(boolean) (Optional) (Default value: true) 是否获取上一篇文章

$taxonomy:(string) (Optional)(Default value: 'category')  如果 $in_same_term 设置为 表示限定的分类

返回值

WP_Post:如果成功,返回文章对 象。

Null:如果 global $post 没有设置,返回空值Null。

String:如果不存在符合条件的文章 ,返回空字符串。

示例

获取同分类下的上一篇文章。

<?php $prev_post = get_adjacent_post( true, '', true, 'taxonomy_slug' ); ?>
<?php if ( is_a( $prev_post, 'WP_Post' ) ) { ?>
   <a href="<?php echo get_permalink( $prev_post->ID ); ?>"><?php echo get_the_title( $prev_post->ID ); ?></a>
<?php } ?>

获取同分类下的下一篇文章。

<?php $next_post = get_adjacent_post( true, '', false, 'taxonomy_slug' ); ?>
<?php if ( is_a( $next_post, 'WP_Post' ) ) {  ?>
   <a href="<?php echo get_permalink( $next_post->ID ); ?>"><?php echo get_the_title( $next_post->ID ); ?></a>
<?php } ?>

关系

被用

wp-includes/link-template.php: get_adjacent_post_link()
wp-includes/link-template.php: get_previous_post()
wp-includes/link-template.php: get_next_post()
wp-includes/link-template.php: get_adjacent_post_rel_link()

源码

位置: wp-includes/link-template.php

function get_adjacent_post( $in_same_term = false, $excluded_terms = '', $previous = true, $taxonomy = 'category' ) {
    global $wpdb;
 
    if ( ( ! $post = get_post() ) || ! taxonomy_exists( $taxonomy ) )
        return null;
 
    $current_post_date = $post->post_date;
 
    $join = '';
    $where = '';
    $adjacent = $previous ? 'previous' : 'next';
 
    if ( $in_same_term || ! empty( $excluded_terms ) ) {
        if ( ! empty( $excluded_terms ) && ! is_array( $excluded_terms ) ) {
            // back-compat, $excluded_terms used to be $excluded_terms with IDs separated by " and "
            if ( false !== strpos( $excluded_terms, ' and ' ) ) {
                _deprecated_argument( __FUNCTION__, '3.3.0', sprintf( __( '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 );
        }
 
        if ( $in_same_term ) {
            $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";
            $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 ) . ")";
        }
 
        /**
         * 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'.
         *
         * @since 4.4.0
         *
         * @param string $excluded_terms Array of excluded term IDs.
         */
        $excluded_terms = apply_filters( "get_{$adjacent}_post_excluded_terms", $excluded_terms );
 
        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 ( (array) $private_states as $state ) {
            if ( current_user_can( $read_private_cap ) ) {
                $where .= $wpdb->prepare( " OR p.post_status = %s", $state );
            } else {
                $where .= $wpdb->prepare( " OR (p.post_author = %d AND p.post_status = %s)", $user_id, $state );
            }
        }
        $where .= " )";
    } else {
        $where .= " AND p.post_status = 'publish'";
    }
 
    $op = $previous ? '<' : '>';
    $order = $previous ? 'DESC' : 'ASC';
 
    /**
     * Filters the JOIN clause in the SQL for an adjacent post query.
     *
     * The dynamic portion of the hook name, `$adjacent`, refers to the type
     * of adjacency, 'next' or 'previous'.
     *
     * @since 2.5.0
     * @since 4.4.0 Added the `$taxonomy` and `$post` parameters.
     *
     * @param string  $join           The JOIN clause in the SQL.
     * @param bool    $in_same_term   Whether post should be in a same taxonomy term.
     * @param array   $excluded_terms Array of excluded term IDs.
     * @param string  $taxonomy       Taxonomy. Used to identify the term used when `$in_same_term` is true.
     * @param WP_Post $post           WP_Post object.
     */
    $join = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms, $taxonomy, $post );
 
    /**
     * Filters the WHERE clause in the SQL for an adjacent post query.
     *
     * The dynamic portion of the hook name, `$adjacent`, refers to the type
     * of adjacency, 'next' or 'previous'.
     *
     * @since 2.5.0
     * @since 4.4.0 Added the `$taxonomy` and `$post` parameters.
     *
     * @param string  $where          The `WHERE` clause in the SQL.
     * @param bool    $in_same_term   Whether post should be in a same taxonomy term.
     * @param array   $excluded_terms Array of excluded term IDs.
     * @param string  $taxonomy       Taxonomy. Used to identify the term used when `$in_same_term` is true.
     * @param WP_Post $post           WP_Post object.
     */
    $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s $where", $current_post_date, $post->post_type ), $in_same_term, $excluded_terms, $taxonomy, $post );
 
    /**
     * Filters the ORDER BY clause in the SQL for an adjacent post query.
     *
     * The dynamic portion of the hook name, `$adjacent`, refers to the type
     * of adjacency, 'next' or 'previous'.
     *
     * @since 2.5.0
     * @since 4.4.0 Added the `$post` parameter.
     * @since 4.9.0 Added the `$order` parameter.
     *
     * @param string $order_by The `ORDER BY` clause in the SQL.
     * @param WP_Post $post    WP_Post object.
     * @param string  $order   Sort order. 'DESC' for previous post, 'ASC' for next.
     */
    $sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1", $post, $order );
 
    $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;
}