pippin
  • 0
Профи

Получить следующие/предыдущие 3 сообщения относительно текущего сообщения

  • 0

У меня есть 7 сообщений, например:

1

2

3

4 — это текущий пост

5

6

7

Как уже отмечалось, номер четыре — это текущая отображаемая запись. Мне нужно создать запрос, который позволит мне отобразить предыдущие 3 сообщения (по дате публикации), а также три сообщения после. Это можно сделать с помощью двух отдельных запросов.

Я смог отобразить непосредственно предыдущую или следующую запись, но не те, что дальше вниз/вверх.

Есть идеи?

Share
  1. Какие данные вы хотите получить по этим предыдущим и следующим сообщениям? Только название, содержание, постоянная ссылка?

    • 0
  2. Это можно сделать в одном запросе, хотя я не могу конкретно говорить о том, насколько хорошо этот запрос будет работать (я не тратил много времени на запросы Union — до сих пор в этом не было необходимости).

    Во-первых, функция для выбора двух наборов результатов, но с использованием объединения для возврата их в виде одного набора результатов.

    function get_post_siblings( $limit = 3, $date = '' ) {
        global $wpdb, $post;
    
        if( empty( $date ) )
            $date = $post->post_date;
    
        //$date = '2009-06-20 12:00:00'; // test data
    
        $limit = absint( $limit );
        if( !$limit )
            return;
    
        $p = $wpdb->get_results( "
        (
            SELECT 
                p1.post_title, 
                p1.post_date,
                p1.ID
            FROM 
                $wpdb->posts p1 
            WHERE 
                p1.post_date < '$date' AND 
                p1.post_type = 'post' AND 
                p1.post_status = 'publish' 
            ORDER by 
                p1.post_date DESC
            LIMIT 
                $limit
        )
        UNION 
        (
            SELECT 
                p2.post_title, 
                p2.post_date,
                p2.ID 
            FROM 
                $wpdb->posts p2 
            WHERE 
                p2.post_date > '$date' AND 
                p2.post_type = 'post' AND 
                p2.post_status = 'publish' 
            ORDER by
                p2.post_date ASC
            LIMIT 
                $limit
        ) 
        ORDER by post_date ASC
        " );
        $i = 0;
        $adjacents = array();
        for( $c = count($p); $i < $c; $i++ )
            if( $i < $limit )
                $adjacents['prev'][] = $p[$i];
            else
                $adjacents['next'][] = $p[$i];
    
        return $adjacents;
    }
    

    Там есть дата тестирования, вы можете спокойно игнорировать это или добавить свое собственное значение для тестирования.

    Вот некоторый пример кода, который вы можете использовать в своем цикле single.php для вывода результатов, хотя обратите внимание, что это всего лишь общий пример, и функции может потребоваться выбрать больше/другие данные, но на основе предоставленной вами информации я не был уверен, что именно вы хотели, поэтому нижеследующее предназначено для иллюстрации и дает образец, который вы можете использовать для проверки результатов.

    <?php 
    $siblings = get_post_siblings( 3 ); // This is the same as doing the call below(which is just for illustration)
    //$siblings = get_post_siblings( 3, $post->post_date );
    
    $prev = $siblings['prev'];
    
    foreach( $prev as $p )
        echo get_the_time( 'd m Y', $p ) . ': ' . apply_filters( 'the_title', $p->post_title ) . '<br />';
    
    $next = $siblings['next'];
    
    foreach( $next as $p )
        echo get_the_time( 'd m Y', $p ) . ': ' . apply_filters( 'the_title', $p->post_title ) . '<br />';
    ?>
    

    В ожидании обратной связи… 🙂

    • 0
  3. Это можно сделать гораздо лучше с помощью свойства date_query класса WP_Query. Это позволит получить сообщения до даты публикации текущего сообщения.

    // WP_Query arguments
    $args = array (
        'post_type'              => 'post',
        'post_status'            => 'publish',
         'date_query'    => array(
            'column'  => 'post_date',
            'before'   => get_the_date()
        ),
    );
    
    // The Query
    $the_query = new WP_Query( $args );
    

    ………

    • 0
  4. 3 х get_adjacent_post() :

    global $post;
    $current_post = $post; // remember the current post
    
    for($i = 1; $i <= 3; $i++){
      $post = get_previous_post(); // this uses $post->ID
      setup_postdata($post);
    
      // do your stuff here       
      the_title();
    
    }
    
    $post = $current_post; // restore
    

    то же самое для следующих 3 сообщений, просто измените функцию на get_next_post()…


    Чтобы сделать это с помощью одного запроса, все еще используя WP API, попробуйте изменить LIMIT значение на 3 в фильтрах get_previous_post_sort и.get_next_post_sort

    • 0
  5. Как предлагает JanFabry в ответе @onetrickpony выше, вы можете изменить get_adjacent_post(). Это то, что я сделал. Вот функция. Я изменил сигнатуру функции, потому что так она имела для меня больше смысла.

    /**
     * Retrieve multiple adjacent posts. Adapted from get_adjacent_post()
     *
     * Can either be next or previous post.
     *
     * @since 2.5.0
     *
     * @param int       $post_id    Optional. Will fall back to loop.
     * @param int       $limit      Optional. Number of posts to return.
     * @param bool          $previous       Optional. Whether to retrieve previous or next posts.
     * @param bool          $in_same_term   Optional. Whether post should be in a same taxonomy term.
     * @param array|string  $excluded_terms Optional. Array or comma-separated list of excluded term IDs.
     * @param string        $taxonomy       Optional. Taxonomy, if $in_same_term is true. Default 'category'.
     * @return mixed        Array of post objects if successful. Null if global $post is not set. Empty string if no corresponding post exists.
     */
    function pst_get_adjacent_posts( $post_id = null, $limit = 1, $previous = true, $in_same_term = false, $excluded_terms = '', $taxonomy = 'category' ) {
        global $wpdb;
    
        if ( ( ! $post = get_post( $post_id ) ) || ! taxonomy_exists( $taxonomy ) )
            return null;
    
        $current_post_date = $post->post_date;
    
        $join = '';
        $posts_in_ex_terms_sql = '';
        if ( $in_same_term || ! empty( $excluded_terms ) ) {
            $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_term ) {
                if ( ! is_object_in_taxonomy( $post->post_type, $taxonomy ) )
                    return '';
                $term_array = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
                if ( ! $term_array || is_wp_error( $term_array ) )
                    return '';
                $join .= $wpdb->prepare( " AND tt.taxonomy = %s AND tt.term_id IN (" . implode( ',', array_map( 'intval', $term_array ) ) . ")", $taxonomy );
            }
    
            $posts_in_ex_terms_sql = $wpdb->prepare( "AND tt.taxonomy = %s", $taxonomy );
            if ( ! empty( $excluded_terms ) ) {
                if ( ! 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', 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 ( ! empty( $term_array ) ) {
                    $excluded_terms = array_diff( $excluded_terms, $term_array );
                    $posts_in_ex_terms_sql = '';
                }
    
                if ( ! empty( $excluded_terms ) ) {
                    $posts_in_ex_terms_sql = $wpdb->prepare( " AND tt.taxonomy = %s AND tt.term_id NOT IN (" . implode( $excluded_terms, ',' ) . ')', $taxonomy );
                }
            }
        }
    
        $adjacent = $previous ? 'previous' : 'next';
        $op = $previous ? '<' : '>';
        $order = $previous ? 'DESC' : 'ASC';
    
        /**
         * Filter 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
         *
         * @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.
         */
        $join  = apply_filters( "get_{$adjacent}_post_join", $join, $in_same_term, $excluded_terms );
    
        /**
         * Filter 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
         *
         * @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.
         */
        $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_terms_sql", $current_post_date, $post->post_type), $in_same_term, $excluded_terms );
    
        /**
         * Filter 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
         *
         * @param string $order_by The ORDER BY clause in the SQL.
         */
        $sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT $limit" );
    
        $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 = array_map( 'get_post', $result );
            return $result;
        }
    
        $result = $wpdb->get_col( $query );
        if ( null === $result )
            $result = '';
    
        wp_cache_set( $query_key, $result, 'counts' );
    
        if ( $result )
            $result = array_map( 'get_post', $result );
    
        return $result;
    }
    

    • 0

Оставить ответ

You must login to add an answer.