Вопрос или проблема
Я расширяю функциональность импорта CSV продуктов Woocommerce, чтобы импортировать больше данных.
Я вставляю пользовательский тип записи (CPT) с двумя метаданными: строкой (URL) и булевым значением, и вставленные post_meta нарушаются. Вставляется массив для мета, который должен содержать булево значение.
Снимок кода:
$link = array(
'url' => $url // строка
'caption' => $caption // строка
'hide' => $hide // булево
$meta_input = array(
'ct_external_link_url' => $link['url']
);
if( isset($link['hide']) ) {
$meta_input += ['ct_hide_from_frontent' => $link['hide']];
}
$postarr = array(
'post_title' => $link['caption'],
'post_type' => 'ct_external_link',
'post_status' => 'publish',
'post_excerpt' => $link['caption'],
'meta_input' => $meta_input
);
write_log("Аргументы для вставки поста внешней ссылки:"); // write_log выводит в debug.txt
write_log($postarr);
$external_link_id = wp_insert_post($postarr);
$external_link = get_post($external_link_id, 'ARRAY_A');
if( !is_null($external_link)) {
write_log("Пост внешней ссылки:");
write_log($external_link);
write_log("Метаданные поста внешней ссылки:");
$meta = get_post_meta($external_link_id);
write_log($meta);
}
Поскольку я пишу логи, они выглядят следующим образом:
[15-Mar-2019 10:33:45 UTC] Аргументы для вставки поста внешней ссылки:
[15-Mar-2019 10:33:45 UTC] Массив
(
[post_title] => VÃdeo 1
[post_type] => ct_external_link
[post_status] => publish
[post_excerpt] => VÃdeo 1
[meta_input] => Массив
(
[ct_external_link_url] => https://www.youtube.com/watch?v=F0IbjVq-fgs&ab_channel=CollegeMusic
[ct_hide_from_frontent] => 1
)
)
[15-Mar-2019 10:33:45 UTC] Метаданные поста внешней ссылки:
[15-Mar-2019 10:33:45 UTC] Массив
(
[ct_hide_from_frontent] => Массив
(
[0] => 1
)
)
Обратите внимание, что, хотя значение для ключа ‘ct_hide_from_frontent’ является булевым в meta_input, из post_meta оно выводится как массив. Почему?
Спасибо!
В итоге я просто добавил мета после вставки поста, что не вызывает ошибок. Это обходит проблему, не объясняя её, однако…
$postarr = array(
'post_title' => $link['caption'],
'post_type' => 'ct_external_link',
'post_status' => 'publish',
'post_excerpt' => $link['caption'],
);
$external_link_id = wp_insert_post($postarr);
if( !empty($external_link_id) ) {
add_post_meta($external_link_id, 'ct_external_link_url', $doc['file'], true);
if( isset($doc['hide']) ) {
add_post_meta($external_link_id, 'ct_hide_from_frontent', $doc['hide']);
}
}
Ответ или решение
Проблема с метаданными при использовании wp_insert_post
Когда вы работаете с функциональностью импорта CSV в WooCommerce, возможны определённые сложности, связанные с вставкой пользовательских типов записей (CPT) и метаданными через функцию wp_insert_post
. Как показывает ваша проблема, метаданные, вставленные в массив meta_input
, возвращаются не в том формате, как ожидалось.
Описание проблемы
В вашем коде вы пытаетесь вставить два метаданных:
ct_external_link_url
— строка (URL).ct_hide_from_frontent
— булевый тип (boolean).
Однако после выполнения команды wp_insert_post
вы заметили, что метаданные сохраняются как массив, а не как отдельное булевое значение. На первый взгляд это может показаться незначительной ошибкой, но это может иметь серьёзные последствия, особенно если у вас ограниченные возможности для извлечения этих метаданных в будущем.
Причина проблемы
Причиной этого поведения является способ, которым WordPress обрабатывает метаданные. При использовании wp_insert_post
с meta_input
, если ключ уже существует в таблице wp_postmeta
, значение, переданное в meta_input
, будет добавлено в существующую запись как новый элемент массива. В вашем случае, когда вы передаёте булевое значение, оно сохраняется как массив с одним элементом, и это может вызывать путаницу.
Когда вы добавляете метаданные с помощью add_post_meta
, если указать третий аргумент как true
, это создаст новое метаданные, если оно не существует, и сохранит значение как отдельную запись. Это и объясняет, почему в последнем варианте кода всё работает корректно.
Решение
Чтобы избежать ситуации, когда булевое значение сохраняется как массив, используйте следующее решение:
- Добавление метаданных после вставки поста: Как вы делаете во втором примере кода, сохраните метаданные с помощью
add_post_meta
. Это гарантирует, что значения будут храниться отдельно.
$postarr = array(
'post_title' => $link['caption'],
'post_type' => 'ct_external_link',
'post_status' => 'publish',
'post_excerpt' => $link['caption'],
);
$external_link_id = wp_insert_post($postarr);
if( !empty($external_link_id) ) {
add_post_meta($external_link_id, 'ct_external_link_url', $link['url'], true);
if( isset($link['hide']) ) {
add_post_meta($external_link_id, 'ct_hide_from_frontent', $link['hide'], true);
}
}
- Проверка существования метаданных: Если необходимо сохранить метаданные при использовании
meta_input
, вы можете выполнить проверку на существование значения и использоватьupdate_post_meta
, чтобы обновить существующие значения.
Заключение
Работа с метаданными в WordPress может иногда вести к непредвиденным последствиям, если не учитывать, как платформа управляет данными. Использование методов add_post_meta
или update_post_meta
даёт больше контроля над тем, как данные сохраняются, и предотвращает ошибочное хранение значений как массивов. Оптимизируя свой код таким образом, вы обеспечиваете более высокую степень предсказуемости в работе с метаданными ваших пользовательских типов записей.