Задать вопрос
@roman2959

Как сделать перевод локальных атрибутов в глобальные на WooCommerce при сохранении товара?

Задача следующая: при сохранении товара, проверять его атрибуты, и если они локальные - переводить в глобальные, добавляя соответствующие опции, проверяя уникальность и т.д.

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

Я добавил тестовый вывод логов, вот что в нём вижу:

Product ID: 54624
Глобальный атрибут с именем Длина УЖЕ СУЩЕСТВУЕТ
Опция Длина -> 10см УЖЕ СУЩЕСТВУЕТ (ID 1368)
Глобальный атрибут с именем Бренд УЖЕ СУЩЕСТВУЕТ
Опция Бренд -> новый бренд УЖЕ СУЩЕСТВУЕТ (ID 1369)
Глобальный атрибут с именем Тест УЖЕ СУЩЕСТВУЕТ
Опция Тест -> тест УЖЕ СУЩЕСТВУЕТ (ID 1370)
Глобальный атрибут с именем newattr УЖЕ СУЩЕСТВУЕТ
Опция newattr -> newaattr УЖЕ СУЩЕСТВУЕТ (ID 1371)
Локальные атрибуты удалены
Сохраняем продукт


Но в товаре по-прежнему вижу локальные атрибуты, в глобальные не переводится.

Вот код:

add_action('save_post_product', 'convert_local_to_global_attributes', 10, 3);

function convert_local_to_global_attributes($product_id, $post, $update) {

    $test_mode = false;
    $writelog = true;

    $logfile = __DIR__ . '/atrlog.txt';

    $logs = [];
    $logs[] = 'Product ID: ' . $product_id;

    $product = new \WC_Product($product_id);
    $product_attributes = $product->get_attributes();

    if (empty($product_attributes)) {
        $logs[] = 'Атрибуты для товара отсутствуют.';
        if ($writelog === true) {
            file_put_contents($logfile, implode(PHP_EOL, $logs) . PHP_EOL . PHP_EOL, FILE_APPEND);
        }
        return;
    }

    foreach ($product_attributes as $attribute_key => $attribute) {
        
        $attribute_name = $attribute->get_name();
        $attribute_options = $attribute->get_options();

        if ($attribute->get_id() > 0) {
            $logs[] = "$attribute_name - Это уже глобальный атрибут, пропускаем";
            continue;
        }

        $attribute_id = wc_attribute_taxonomy_id_by_name($attribute_name);

        if (empty($attribute_id) or $attribute_id == 0) {
            $attribute_id = wc_attribute_taxonomy_id_by_name(mb_strtolower($attribute_name));
        }

        if (empty($attribute_id) or $attribute_id == 0) {
            $attribute_name = mb_convert_case(mb_strtolower($attribute_name), MB_CASE_TITLE, "UTF-8");
            $attribute_id = wc_attribute_taxonomy_id_by_name($attribute_name);
        }

        // Транслитерация имени атрибута для создания slug
        $attribute_name_slug = str_replace(' ', '-', mb_strtolower(transliterate($attribute_name)));
        $term_name = "pa_" . $attribute_name_slug;

        if (!empty($attribute_id) and $attribute_id > 0) {
            $logs[] = "Глобальный атрибут с именем <b>$attribute_name</b> УЖЕ СУЩЕСТВУЕТ";
        } else {
            if ($test_mode === false) {
                $attribute_id = wc_create_attribute([
                    'name' => $attribute_name,
                    'type' => 'text',
                ]);
                register_taxonomy($term_name, array('product'), array());
            } else {
                $attribute_id = 1;
            }
        
            if (!is_int($attribute_id)) {
                $err = $attribute_id->get_error_message();
                $logs[] = "[ERROR] ОШИБКА ПРИ СОЗДАНИИ ГЛОБАЛЬНОГО АТРИБУТА, ОСТАВЛЯЕМ ЕГО ЛОКАЛЬНЫМ. <b>$attribute_name</b> - $err";
                continue;
            }

            $logs[] = "Создан глобальный атрибут с именем <b>$attribute_name</b>";
        }

        $term_options = [];
        
        $continue = false;

        foreach ($attribute_options as $opt) {
            if (!$term = get_term_by('name', $opt, $term_name)) {
                $logs[] = "Добавляем опцию: $attribute_name -> $opt";

                if ($test_mode === false) {
                    $term_data = wp_insert_term($opt, $term_name);

                    if (is_wp_error($term_data)) {
                        $err = $term_data->get_error_message();
                        $logs[] = "[ERROR] Ошибка при добавлении новой опции ($err). Оставляем атрибут локальным. Таксономия: $term_name"; 
                        $continue = true;
                        break;  
                    }

                    $term_id = $term_data['term_id'];

                    $logs[] = "Добавили опцию ID $term_id";
                }
            } else {
                $term_id = $term->term_id;
                $logs[] = "Опция $attribute_name -> $opt УЖЕ СУЩЕСТВУЕТ (ID $term_id)";
            }

            $term_options[] = $term_id;
        }

        if ($continue === true) {
            continue;
        }

        $attribute->set_id($attribute_id);
        $attribute->set_name($term_name);
        $attribute->set_options($term_options);

        $product_attributes[$attribute_key] = $attribute;
    }
        
    if ($test_mode === false) {
        $logs[] = 'Локальные атрибуты удалены';
        $logs[] = "Сохраняем продукт";

        $product->set_attributes($product_attributes);
        $product->save();
    } else {
        $logs[] = 'TEST MODE - ничего не делаем';
    }

    if ($writelog === true) {
        file_put_contents($logfile, implode(PHP_EOL, $logs) . PHP_EOL . PHP_EOL, FILE_APPEND);
    }
}
  • Вопрос задан
  • 56 просмотров
Подписаться 1 Средний 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы