Получить список годов, когда были опубликованы записи

21 мая 2014 г., 21:04:26
Просмотры: 19.4K
Голосов: 7

Я хочу создать список записей из произвольного типа записи (Custom Post Type) и добавить фильтры, по которым пользователь сможет фильтровать этот список.

Я добавил фильтры для всех категорий, используя функцию get_terms(). Теперь я хочу добавить фильтры по годам, поэтому мне нужен способ получить список всех годов, в которых была опубликована хотя бы одна запись...

Мне нужно что-то вроде:

$years = get_all_years_with_posts();
// возвращает array( 2011, 2013, 2014 )

Я знаю, что могу получить все записи, проверить их год публикации и вручную построить список, но нет ли другого способа?

0
Все ответы на вопрос 5
6
16

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

function get_posts_years_array() {
    global $wpdb;
    $result = array();
    $years = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT YEAR(post_date) FROM {$wpdb->posts} WHERE post_status = 'publish' GROUP BY YEAR(post_date) DESC"
        ),
        ARRAY_N
    );
    if ( is_array( $years ) && count( $years ) > 0 ) {
        foreach ( $years as $year ) {
            $result[] = $year[0];
        }
    }
    return $result;
}

Для пользовательских типов записей потребуется небольшая модификация — просто добавьте AND wp_posts.post_type = 'my_cpt' в соответствующий участок запроса.

17 июл. 2017 г. 15:49:21
Комментарии

Мне потребовалось немного его доработать. Кажется, prepare() требует указания хотя бы одного аргумента формата %s (см. https://wordpress.stackexchange.com/a/270970/11914). Но решение сработало, я поставил плюс.

yuvilio yuvilio
5 апр. 2018 г. 20:33:14

Почему это именно верное решение?

idleberg idleberg
26 апр. 2019 г. 11:14:56

@idleberg Потому что на момент публикации моего ответа другой участник неправильно понял вопрос. Он привёл пример получения всех записей, отсортированных по году, но автор вопроса хотел получить список годов, в которых есть записи.

Gavin Gavin
10 мая 2019 г. 09:48:34

Это работает, однако, запрос получает все записи без учета их типа — убедитесь, что применяете фильтр по типу записи (WHERE post_type = 'posts'), иначе запрос вернет также и страницы.

Vincent Edward Gedaria Binua Vincent Edward Gedaria Binua
28 февр. 2021 г. 08:42:50

При включенном режиме отладки этот код вызывает уведомление 'Аргумент запроса в wpdb::prepare() должен содержать плейсхолдер'. Пожалуйста, отредактируйте этот ответ, добавив плейсхолдеры.

user45288 user45288
7 апр. 2021 г. 22:17:04

@user45288 Почему бы просто не убрать prepare, если параметров нет?

Rup Rup
8 апр. 2021 г. 02:23:31
Показать остальные 1 комментариев
1

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

$terms_year = array(
    'post_type'         => array('ВАШ_ПОЛЬЗОВАТЕЛЬСКИЙ_ТИП_ЗАПИСИ'),
);

$years = array();
$query_year = new WP_Query( $terms_year );

if ( $query_year->have_posts() ) :
    while ( $query_year->have_posts() ) : $query_year->the_post();
        $year = get_the_date('Y');
        if(!in_array($year, $years)){
            $years[] = $year;
        }
    endwhile;
    wp_reset_postdata();
endif;

// Вывод годов там, где вам нужно

echo '<pre>';
print_r($years);
echo '</pre>';
27 авг. 2018 г. 12:51:53
Комментарии

Это решение работает корректно после исправления опечатки (замены $query_jaar на query_year).

idleberg idleberg
26 апр. 2019 г. 11:14:26
0

Вы можете использовать функцию WP и шорткод следующим образом:

add_shortcode( 'archives', '_get_archived_posts' );
function _get_archived_posts( $atts ) {

 $a = shortcode_atts( array(
    'type'            => 'yearly',
    'limit'           => '',
    'format'          => '', 
    'before'          => '',
    'after'           => '',
    'show_post_count' => false,
    'echo'            => 0,
    'order'           => 'DESC'
), $atts, 'filter_archives_sc' );

    return wp_get_archives($a);
}

Источник

21 мая 2014 г. 21:20:13
0
// Получить все года публикации записей;
function get_posts_years_array($post_type = 'post') {

    global $wpdb;
    $result = array();

    $query_prepare = $wpdb->prepare("SELECT YEAR(post_date) FROM ($wpdb->posts) WHERE post_status = 'publish' AND post_type = %s GROUP BY YEAR(post_date) DESC", $post_type);

    $years = $wpdb->get_results($query_prepare);

    if ( is_array( $years ) && count( $years ) > 0 ) {
        foreach ( $years as $year ) {
            $result[] = json_decode(json_encode($year), true);
        }
    }

    return $result;
}
16 сент. 2019 г. 16:06:44
0

Я взял решение от @Gavin и улучшил его, добавив поддержку любых типов записей и любых статусов:

/**
 * Получить массив доступных годов для любого типа записей с любыми статусами
 * @see https://wordpress.stackexchange.com/a/273627/18713
 */
private function get_years_with_posts(
    string $post_type = 'post',
    array $post_stati = ['publish']
): array {
    /** @var wpdb $wpdb */
    global $wpdb;

    /** Конвертируем массив $post_stati в эквивалент MySql IN */
    $post_status_in = "('" . implode("', '", array_map('esc_sql', $post_stati)) . "')";

    /** Подготавливаем запрос с выбранным типом записи */
    $query = $wpdb->prepare(
        "SELECT YEAR(post_date)
        FROM {$wpdb->posts}
        WHERE post_status IN $post_status_in
        AND post_type = %s
        GROUP BY YEAR(post_date) DESC",
        $post_type
    );

    $years = $wpdb->get_results($query, ARRAY_N);

    return array_column($years, 0);
}

Пример использования: Получить все опубликованные и запланированные записи типа event:

$available_years = get_years_with_posts('event', ['publish', 'future']);
20 февр. 2024 г. 12:07:18