Разработка “резервного варианта” для пустых результатов wp_query

Вопрос или проблема

Я пытаюсь настроить “резервный” запрос для wp_query. Я хочу получить первый пост, которому один год, но если такого не существует, получить пост, которому один год и один день. А затем сохранить этот HTML в Advanced Custom Field on_this_day_1_year_ago. Первый код работает для одного поста, второй код с резервным вариантом ниже не работает и не дает никаких ошибок PHP. (Я знаю, что мое использование strtotime немного неаккуратное, и вся эта функция вероятно ресурсоемкая для базы данных).

Это то, с чего я начал; простой wp_query для поста годичной давности, и это работает.

$one_year_ago = date('Y-m-d', strtotime('-1 year'));

$args = array(
      'post_type' => 'post',  
      'posts_per_page' => 1,
      'post_status' => 'publish',
      'orderby' => 'date',
      'order' => 'DESC',
      'date_query' => array(
            array(
                'year'  => date('Y', strtotime($one_year_ago)),
                'month' => date('m', strtotime($one_year_ago)),
                'day'   => date('d', strtotime($one_year_ago)),
            ),
       ),
 );
$query = new WP_Query( $args ); 

ob_start();

    while( $query->have_posts() ) {
        $query->the_post();

        echo '<a href="' . get_permalink() '">';    
        the_title();
        echo '</a>';
    }
        endwhile;
        wp_reset_postdata();

$this_day_one_year_ago = ob_get_clean();

// Сохранение в поле ACF
update_field('on_this_day_1_year_ago', $this_day_one_year_ago, 'option');

Это резервный вариант для поста годичной давности и одного дня, который не работает. Какие-то идеи? Думаю, проблема в output_posts()

date_default_timezone_set('America/Chicago');
$one_year_ago = date('Y-m-d', strtotime('-1 year'));
$one_year_ago_plus_day = date('Y-m-d', strtotime('-367 days'));


function output_posts( $query ){

// получение вывода для сохранения в Advanced Custom Field

ob_start();

    while( $query->have_posts() ) {
        $query->the_post();

        echo '<a href="' . get_permalink() '">';    
        the_title();
        echo '</a>';
    }

    wp_reset_postdata();   

$this_day_one_year_ago = ob_get_clean();

// сохранение в настраиваемое поле

update_field('on_this_day_1_year_ago', $this_day_one_year_ago, 'option');

}

// аргументы для поста годичной давности

$args = array(
      'post_type' => 'post',  
      'posts_per_page' => 1,
      'post_status' => 'publish',
      'orderby' => 'date',
      'order' => 'DESC',
      'date_query' => array(
           array(
           'year'  => date('Y', strtotime($one_year_ago)),
           'month' => date('m', strtotime($one_year_ago)),
           'day'   => date('d', strtotime($one_year_ago)),
            ),
       ),
);

$query = new WP_Query( $args );

// Если в запросе есть посты

if( $query->have_posts() ) {

    output_posts( $query );    


// или резервный вариант - 367 дней

} else {

    // аргументы для поста годичной давности и одного дня

    $args = array(
        'post_type' => 'post',  
        'posts_per_page' => 1,
        'post_status' => 'publish',
        'orderby' => 'date',
        'order' => 'DESC',
        'date_query' => array(
         array(
        'year'  => date('Y', strtotime($one_year_ago_plus_day)),
        'month' => date('m', strtotime($one_year_ago_plus_day)),
        'day'   => date('d', strtotime($one_year_ago_plus_day)),
            ),
       ),
);

    $fallback = new WP_Query( $args );

    if ( $fallback->have_posts() ){

        output_posts( $fallback );       
    }
} 

Ответ или решение

Для решения задачи по созданию "аварийного" механизма для получения результатов WP_Query необходимо учитывать специфические детали работы с WP_Query и управлением датами в PHP. Давайте разберем этот процесс, чтобы обеспечить корректную работу вашего кода.

Теория

WP_Query — это класс в WordPress, который позволяет выполнять запросы к базе данных для извлечения записей, соответствующих определенным критериям. В вашем случае задача заключается в получении записи, опубликованной ровно год назад. Если таких записей нет, необходимо получить первую запись, опубликованную на день раньше (1 год и 1 день назад).

Пример

Далее я предоставлю исправленный и оптимизированный пример кода для вашей задачи. Рассмотрим типичные ошибки и ко

рректировки при работе с WP_Query:

date_default_timezone_set('America/Chicago');

// Определение дат для запросов
$one_year_ago = date('Y-m-d', strtotime('-1 year'));
$one_year_ago_plus_day = date('Y-m-d', strtotime('-367 days'));

// Функция для обработки и сохранения результатов запроса
function output_posts($query) {
    ob_start();

    while ($query->have_posts()) {
        $query->the_post();

        echo '<a href="' . get_permalink() . '">';
        the_title();
        echo '</a>';
    }

    wp_reset_postdata();

    $this_day_one_year_ago = ob_get_clean();

    // Сохранение в поле ACF
    update_field('on_this_day_1_year_ago', $this_day_one_year_ago, 'option');
}

// Параметры запроса для поиска записи год назад
$args = array(
    'post_type' => 'post',
    'posts_per_page' => 1,
    'post_status' => 'publish',
    'orderby' => 'date',
    'order' => 'DESC',
    'date_query' => array(
        array(
            'after'     => date('Y-m-d', strtotime('-1 year -1 day')),
            'before'    => date('Y-m-d', strtotime('-1 year +1 day')),
            'inclusive' => true,
        ),
    ),
);

$query = new WP_Query($args);

if ($query->have_posts()) {
    output_posts($query);
} else {
    // Параметры запроса для поиска записи год и один день назад
    $args['date_query'] = array(
        array(
            'year'  => date('Y', strtotime($one_year_ago_plus_day)),
            'month' => date('m', strtotime($one_year_ago_plus_day)),
            'day'   => date('d', strtotime($one_year_ago_plus_day)),
        ),
    );

    $fallback = new WP_Query($args);

    if ($fallback->have_posts()) {
        output_posts($fallback);
    }
}

Применение

В данном решении мы используем:

  1. ob_start() и ob_get_clean(): Эти функции PHP полезны для временного хранения вывода функций, таких как the_title() и get_permalink(), перед их сохранением в пользовательское поле ACF.

  2. Массив date_query: Чтобы избежать повторяющегося кода и сделать запросы более гибкими и корректными по времени, мы используем диапазон дат вместо строгого соответствия.

  3. Функция output_posts($query): Отдельная функция для обработки вывода позволяет избежать дублирования кода при обработке основного запроса и "аварийного" механизма.

Этот подход улучшает структуру и производительность кода, обеспечивая выполнение вашей задачи более эффективно и надежно.

Оцените материал
Добавить комментарий

Капча загружается...