Задача следующая: при сохранении товара, проверять его атрибуты, и если они локальные - переводить в глобальные, добавляя соответствующие опции, проверяя уникальность и т.д.
У меня есть функция, но при сохранении товара атрибуты остаются локальными, при этом новые глобальные добавляются с опциями.
Я добавил тестовый вывод логов, вот что в нём вижу:
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);
}
}