Я хотел бы создать переменный продукт с атрибутами и вариациями программно, используя php - все это из плагина WordPress (так что HTTP-запрос к API отсутствует). Я успешно создал новый плагин, который добавляет продукт на основе входных значений [например, как простой продукт или переменный продукт].
Простые продукты добавляются успешно без каких-либо ошибок. Чтобы создать переменный продукт, я сослался на эту ссылку - Программно создать переменный продукт и два новых атрибута в WooCommerce и Программно создать вариант продукта WooCommerce с новыми значениями атрибутов
Моя проблема в том, что с помощью этого кода создается переменная product, но атрибуты добавляются неправильно. Например, если мои атрибуты RAM [4GB, 8GB] и Model [2017,2019], после добавления продуктов при открытии страницы продукта он отображает только один атрибут [RAM], и я не вижу атрибут Model и добавленные варианты для этих атрибутов тоже не добавляются. Даже в бэкэнде страницы продукта в разделе атрибутов указан только один атрибут. В некоторых продуктах атрибуты не указаны, и мои варианты не отображаются на главной странице продукта, а в бэкэнде раздел атрибутов пуст.
Ниже приведен код, который я использую для добавления переменного продукта. Я получаю значения из внешней БД и передаю их функции. Я вызываю эту функцию, создавая задание расписания [устанавливая цикл cron вручную], поэтому раз в 15 минут эта функция будет вызываться.
function create_variant_product( $data ){
if( ! function_exists ('save_product_attribute_from_name') ) return;
$postname = sanitize_title( $data['title'] );
$author = empty( $data['author'] ) ? '1' : $data['author'];
$post_data = array(
'post_author' => $author,
'post_name' => $postname,
'post_title' => $data['title'],
'post_content' => $data['content'],
'post_excerpt' => $data['excerpt'],
'post_status' => 'publish',
'ping_status' => 'closed',
'post_type' => 'product',
'guid' => home_url( '/product/'.$postname.'/' ),
);
// Creating the product (post data)
$product_id = wp_insert_post( $post_data );
//Method used to add the categories to the product
if(!empty($data['maincat'])){
wp_set_object_terms($product_id, $data['maincat'], 'product_cat' );
}
// Get an instance of the WC_Product_Variable object and save it
$product = new WC_Product_Variable( $product_id );
$product->save();
## ---------------------- Other optional data ---------------------- ##
## (see WC_Product and WC_Product_Variable setters methods)
$product->validate_props(); // Check validation
## ---------------------- VARIATION ATTRIBUTES ---------------------- ##
$product_attributes = array();
$productprice=$data['regular_price'];
$allvariation=$data['variationarray'];
$Headerarray=$data['Array'];
$servername=$data['servername'];
$serverpassword=$data['serverpassword'];
$dbname=$data['dbname'];
$serverhost=$data['serverhost'];
foreach( $data['attributes'] as $key => $terms ){
$taxonomy = wc_attribute_taxonomy_name($key); // The taxonomy slug
$attr_label = ucfirst($key); // attribute label name
$attr_name = (wc_sanitize_taxonomy_name($key)); // attribute slug
$attribute='';
// NEW Attributes: Register and save them
if(!taxonomy_exists( $taxonomy ) )
save_product_attribute_from_name( $attr_name, $attr_label );
foreach( $terms as $value ){
$attribute .= '|';
$attribute .= $value;
$term_name = ucfirst($value);
$term_slug = sanitize_title($value);
// Check if the Term name exist and if not we create it.
if(!term_exists($value, $taxonomy)){
wp_insert_term( $term_name, $taxonomy, array('slug' => $term_slug )); // Create the term
}
// Set attribute values
wp_set_object_terms( $product_id, $term_name, $taxonomy,True );
}
wp_set_object_terms( $product_id, $terms, $taxonomy, True );
$attribute = trim($attribute, '|');
$product_attributes[$taxonomy] = array (
'name' => $taxonomy,
'value' => $attribute,
'is_visible' => 1,
'is_variation' => 1,
'is_taxonomy' => 1
);
}
update_post_meta( $product_id, '_product_attributes', $product_attributes );
$product->save(); // Save the data
Код для добавления вариантов для добавленных выше атрибутов.
global $wpdb;
$mydb = new wpdb($servername,$serverpassword,$dbname,$serverhost);
foreach($allvariation as $key => $value) {
$total=0;
$totalsaleprice=0;
$totalsaleprice = $total+$productprice;
$ttttt = $totalsaleprice+$productprice;
//Get the Variable product object (parent)
$variation_post = array(
'post_author' => $author,
'post_title' => $product->get_name(),
'post_name' => 'product-'.$product_id.'-variation',
'post_status' => 'publish',
'post_parent' => $product_id,
'post_type' => 'product_variation',
'guid' => $product->get_permalink()
);
// Creating the product variation
$variation_id = wp_insert_post( $variation_post );
// Get an instance of the WC_Product_Variation object
$variation = new WC_Product_Variation($variation_id);
// Iterating through the variations attributes
foreach ($value as $attribute => $term_name)
{
$taxonomy = 'pa_'.$attribute; // The attribute taxonomy
// If taxonomy doesn't exists we create it (Thanks to Carl F. Corneil)
if( ! taxonomy_exists( $taxonomy ) ){
register_taxonomy(
$taxonomy,
'product_variation',
array(
'hierarchical' => false,
'label' => ucfirst( $attribute ),
'query_var' => true,
'rewrite' => array( 'slug' => sanitize_title($attribute)) // The base slug
)
);
}
// Check if the Term name exist and if not we create it.
if(!term_exists( $term_name, $taxonomy ))
wp_insert_term( $term_name, $taxonomy ); // Create the term
$term_slug = get_term_by('name', $term_name, $taxonomy )->slug; // Get the term slug
// Get the post Terms names from the parent variable product.
$post_term_names = wp_get_post_terms( $product_id, $taxonomy, array('fields' => 'names') );
// Check if the post term exist and if not we set it in the parent variable product.
//if(!in_array( $term_name, $post_term_names ))
wp_set_post_terms( $product_id, $term_name, $taxonomy,True );
wp_set_object_terms( $product_id, $term_name, $taxonomy, True);
// Set/save the attribute data in the product variation
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
}
## Set/save all other data
$variation->set_price( $ttttt );
$variation->set_sale_price( $totalsaleprice );
$variation->set_regular_price( $ttttt );
$variation->set_manage_stock(false);
$variation->set_weight(''); // weight
$variation->save(); // Save the data
WC_Product_Variable::sync( $product_id );
}
$product->save(); return; }
Ввод для приведенного выше кода:
create_variant_product( array(
'author' => '', // optional
'title' => $obj->product_name,
'content' => $obj->description,
'excerpt' => $obj->highlight_information,
'regular_price' => $obj->unit_price, // product regular price
'sale_price' => $obj->original_price, // product sale price (optional)
'stock' => 'instock', // Set a minimal stock quantity
'image_id' => '', // optional
'gallery_ids' => array(), // optional
'maincat' => $maincat,
'sku' => '', // optional
'tax_class' => '', // optional
'weight' => '', // optional
'attributes' => $attributeArray,
'variationarray' => $mixedvariations,
'servername' =>$servername,
'serverpassword' =>$serverpassword,
'dbname' =>$dbname,
'serverhost' =>$serverhost,
'Array' =>$Array, ));
Атрибуты добавляются в формате ниже
$attributeArray=array(2) { ["RAM"]=> array(2) { [0]=> string(4) "4 GB" [1]=> string(4) "8 GB" } ["Model"]=> array(2) { [0]=> string(4) "2017" [1]=> string(4) "2019" } }
Варианты добавляются в формате ниже
$mixedvariations=array(4) { [0]=> array(2) { ["ram"]=> string(4) "4 GB" ["model"]=> string(4) "2017" } [1]=> array(2) { ["ram"]=> string(4) "4 GB" ["model"]=> string(4) "2019" } [2]=> array(2) { ["ram"]=> string(4) "8 GB" ["model"]=> string(4) "2017" } [3]=> array(2) { ["ram"]=> string(4) "8 GB" ["model"]=> string(4) "2019" } }
Я приложил изображения для каждого случая. Изображение для продукта, для которого не добавлены вариации и атрибуты - Вид спереди
Изображение Для продукта с добавленным только одним атрибутом (например, RAM) - Вид спереди
Изображение Для продукта с добавленным только одним атрибутом (например, ОЗУ) - вид внутренней панели администратора
Пожалуйста, помогите мне найти проблему в коде. Я новичок в концепциях разработки плагинов и woocommerce. Я добавляю товары в al oop. Для каждого продукта может быть более двух атрибутов с более чем двумя значениями. И для каждого значения я добавляю варианты.
Моя проблема в том, что атрибуты и варианты добавляются неправильно. Все термины и таксономии добавляются в таблицы терминов, terms_taxonomy в базе данных, но не отображаются на странице продукта [как вид спереди, так и вид внутренней панели администратора]. Для некоторых продуктов не добавлены атрибуты и вариации, а для некоторых добавлен только один атрибут.
Пожалуйста, я застрял с этим на неделю, и у меня нет другого выхода, кроме как попросить о помощи. Я разрабатываю код с woocommerce версии 4.0.1 с версией PHP: 5.6.39 и версией wordpress 5.4.2
Заранее спасибо!