the_post() внутри switch_to_blog() изменяет мой анонс

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

У меня есть странная проблема, с которой я сталкиваюсь при использовании WP_Query с мультисайтом в плагине, который я пишу и который подключается к add_meta_boxes. Я хочу отобразить все заголовки постов в выпадающем списке в мета-боксе.

При добавлении или редактировании поста в блоге № 2 (это может быть любой блог), я перебираю блог № 1 и получаю заголовки постов из кастомного типа постов, чтобы заполнить выпадающий список select. Это работает, как и должно, но в процессе текст в моем экстракте заменяется экстрактом последнего поста в цикле.

Я отключил все плагины. Я включил тему 2015 года на всех сайтах. Я использую WordPress 4.1. Я пробовал с обычными постами вместо кастомных, и проблема все еще существует. Вот код, который я использую:

switch_to_blog( 1 ); 
$qry_args = array(
    'post_status' => 'publish',     
    'post_type' => $typenow,        
    'posts_per_page' => -1,         
    );

$blog_query = new WP_Query( $qry_args );

if ( $blog_query->have_posts() ) {  
    while ( $blog_query->have_posts() ) {
        $blog_query->the_post();

        // get_the_ID(); and put in an <option></option>                 
    }
} 
wp_reset_postdata();
restore_current_blog();     

Я сузил источник проблемы до строки $blog_query->the_post();

Может кто-нибудь указать, почему мой экстракт в посте в блоге 2 заменяется экстрактом из поста в блоге 1, когда я перебираю блог 1? Я довольно нов в написании плагинов, поэтому, возможно, я делаю что-то неправильно, о чем не знаю.

Спасибо за вашу помощь,

Адриан

ИСПРАВЛЕНИЕ:

Я только что сделал еще несколько тестов и обнаружил, что получаю следующее предупреждение PHP с плагином Query Monitor:

Ошибка PHP:
Попытка получить свойство не-объекта

Количество:
6

Местоположение:
wp-includes/capabilities.php:1203

Стек вызовов:
map_meta_cap()
WP_User->has_cap()
current_user_can()
meta_form()
post_custom_meta_box()
do_meta_boxes()

Когда я размещаю вышеуказанный код в admin_footer вместо add_meta_boxes, проблема решается. Так что, похоже, это может быть проблема с таймингом?? Если да, то как я могу сделать запрос к своим постам в add_meta_boxes?

Проверьте, что вы получаете. new WP_Query() не работает по какой-то причине. Вызовите var_dump для этого. Я подозреваю, что вы не получаете никаких результатов от запроса, что приводит к Попытка получить свойство не-объекта, когда вы пытаетесь получить доступ к методам.

Вы сбрасываете данные поста перед тем, как вернуться к исходному блогу. Это означает, что глобальные переменные, связанные с постом, будут установлены в что-то неожиданное в блоге 1, потому что вы все еще находитесь в его контексте.

Правильный порядок должен быть:

restore_current_blog();
wp_reset_postdata();

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

Причины проблемы с the_post() и switch_to_blog()

Проблема, с которой вы столкнулись, связана с использованием функции the_post() в сочетании с функцией switch_to_blog(). Основная проблема в том, что при переключении между блогами в сетевом пространстве WordPress, глобальные переменные, которые управляют состоянием поста, могут быть неправильно настроены, если вы не правильно сбрасываете их после выполнения цикла. Это может приводить к тому, что при редактировании поста в одном блоге, данные из другого блога могут влиять на текущий контекст, в первую очередь, на содержимое экстрактов и заголовков.

Обстоятельства возникновения проблемы

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

Решение проблемы

Чтобы устранить данную проблему, необходимо правильно восстановить состояние глобальной переменной поста после завершения работы с switch_to_blog(). Вот корректная последовательность действий:

  1. Сначала выполните необходимые действия с переменной глобального поста, используя the_post().
  2. После завершения работы с постами текущего блога, вызовите restore_current_blog() для возврата к первоначальному блогу.
  3. Затем выполните wp_reset_postdata() для сброса глобальных переменных поста.

Таким образом, правильная последовательность кода будет выглядеть следующим образом:

switch_to_blog( 1 ); 
$qry_args = array(
    'post_status' => 'publish',     
    'post_type' => $typenow,        
    'posts_per_page' => -1,         
);

$blog_query = new WP_Query( $qry_args );

if ( $blog_query->have_posts() ) {  
    while ( $blog_query->have_posts() ) {
        $blog_query->the_post();
        // Получаем ID поста и выводим в <option></option>                 
    }
}
wp_reset_postdata(); // Сбрасываем после работы с блогом 1
restore_current_blog(); // Восстанавливаем текущий блог

Устранение ошибок

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

Итоги

Сложности, которые возникают при работе с мультисайтовой сетью WordPress, требуют осторожного обращения с глобальными переменными. Корректное использование функций switch_to_blog() и wp_reset_postdata() критично для поддержания целостности данных при работе в разных блогах. Убедитесь, что код выполняется в правильное время, поскольку обработка мета-боксов происходит на этапе, который может иметь некоторые ограничения. Если ваш код работает в admin_footer, возможно, вам стоит пересмотреть, как инициализируется запрос, чтобы избежать подобных проблем в мета-боксах.

Надеюсь, это поможет вам в решении проблемы. Если у вас есть дополнительные вопросы, не стесняйтесь обращаться.

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

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