Как создать элемент таксономии wp_insert_term с своим ID?

Ссылка скопирована
1 ответ

На сайте есть кастомный тип записей и кастомная таксономия для этого типа. Делаю скрипт импорта древа категорий из CSV. Необходимо добавить элемент для кастомной таксономии

Набросал такой код (это отрывок, но суть думаю ясна)

В $row['parent_page_id'] - id элемента таксономии
$first_cat_id = get_term_by( 'id', $row->page_id, 'category_gifts','ARRAY_A');
if (is_array($first_cat_id)) {
echo ' Есть ID - '.$first_cat_id['term_id'].'
';
}
else {
echo ' Будет создана
';
wp_insert_term($row->name,'category_gifts');
}

Он проверяет есть ли элемент таксономии с нужным id. Если его нет то создает новый. Но id задается автоматически а мне нужно указать свой. Возможно ли это сделать ? Может нужно использовать не wp_insert_term а другую функцию. На просторах интернета не нашел как задать свой id при создании элемента таксономии

Дополнительно

Накопал на формах США. Делается так

В $row['parent_page_id'] - id элемента таксономии
$first_cat_id = get_term_by( 'id', $row->page_id, 'category_gifts','ARRAY_A');
if (is_array($first_cat_id)) {
echo ' Есть ID - '.$first_cat_id['term_id'].'';
}
else {
echo ' Будет создана';

$wpdb->insert($wpdb->prefix.'terms', array('term_id' => $row->page_id,'name' => $row->name,'slug' => $row->uri));
$wpdb->insert($wpdb->prefix.'term_taxonomy',array('term_taxonomy_id' => $row->page_id,,'term_id' => $row->page_id,'taxonomy' => 'category_gifts','parent' => 0));

}

Дописать уже можно под свои нужды, но я понял что мне не подходит

Ответы:

Используйте wpdb, он позволяет производить с базой вообще любые манипуляции. Но помните, что инструмент этот нужно использовать с соблюдением предосторожностей.

  • Да, совершенно верно, я уже и сам накопал на Ассашайских форумах. Но понял что есть косяк, wp_terms содержит все термы для всех типов записей. И если допустим в другой таксономии будет создан термин с таки-же id как в csv, то все полетит бородой. Нужно все-таки через wp_insert_term делать, а связывать с записям через отдельную таблицу
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Алексей Денисов Ответ

Через wp_insert_term нельзя задать свой term_id. WordPress сам выдаёт ID через AUTO_INCREMENT, и это не случайное ограничение. Термины в WordPress живут не только в таблице terms: связь с конкретной таксономией хранится в term_taxonomy, метаданные в termmeta, связи с записями в term_relationships. Если руками вставить одинаковые ID или перепутать term_id и term_taxonomy_id, можно получить дубли, неправильных родителей, битый кеш терминов и проблемы в других таксономиях.

Правильная схема импорта: внешний ID из CSV хранить отдельно, например в term meta. Внутренний term_id остаётся тем, который назначил WordPress. При следующем прогоне скрипт ищет термин по external_id, а если его нет, создаёт через wp_insert_term и записывает external_id. Так импорт становится повторяемым и не зависит от внутренних ID WordPress.

function site_find_term_by_external_id($external_id, $taxonomy) {
    $terms = get_terms(array(
        'taxonomy' => $taxonomy,
        'hide_empty' => false,
        'fields' => 'ids',
        'number' => 1,
        'meta_key' => 'external_id',
        'meta_value' => (string) $external_id,
    ));
 
    if (is_wp_error($terms) || empty($terms)) {
        return 0;
    }
 
    return (int) $terms[0];
}
 
$taxonomy = 'category_gifts';
$external_id = absint($row['page_id']);
$term_id = site_find_term_by_external_id($external_id, $taxonomy);
 
if (! $term_id) {
    $result = wp_insert_term($row['name'], $taxonomy, array(
        'slug' => sanitize_title($row['uri'] ?: $row['name']),
    ));
 
    if (is_wp_error($result)) {
        return;
    }
 
    $term_id = (int) $result['term_id'];
    update_term_meta($term_id, 'external_id', $external_id);
}

function site_find_term_by_external_id($external_id, $taxonomy) { $terms = get_terms(array( 'taxonomy' => $taxonomy, 'hide_empty' => false, 'fields' => 'ids', 'number' => 1, 'meta_key' => 'external_id', 'meta_value' => (string) $external_id, )); if (is_wp_error($terms) || empty($terms)) { return 0; } return (int) $terms[0]; } $taxonomy = 'category_gifts'; $external_id = absint($row['page_id']); $term_id = site_find_term_by_external_id($external_id, $taxonomy); if (! $term_id) { $result = wp_insert_term($row['name'], $taxonomy, array( 'slug' => sanitize_title($row['uri'] ?: $row['name']), )); if (is_wp_error($result)) { return; } $term_id = (int) $result['term_id']; update_term_meta($term_id, 'external_id', $external_id); }

Для древовидной структуры лучше делать импорт в два прохода. На первом проходе создаются все термины и сохраняется связь внешний ID → term_id. На втором проходе выставляются родители, потому что родительский термин к этому моменту уже точно существует.

$parent_external_id = absint($row['parent_page_id']);
$parent_term_id = $parent_external_id ? site_find_term_by_external_id($parent_external_id, $taxonomy) : 0;
 
if ($parent_term_id) {
    wp_update_term($term_id, $taxonomy, array(
        'parent' => $parent_term_id,
    ));
}

$parent_external_id = absint($row['parent_page_id']); $parent_term_id = $parent_external_id ? site_find_term_by_external_id($parent_external_id, $taxonomy) : 0; if ($parent_term_id) { wp_update_term($term_id, $taxonomy, array( 'parent' => $parent_term_id, )); }

Вставка напрямую через wpdb в terms и term_taxonomy допустима только в контролируемой миграции на пустой или специально подготовленной базе, когда вы полностью понимаете состояние всех таблиц и потом чистите кеши, пересчитываете связи и проверяете AUTO_INCREMENT. Для обычного импорта на живом сайте это плохой путь. Особенно важно, что terms содержит термины всех таксономий, а slug и term_id не являются изолированными внутри одной вашей category_gifts.

  • Не пытайтесь сделать term_id равным ID из CSV.
  • Храните CSV ID в external_id или другом понятном meta key.
  • Для родителей используйте найденный WordPress term_id, а не внешний ID.
  • Перед повторным импортом ищите существующий термин по external_id, чтобы не плодить дубли.

Так вы сохраните связь с внешней системой и при этом не будете ломать внутреннюю модель таксономий WordPress.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно