Мета, вставленная через wp_insert_post, портится.

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

Я расширяю функциональность импорта 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, возвращаются не в том формате, как ожидалось.

Описание проблемы

В вашем коде вы пытаетесь вставить два метаданных:

  1. ct_external_link_url — строка (URL).
  2. ct_hide_from_frontent — булевый тип (boolean).

Однако после выполнения команды wp_insert_post вы заметили, что метаданные сохраняются как массив, а не как отдельное булевое значение. На первый взгляд это может показаться незначительной ошибкой, но это может иметь серьёзные последствия, особенно если у вас ограниченные возможности для извлечения этих метаданных в будущем.

Причина проблемы

Причиной этого поведения является способ, которым WordPress обрабатывает метаданные. При использовании wp_insert_post с meta_input, если ключ уже существует в таблице wp_postmeta, значение, переданное в meta_input, будет добавлено в существующую запись как новый элемент массива. В вашем случае, когда вы передаёте булевое значение, оно сохраняется как массив с одним элементом, и это может вызывать путаницу.

Когда вы добавляете метаданные с помощью add_post_meta, если указать третий аргумент как true, это создаст новое метаданные, если оно не существует, и сохранит значение как отдельную запись. Это и объясняет, почему в последнем варианте кода всё работает корректно.

Решение

Чтобы избежать ситуации, когда булевое значение сохраняется как массив, используйте следующее решение:

  1. Добавление метаданных после вставки поста: Как вы делаете во втором примере кода, сохраните метаданные с помощью 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);
    }
}
  1. Проверка существования метаданных: Если необходимо сохранить метаданные при использовании meta_input, вы можете выполнить проверку на существование значения и использовать update_post_meta, чтобы обновить существующие значения.

Заключение

Работа с метаданными в WordPress может иногда вести к непредвиденным последствиям, если не учитывать, как платформа управляет данными. Использование методов add_post_meta или update_post_meta даёт больше контроля над тем, как данные сохраняются, и предотвращает ошибочное хранение значений как массивов. Оптимизируя свой код таким образом, вы обеспечиваете более высокую степень предсказуемости в работе с метаданными ваших пользовательских типов записей.

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

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