Вопрос или проблема
У меня есть код для пользовательского cron в WordPress multisite, который получает посты и метаданные постов из каждого блога и помещает их в XML-структуру.
Но когда я извлекаю метаданные (используя get_post_meta
) из каждого блога (используя switch_to_blog
), я получаю данные с главного сайта (blog_id=1), а не с сайта, который мне нужен (например, blog_id=33).
Вот пример части моего кода:
function generate_xml(33);
function generate_xml($blog_id){
global $wpdb;
$change_ok = switch_to_blog($blog_id);
if ( is_wp_error($change_ok) ) {
WriteErrorLog($change_ok->get_error_message());
}
else {
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><data></data>', null, false);
$Body = $xml->addChild('Body');
$add_adverts = $Body->addChild('add_adverts');
$sql_posts = "select id, post_title, post_content from wp_".$blog_id."_posts where post_type="custom_add" and post_status="publish"";
$result_posts = $wpdb->get_results ($sql_posts);
foreach ( $result_posts as $data_posts ){
$post_id_loop = $data_posts->id;
$advert = $add_adverts->addChild('advert');
//...
$price = get_post_meta($post_id_loop, '_price', true);
$advert->addChild('price', $price);
$color = get_post_meta($post_id_loop, '_color', true);
$advert->addChild('color', $color);
$size = get_post_meta($post_id_loop, '_size', true);
$advert->addChild('size', $size);
//...
}
}
//... больше кода
restore_current_blog();
}
Сводка данных в таблицах базы данных такова:
Но данные, которые я получаю, такие:
Как я могу использовать get_post_meta()
на каждом блоге после выполнения switch_to_blog()
?
читая ваш код …
if ( is_wp_error($change_ok) ) {
WriteErrorLog($change_ok->get_error_message());
}
не применимо, так как $change_ok всегда будет true. ссылка https://codex.wordpress.org/Function_Reference/switch_to_blog
как указывают комментарии, лучше использовать get_posts(), и это может решить вашу проблему, в противном случае используйте $wpdb->prepare перед вашими get_results.
также комментарий заключается в том, что ваш SQL-запрос не сработает для основного сайта..
$sql_posts = "select id, post_title, post_content from wp_".$blog_id."_posts where post_type="custom_add" and post_status="publish"";
Обратите внимание, что префикс таблицы “wp_” может быть изменен в файле wp-config.php, и если сайт использует жестко закодированный префикс “wp_”, то $wpdb->base_prefix
может быть использован, чтобы всегда подгонять “wp_” под текущий сайт.
также wp_".$blog_id."_posts
не будет работать для основного сайта, так как структура таблиц различается.
простая функция для получения префикса таблицы базы данных WP текущего сайта…
// Получение префикса базы данных
function get_blog_prefix( $blog_id=null ) {
global $wpdb;
if ( null === $blog_id ) {
$blog_id = $wpdb->blogid;
}
$blog_id = (int) $blog_id;
if ( defined( 'MULTISITE' ) && ( 0 == $blog_id || 1 == $blog_id ) ) {
return $wpdb->base_prefix;
} else {
return $wpdb->base_prefix . $blog_id . '_';
}
}
Ответ или решение
Проблема с получением метаданных постов в WordPress Multisite после использования функции switch_to_blog
может возникнуть по нескольким причинам. Давайте рассмотрим несколько ключевых аспектов, которые помогут вам устранить эту ошибку и правильно извлечь данные.
1. Понимание контекста работы с switch_to_blog
Функция switch_to_blog($blog_id)
позволяет переключаться между сайтами в сети WordPress Multisite. После успешного переключения все последующие вызовы функций WordPress, включая get_post_meta()
, должны работать в контексте выбранного сайта. Однако, если вы получаете данные из основного сайта (blog_id=1), это может указывать на несколько вызовов функции в одном контексте или на том, что данные не загружаются должным образом.
2. Проблема с SQL-запросами
Ваш SQL-запрос, который вы используете для получения постов, формируется следующим образом:
$sql_posts = "select id, post_title, post_content from wp_".$blog_id."_posts where post_type='custom_add' and post_status='publish'";
Замечания:
- Кавычки: Используйте одинарные кавычки в SQL запросе для строковых литералов, чтобы избежать путаницы.
- Префикс таблицы: Префикс
wp_
может быть изменен вwp-config.php
, поэтому следует использовать$wpdb->base_prefix
илиget_blog_prefix($blog_id)
для получения правильного префикса в зависимости от текущего сайта. Это обеспечит совместимость с различными конфигурациями базы данных.
3. Рекомендация использовать get_posts()
Вместо ручного формирования SQL-запроса рекомендуется использовать метод get_posts()
, который автоматически будет работать с нужным контекстом сайта. Вот пример, как можно переписать ваш код:
$args = array(
'post_type' => 'custom_add',
'post_status' => 'publish',
'numberposts' => -1
);
$result_posts = get_posts($args);
foreach ($result_posts as $data_posts) {
$post_id_loop = $data_posts->ID;
$advert = $add_adverts->addChild('advert');
// Получение метаданных
$price = get_post_meta($post_id_loop, '_price', true);
$advert->addChild('price', $price);
$color = get_post_meta($post_id_loop, '_color', true);
$advert->addChild('color', $color);
$size = get_post_meta($post_id_loop, '_size', true);
$advert->addChild('size', $size);
}
4. Обработка ошибок
Код обработки ошибок, связанный с switch_to_blog()
, в вашем примере не совсем корректен, так как функция не возвращает объект WP_Error
. Убедитесь, что ваша проверка успешности переключения на другой блог выполняется корректно.
if (!switch_to_blog($blog_id)) {
WriteErrorLog("Не удалось переключиться на блог: " . $blog_id);
return;
}
5. Восстановление исходного контекста
Не забудьте восстановить исходный контекст после выполнения всех операций с данными:
restore_current_blog();
Заключение
Следуя этим рекомендациям и исправляя указанные проблемы, вы сможете успешно получать метаданные постов для выбранного блога после использования функции switch_to_blog
. Убедитесь, что вся логика вашего кода правильно организована, и используйте функции WordPress для более эффективного и безопасного обращения с данными.