нельзя создать атрибут продукта (таксономию) и добавить термины в одном выполнении

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

У меня есть следующие функции для создания глобального атрибута продукта и заполнения его терминами на основе данных из API.

protected function getOrCreateAttribute($slug, $name)
    {
        $taxonomyId = wc_attribute_taxonomy_id_by_name($slug);
        if (!empty($taxonomyId) && $taxonomyId > 0) {
            return $taxonomyId;
        }
        $taxonomyId = wc_create_attribute([
            'name' => $name,
            'slug' => $slug,
            'type' => 'select',
        ]);
        if ($taxonomyId instanceof \WP_Error) {
            throw new Exception($taxonomyId->get_error_message());
        }
        return $taxonomyId;
    }

    protected function getOrCreateTerm($slug, $name, $taxonomySlug)
    {
        $term = get_term_by('slug', $slug, $taxonomySlug);
        if ($term === false) {
            clean_taxonomy_cache($taxonomySlug);
            /** @var \WP_Term|\WP_Error $term */
            $term = wp_insert_term($name, $taxonomySlug, ['slug' => $slug]);
            clean_term_cache($term->term_id, $taxonomySlug);
        }
        if ($term instanceof \WP_Error) {
            throw new Exception($term->get_error_message());
        }
        return $term;
    }

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

Наконец, я пытаюсь добавить их к продукту.

            foreach ($featuresGroup->Features as $feature) {
                $taxonomyName = $feature->Feature->Name->Value;
                $taxonomySlug = $this->slugger->slugify($taxonomyName);
                $taxonomyId = $this->getOrCreateAttribute($taxonomySlug, $taxonomyName);
                $attribute = wc_get_attribute($taxonomyId);

                $termsToSet = [];
                $termName = $feature->PresentationValue;
                $termSlug = $this->slugger->slugify($termName);
                $term = $this->getOrCreateTerm($termSlug, $termName, $attribute->slug);

                $termsToSet[] = $term->term_id;
                if (array_key_exists($attribute->slug, $productAttributes)) {
                    $productAttribute = &$productAttributes[$attribute->slug];
                    $productAttribute->set_options($termsToSet);
                } else {
                    $wcProductAttribute = new \WC_Product_Attribute();
                    $wcProductAttribute->set_name($attribute->name);
                    $wcProductAttribute->set_id($attribute->id);
                    $wcProductAttribute->set_visible(1);
                    $wcProductAttribute->set_options($termsToSet);
                    $productAttributes[$attribute->slug] = $wcProductAttribute;
                }
            }

Теперь моя проблема здесь в том, что мне нужно запускать один и тот же фрагмент кода несколько раз, чтобы на самом деле получить результат, и я не уверен, почему. Обычно при первом запуске я сталкиваюсь с ошибкой

Неверная таксономия

Во время выполнения wp_insert_term, что вместо создания WP_Term приводит к WP_Error

Однако если я запускаю его несколько раз, все в конечном итоге создается.

Я не уверен, что здесь происходит.

Я пытался очистить кэши термов и таксономий на случай, если это было неудачно из-за кэша, но безуспешно.

Позвольте мне добавить немного информации, например, переменную $attribute перед вызовом функции getOrCreateTerm

вставьте описание изображения сюда

И результат taxonomy_exists показывает false во время wp_insert_term, даже если он был четко определен ранее и имеет ID

вставьте описание изображения сюда

В конце я добавил быструю проверку с

taxonomy_exists($slug)

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

register_taxonomy($taxonomySlug, 'product')

Это, похоже, позволило создать все термины за один раз.

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

Когда вы работаете с продуктами в WooCommerce и взаимодействуете с глобальными атрибутами и терминами, вам может понадобиться создавать атрибуты и добавлять термины к ним в одном цикле, однако возникают сложности, такие как ошибочное сообщение "Invalid taxonomy". Давайте рассмотрим вашу ситуацию более подробно и проанализируем, как можно оптимизировать процесс.

Проблема: Ошибка "Invalid taxonomy"

Ошибка "Invalid taxonomy" возникает во время выполнения функции wp_insert_term, когда система не может распознать таксономию, к которой вы пытаетесь добавить термин. Это может происходить по нескольким причинам:

  1. Кэширование: Кэширование может временно хранить устаревшую информацию о таксономиях. Вы уже пробовали очищать кэш таксономий и терминов, но это может быть недостаточно.

  2. Регистрация таксономий: Таксономия может не быть зарегистрирована к моменту, когда выполняется код добавления термина. Если при проверке с помощью taxonomy_exists возвращается FALSE, это говорит о том, что таксономия еще не была зарегистрирована.

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

Вы нашли временное решение, добавив проверку с помощью taxonomy_exists($slug) и вызвав register_taxonomy($taxonomySlug, 'product'), если таксономия не существует. Это действительно устранит проблему с регистрацией термина, так как register_taxonomy гарантирует, что таксономия будет зарегистрирована перед тем, как вы попытаетесь добавить к ней термины.

Пример кода

Вот как вы можете оптимизировать вашу логику:

protected function getOrCreateAttribute($slug, $name)
{
    // Проверяем, существует ли уже атрибут
    $taxonomyId = wc_attribute_taxonomy_id_by_name($slug);
    if (!empty($taxonomyId) && $taxonomyId > 0) {
        return $taxonomyId;
    }

    // Создаем новый атрибут
    $taxonomyId = wc_create_attribute([
        'name' => $name,
        'slug' => $slug,
        'type' => 'select',
    ]);

    if ($taxonomyId instanceof \WP_Error) {
        throw new Exception($taxonomyId->get_error_message());
    }

    return $taxonomyId;
}

protected function getOrCreateTerm($slug, $name, $taxonomySlug)
{
    // Проверяем, существует ли термин
    $term = get_term_by('slug', $slug, $taxonomySlug);
    if ($term === false) {
        clean_taxonomy_cache($taxonomySlug);

        // Если таксономия не существует, регистрируем её
        if (!taxonomy_exists($taxonomySlug)) {
            register_taxonomy($taxonomySlug, 'product');
        }

        // Добавляем новый термин
        /** @var \WP_Term|\WP_Error $term */
        $term = wp_insert_term($name, $taxonomySlug, ['slug' => $slug]);
        clean_term_cache($term->term_id, $taxonomySlug);
    }

    if ($term instanceof \WP_Error) {
        throw new Exception($term->get_error_message());
    }

    return $term;
}

Итог

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

Также важно убедиться, что вы вызываете функции в правильном порядке и правильно обрабатываете ошибки. Пробежавшись по коду, вы можете убедиться, что все проверки выполняются до операций, которые могут быть причиной возникновения ошибок.

Эта оптимизация позволила динамически и эффективно управлять атрибутами продуктов, что существенно упрощает обработку данных и интеграцию с API.

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

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