以编程方式创建具有新属性值的 WooCommerce 产品变体
Create programmatically a WooCommerce product variation with new attribute values
我在 WooCommerce 版本 3+ 中创建了一个变量产品("parent" 产品)。从 WordPress 插件,我想以编程方式创建具有新属性值的产品变体("children" 产品)。
变体属性已在 WooCommerce 中设置。
因此,每次创建一个变体时,新属性的值也应以编程方式创建并在父变量产品中设置。
如何做到这一点?可能吗?
更新:我已经写了更多我希望的代码行,并尝试了很多方法来解决它,使用 woocommerce 对象,并添加了关于术语、termmeta、与术语的关系的缺失数据使用 post,在数据库中使用 WordPress 数据库对象 - 但没有任何东西足以使其工作。而且我无法指出我哪里出错了——这就是为什么我不能提供一个更窄的问题——Whosebug 更适合的东西。
Update January 2020: Changed to WC_Product
method get_name()
instead of get_title()
Update September 2018: Handling taxonomy creation (Thanks to Carl F. Corneil)
从定义的变量产品 ID 您将在下面找到一个自定义函数,该函数将添加(创建)产品变体。可变父产品需要为其设置所需的属性。
您需要提供一些信息:
- attributes/values
的数组
- Sku、价格和库存……
此数据必须存储在格式化的多维数组中(见最后的示例)。
此函数将检查属性值(术语名称)是否已经存在,如果不存在:
- 它为产品属性创建它
- 在父变量产品中设置它。
自定义函数代码:
/**
* Create a product variation for a defined variable product ID.
*
* @since 3.0.0
* @param int $product_id | Post ID of the product parent variable product.
* @param array $variation_data | The data to insert in the product.
*/
function create_product_variation( $product_id, $variation_data ){
// Get the Variable product object (parent)
$product = wc_get_product($product_id);
$variation_post = array(
'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 ($variation_data['attributes'] 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 );
// Set/save the attribute data in the product variation
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
}
## Set/save all other data
// SKU
if( ! empty( $variation_data['sku'] ) )
$variation->set_sku( $variation_data['sku'] );
// Prices
if( empty( $variation_data['sale_price'] ) ){
$variation->set_price( $variation_data['regular_price'] );
} else {
$variation->set_price( $variation_data['sale_price'] );
$variation->set_sale_price( $variation_data['sale_price'] );
}
$variation->set_regular_price( $variation_data['regular_price'] );
// Stock
if( ! empty($variation_data['stock_qty']) ){
$variation->set_stock_quantity( $variation_data['stock_qty'] );
$variation->set_manage_stock(true);
$variation->set_stock_status('');
} else {
$variation->set_manage_stock(false);
}
$variation->set_weight(''); // weight (reseting)
$variation->save(); // Save the data
}
代码进入您的活动子主题(或主题)的 function.php 文件或任何插件文件。
用法(具有 2 个属性的示例):
$parent_id = 746; // Or get the variable product id dynamically
// The variation data
$variation_data = array(
'attributes' => array(
'size' => 'M',
'color' => 'Green',
),
'sku' => '',
'regular_price' => '22.00',
'sale_price' => '',
'stock_qty' => 10,
);
// The function to be run
create_product_variation( $parent_id, $variation_data );
已测试并有效。
Part 2:
你会在后端得到这个:
而且它会在前端完美运行。
Related:
扩展 LoicTheAztec 的答案,您可以通过对他的代码进行以下修改来检查属性组合是否存在。
function create_update_product_variation( $product_id, $variation_data ){
if(isset($variation_data['variation_id'])) {
$variation_id = $variation_data['variation_id'];
} else {
// if the variation doesn't exist then create it
// Get the Variable product object (parent)
$product = wc_get_product($product_id);
$variation_post = array(
'post_title' => $product->get_title(),
'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 );
}
// ...
}
用法示例
// The variation data
$variation_data = array(
'attributes' => array(
'size' => 'M',
'color' => 'Green',
),
'sku' => '',
'regular_price' => '22.00',
'sale_price' => '1',
'stock_qty' => 1,
);
// check if variation exists
$meta_query = array();
foreach ($variation_data['attributes'] as $key => $value) {
$meta_query[] = array(
'key' => 'attribute_pa_' . $key,
'value' => $value
);
}
$variation_post = get_posts(array(
'post_type' => 'product_variation',
'numberposts' => 1,
'post_parent' => $parent_id,
'meta_query' => $meta_query
));
if($variation_post) {
$variation_data['variation_id'] = $variation_post[0]->ID;
}
create_update_product_variation( $product_id, $variation_data );
如果产品的分类没有事先在其他地方注册,您可能 运行 会在这里遇到问题。如果您想确保分类法存在,您可以在 LoicTheAztec 的答案中添加一个条件。
像这样。
foreach ($variation_data['attributes'] as $attribute => $term_name )
{
//echo 'attribute ' . $attribute . ' term name ' . $term_name;
$taxonomy = 'pa_' . $attribute; // The attribute taxonomy
// Check if the Taxonomy exists, and if not we create it.
if (! taxonomy_exists($taxonomy)){
register_taxonomy(
$taxonomy, //The name of the taxonomy. Name should be in slug form (must not contain capital letters or spaces).
'product', //post type name
array(
'hierarchical' => false,
'label' => ucfirst($taxonomy), //Display name
'query_var' => true,
'rewrite' => array(
'slug' => $taxonomy, // This controls the base slug that will display before each term
'with_front' => false // Don't display the category base before
),
)
);
}
...
我只是想把它扔在那里,因为我无法使上述任何示例正常工作。不要问我为什么其他人似乎都成功了。因此,我采用了极简主义的方法并试图找出产品属性 + 变体的基本要素(通过在 wp 中手动创建它并查看数据库)并想出了这个。
$article_name = 'Test';
$post_id = wp_insert_post( array(
'post_author' => 1,
'post_title' => $article_name,
'post_content' => 'Lorem ipsum',
'post_status' => 'publish',
'post_type' => "product",
) );
wp_set_object_terms( $post_id, 'variable', 'product_type' );
$attr_label = 'Test attribute';
$attr_slug = sanitize_title($attr_label);
$attributes_array[$attr_slug] = array(
'name' => $attr_label,
'value' => 'alternative 1 | alternative 2',
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '0' // for some reason, this is really important
);
update_post_meta( $post_id, '_product_attributes', $attributes_array );
$parent_id = $post_id;
$variation = array(
'post_title' => $article_name . ' (variation)',
'post_content' => '',
'post_status' => 'publish',
'post_parent' => $parent_id,
'post_type' => 'product_variation'
);
$variation_id = wp_insert_post( $variation );
update_post_meta( $variation_id, '_regular_price', 2 );
update_post_meta( $variation_id, '_price', 2 );
update_post_meta( $variation_id, '_stock_qty', 10 );
update_post_meta( $variation_id, 'attribute_' . $attr_slug, 'alternative 1' );
WC_Product_Variable::sync( $parent_id );
$variation_id = wp_insert_post( $variation );
update_post_meta( $variation_id, '_regular_price', 2 );
update_post_meta( $variation_id, '_price', 2 );
update_post_meta( $variation_id, '_stock_qty', 10 );
update_post_meta( $variation_id, 'attribute_' . $attr_slug, 'alternative 2' );
WC_Product_Variable::sync( $parent_id );
这不是使用全局产品属性,而是使用特定于文章的属性。希望它对某人有所帮助,因为我正准备在开始工作之前撕掉我的头发。
编辑:我会说只有在官方方法无法正常工作时才使用它。他们会随着时间改变这些东西(字段名称,如“_regular_price”等),而且这样做可能不是超级未来的证明。
如果您想在 WooCommerce 中生成用于测试的产品,您可以使用由 WooCommerce 自己制作的 WooCommerce Smooth Generator。
https://github.com/woocommerce/wc-smooth-generator
示例:
// Generate WC_Product object and save it to database
// 70% change generated product is simple
// 30% chance generated product is variable
$product = \WC\SmoothGenerator\Generator\Product::generate();
// Returns WC_Product object of Simple product and don't save it to database
$product = \WC\SmoothGenerator\Generator\Product::generate_simple_product();
// Returns WC_Product object of Variable Product and saves it to database
$variable_product = \WC\SmoothGenerator\Generator\Product::generate_variable_product();
来源:https://github.com/woocommerce/wc-smooth-generator/blob/master/includes/Generator/Product.php
如果您想以编程方式创建产品,您可以根据需要制作产品 class。
它可以工作,但需要一些修正(函数数组中有 2 个逗号),我确实根据需要编辑了一些代码。
(正在处理 wp 4.9 | wc 3.5)
首先,产品需要具有已经创建和关联的属性,我的分类法是 "pa_r" 友好名称 "R"
backend attribute associeated img
修正后的函数
function create_product_variation( $product_id, $variation_data ){
// Get the Variable product object (parent)
$product = wc_get_product($product_id);
$variation_post = array(
'post_title' => $product->get_title(),
'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 ($variation_data['attributes'] 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( $taxonomy ),
'query_var' => true,
'rewrite' => array( 'slug' => '$taxonomy') // 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 );
// Set/save the attribute data in the product variation
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
}
## Set/save all other data
// SKU
if( ! empty( $variation_data['sku'] ) )
$variation->set_sku( $variation_data['sku'] );
// Prices
if( empty( $variation_data['sale_price'] ) ){
$variation->set_price( $variation_data['regular_price'] );
} else {
$variation->set_price( $variation_data['sale_price'] );
$variation->set_sale_price( $variation_data['sale_price'] );
}
$variation->set_regular_price( $variation_data['regular_price'] );
// Stock
if( ! empty($variation_data['stock_qty']) ){
$variation->set_stock_quantity( $variation_data['stock_qty'] );
$variation->set_manage_stock(true);
$variation->set_stock_status('');
} else {
$variation->set_manage_stock(false);
}
$variation->set_weight(''); // weight (reseting)
$variation->save(); // Save the data
}
我用变体 [id_post、属性、sku、regular_price、库存]
中需要的数据创建了一个数组
$hijos = array(
[9623,'265/70 R16','NE-CT-CO-USA-016-005','0',53],
[9624,'235/65 R17','NE-AU-CO-EUR-017-050','189000',56]
);
和 foreach 为我的产品动态创建所有变体
foreach ($hijos as $vari) {
// The variation data
$variation_data = array(
'attributes' => array(
'r' => $vari[1],
),
'sku' => $vari[2],
'regular_price' => str_replace('.', '', $vari[3]),
'stock_qty' => $vari[4]
);
// var_dump($variation_data);
create_product_variation( $vari[0], $variation_data );
}
以上答案 (LoicTheAztec) 对我帮助很大,但有一些问题而不是使用
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
使用:
update_post_meta( $variation_id, 'attribute_'.$attribute, $term_name );
因为分类法已经被修改,这导致在更改此更新值后更新 post 元时出现问题,并且在此更改后未在管理产品变体编辑中自动选择它工作得很好!
不知道为什么,但是 none 这些解决方案对我有用,所以我决定创建自己的解决方案:
<?php
/**
* Create a variable product on woocommerce
* @return int Product ID
*/
function pricode_create_product(){
$product = new WC_Product_Variable();
$product->set_description('T-shirt variable description');
$product->set_name('T-shirt variable');
$product->set_sku('test-shirt');
$product->set_price(1);
$product->set_regular_price(1);
$product->set_stock_status();
return $product->save();
}
/**
* Create Product Attributes
* @param string $name Attribute name
* @param array $options Options values
* @return Object WC_Product_Attribute
*/
function pricode_create_attributes( $name, $options ){
$attribute = new WC_Product_Attribute();
$attribute->set_id(0);
$attribute->set_name($name);
$attribute->set_options($options);
$attribute->set_visible(true);
$attribute->set_variation(true);
return $attribute;
}
/**
* [pricode_create_variations description]
* @param [type] $product_id [description]
* @param [type] $values [description]
* @return [type] [description]
*/
function pricode_create_variations( $product_id, $values, $data ){
$variation = new WC_Product_Variation();
$variation->set_parent_id( $product_id );
$variation->set_attributes($values);
$variation->set_status('publish');
$variation->set_sku($data->sku);
$variation->set_price($data->price);
$variation->set_regular_price($data->price);
$variation->set_stock_status();
$variation->save();
$product = wc_get_product($product_id);
$product->save();
}
//Adding product
$product = pricode_create_product();
//Creating Attributes
$atts = [];
$atts[] = pricode_create_attributes('color',['red', 'green']);
$atts[] = pricode_create_attributes('size',['S', 'M']);
//Adding attributes to the created product
$product->set_attributes( $atts );
$product->save();
//Setting data (following Alexander's rec
$data = new stdClass();
$data->sku = 'sku-123';
$data->price = '10';
//Create variations
pricode_create_variations( $product->get_id(), ['color' => 'red', 'size' => 'M'], $data );
希望对大家有帮助。
除了 使用分类而不是自定义产品属性之外,您还可以使用此修改后的版本
<?php
/**
* Create a variable product on woocommerce
* @return int Product ID
*/
function pricode_create_product(){
$product = new WC_Product_Variable();
$product->set_description('T-shirt variable description');
$product->set_name('T-shirt variable');
$product->set_sku('test-shirt');
$product->set_price(1);
$product->set_regular_price(1);
$product->set_stock_status();
return $product->save();
}
/**
* Create Product Attributes
* @param string $name Attribute name
* @param array $options Options values
* @return Object WC_Product_Attribute
*/
function pricode_create_attributes( $name, $options ){
$attributes = array();
if(!empty($options)){
if(is_string($options)){
$term = wp_create_term(
$options,
wc_attribute_taxonomy_name($name)
);
if(is_array($term)){
$attributes[] = (int)$term['term_id'];
}
}
else{
for($i = 0; $i < count($options); $i++){
$term = wp_create_term(
$options[$i],
wc_attribute_taxonomy_name($name)
);
if(is_array($term)){
$attributes[] = (int)$term['term_id'];
}
}
}
}
$attribute = new WC_Product_Attribute();
/*
Set the attribute id to the id of the taxonomy to use
with wc_attribute_taxonomy_id_by_name you get the id of the taxonomy stored in {$wpdb->prefix}woocommerce_attribute_taxonomies
with wc_attribute_taxonomy_name you convert the Attribute name to the attribute name woocommerce use
@see https://woocommerce.github.io/code-reference/namespaces/default.html#function_wc_attribute_taxonomy_id_by_name
@see https://woocommerce.github.io/code-reference/namespaces/default.html#function_wc_attribute_taxonomy_name
/*
$attribute->set_id(wc_attribute_taxonomy_id_by_name(wc_attribute_taxonomy_name($name)));
$attribute->set_name(wc_attribute_taxonomy_name($name));
$attribute->set_options($attributes);
$attribute->set_visible(true);
$attribute->set_variation(true);
return $attribute;
}
/**
* [pricode_create_variations description]
* @param [type] $product_id [description]
* @param [type] $values [description]
* @return [type] [description]
*/
function pricode_create_variations( $product_id, $values ){
$variation = new WC_Product_Variation();
$variation->set_parent_id( $product_id );
$variation->set_attributes($values);
$variation->set_status('publish');
$variation->set_sku($data->sku);
$variation->set_price($data->price);
$variation->set_regular_price($data->price);
$variation->set_stock_status();
$variation->save();
$product = wc_get_product($product_id);
$product->save();
}
//Adding product
$product = pricode_create_product();
//Creating Attributes
$atts = [];
$atts[] = pricode_create_attributes('color',['red', 'green']);
$atts[] = pricode_create_attributes('size',['S', 'M']);
//Adding attributes to the created product
$product->set_attributes( $atts );
$product->save();
//Create variations
pricode_create_variations( $product->get_id(), [wc_attribute_taxonomy_name('color') => sanitize_title('red'), wc_attribute_taxonomy_name('size') => sanitize_title('M')]);
晚会来晚了,但添加到 LoicTheAztec 的答案(效果很好)如果您的新变体没有以选定的属性结束,请在保存方法之前使用以下行:
$variation->set_weight(''); //LoicTheAztec
$variation->set_attributes($variation_data["attributes"]); // Select the attributes
$variation->save(); //LoicTheAztec
被接受的文章很有魅力。如果您设法创建变体,但它没有在变体中选择任何选项,并且当您尝试保存一个重置为空时,我强烈建议检查这个线程 ,我一直在努力解决同样的问题问题超过2小时。快乐编码
我在 WooCommerce 版本 3+ 中创建了一个变量产品("parent" 产品)。从 WordPress 插件,我想以编程方式创建具有新属性值的产品变体("children" 产品)。
变体属性已在 WooCommerce 中设置。
因此,每次创建一个变体时,新属性的值也应以编程方式创建并在父变量产品中设置。
如何做到这一点?可能吗?
更新:我已经写了更多我希望的代码行,并尝试了很多方法来解决它,使用 woocommerce 对象,并添加了关于术语、termmeta、与术语的关系的缺失数据使用 post,在数据库中使用 WordPress 数据库对象 - 但没有任何东西足以使其工作。而且我无法指出我哪里出错了——这就是为什么我不能提供一个更窄的问题——Whosebug 更适合的东西。
Update January 2020: Changed to
WC_Product
methodget_name()
instead ofget_title()
Update September 2018: Handling taxonomy creation (Thanks to Carl F. Corneil)
从定义的变量产品 ID 您将在下面找到一个自定义函数,该函数将添加(创建)产品变体。可变父产品需要为其设置所需的属性。
您需要提供一些信息:
- attributes/values 的数组
- Sku、价格和库存……
此数据必须存储在格式化的多维数组中(见最后的示例)。
此函数将检查属性值(术语名称)是否已经存在,如果不存在:
- 它为产品属性创建它
- 在父变量产品中设置它。
自定义函数代码:
/**
* Create a product variation for a defined variable product ID.
*
* @since 3.0.0
* @param int $product_id | Post ID of the product parent variable product.
* @param array $variation_data | The data to insert in the product.
*/
function create_product_variation( $product_id, $variation_data ){
// Get the Variable product object (parent)
$product = wc_get_product($product_id);
$variation_post = array(
'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 ($variation_data['attributes'] 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 );
// Set/save the attribute data in the product variation
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
}
## Set/save all other data
// SKU
if( ! empty( $variation_data['sku'] ) )
$variation->set_sku( $variation_data['sku'] );
// Prices
if( empty( $variation_data['sale_price'] ) ){
$variation->set_price( $variation_data['regular_price'] );
} else {
$variation->set_price( $variation_data['sale_price'] );
$variation->set_sale_price( $variation_data['sale_price'] );
}
$variation->set_regular_price( $variation_data['regular_price'] );
// Stock
if( ! empty($variation_data['stock_qty']) ){
$variation->set_stock_quantity( $variation_data['stock_qty'] );
$variation->set_manage_stock(true);
$variation->set_stock_status('');
} else {
$variation->set_manage_stock(false);
}
$variation->set_weight(''); // weight (reseting)
$variation->save(); // Save the data
}
代码进入您的活动子主题(或主题)的 function.php 文件或任何插件文件。
用法(具有 2 个属性的示例):
$parent_id = 746; // Or get the variable product id dynamically
// The variation data
$variation_data = array(
'attributes' => array(
'size' => 'M',
'color' => 'Green',
),
'sku' => '',
'regular_price' => '22.00',
'sale_price' => '',
'stock_qty' => 10,
);
// The function to be run
create_product_variation( $parent_id, $variation_data );
已测试并有效。
Part 2:
你会在后端得到这个:
而且它会在前端完美运行。
Related:
扩展 LoicTheAztec 的答案,您可以通过对他的代码进行以下修改来检查属性组合是否存在。
function create_update_product_variation( $product_id, $variation_data ){
if(isset($variation_data['variation_id'])) {
$variation_id = $variation_data['variation_id'];
} else {
// if the variation doesn't exist then create it
// Get the Variable product object (parent)
$product = wc_get_product($product_id);
$variation_post = array(
'post_title' => $product->get_title(),
'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 );
}
// ...
}
用法示例
// The variation data
$variation_data = array(
'attributes' => array(
'size' => 'M',
'color' => 'Green',
),
'sku' => '',
'regular_price' => '22.00',
'sale_price' => '1',
'stock_qty' => 1,
);
// check if variation exists
$meta_query = array();
foreach ($variation_data['attributes'] as $key => $value) {
$meta_query[] = array(
'key' => 'attribute_pa_' . $key,
'value' => $value
);
}
$variation_post = get_posts(array(
'post_type' => 'product_variation',
'numberposts' => 1,
'post_parent' => $parent_id,
'meta_query' => $meta_query
));
if($variation_post) {
$variation_data['variation_id'] = $variation_post[0]->ID;
}
create_update_product_variation( $product_id, $variation_data );
如果产品的分类没有事先在其他地方注册,您可能 运行 会在这里遇到问题。如果您想确保分类法存在,您可以在 LoicTheAztec 的答案中添加一个条件。
像这样。
foreach ($variation_data['attributes'] as $attribute => $term_name )
{
//echo 'attribute ' . $attribute . ' term name ' . $term_name;
$taxonomy = 'pa_' . $attribute; // The attribute taxonomy
// Check if the Taxonomy exists, and if not we create it.
if (! taxonomy_exists($taxonomy)){
register_taxonomy(
$taxonomy, //The name of the taxonomy. Name should be in slug form (must not contain capital letters or spaces).
'product', //post type name
array(
'hierarchical' => false,
'label' => ucfirst($taxonomy), //Display name
'query_var' => true,
'rewrite' => array(
'slug' => $taxonomy, // This controls the base slug that will display before each term
'with_front' => false // Don't display the category base before
),
)
);
}
...
我只是想把它扔在那里,因为我无法使上述任何示例正常工作。不要问我为什么其他人似乎都成功了。因此,我采用了极简主义的方法并试图找出产品属性 + 变体的基本要素(通过在 wp 中手动创建它并查看数据库)并想出了这个。
$article_name = 'Test';
$post_id = wp_insert_post( array(
'post_author' => 1,
'post_title' => $article_name,
'post_content' => 'Lorem ipsum',
'post_status' => 'publish',
'post_type' => "product",
) );
wp_set_object_terms( $post_id, 'variable', 'product_type' );
$attr_label = 'Test attribute';
$attr_slug = sanitize_title($attr_label);
$attributes_array[$attr_slug] = array(
'name' => $attr_label,
'value' => 'alternative 1 | alternative 2',
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '0' // for some reason, this is really important
);
update_post_meta( $post_id, '_product_attributes', $attributes_array );
$parent_id = $post_id;
$variation = array(
'post_title' => $article_name . ' (variation)',
'post_content' => '',
'post_status' => 'publish',
'post_parent' => $parent_id,
'post_type' => 'product_variation'
);
$variation_id = wp_insert_post( $variation );
update_post_meta( $variation_id, '_regular_price', 2 );
update_post_meta( $variation_id, '_price', 2 );
update_post_meta( $variation_id, '_stock_qty', 10 );
update_post_meta( $variation_id, 'attribute_' . $attr_slug, 'alternative 1' );
WC_Product_Variable::sync( $parent_id );
$variation_id = wp_insert_post( $variation );
update_post_meta( $variation_id, '_regular_price', 2 );
update_post_meta( $variation_id, '_price', 2 );
update_post_meta( $variation_id, '_stock_qty', 10 );
update_post_meta( $variation_id, 'attribute_' . $attr_slug, 'alternative 2' );
WC_Product_Variable::sync( $parent_id );
这不是使用全局产品属性,而是使用特定于文章的属性。希望它对某人有所帮助,因为我正准备在开始工作之前撕掉我的头发。
编辑:我会说只有在官方方法无法正常工作时才使用它。他们会随着时间改变这些东西(字段名称,如“_regular_price”等),而且这样做可能不是超级未来的证明。
如果您想在 WooCommerce 中生成用于测试的产品,您可以使用由 WooCommerce 自己制作的 WooCommerce Smooth Generator。
https://github.com/woocommerce/wc-smooth-generator
示例:
// Generate WC_Product object and save it to database
// 70% change generated product is simple
// 30% chance generated product is variable
$product = \WC\SmoothGenerator\Generator\Product::generate();
// Returns WC_Product object of Simple product and don't save it to database
$product = \WC\SmoothGenerator\Generator\Product::generate_simple_product();
// Returns WC_Product object of Variable Product and saves it to database
$variable_product = \WC\SmoothGenerator\Generator\Product::generate_variable_product();
来源:https://github.com/woocommerce/wc-smooth-generator/blob/master/includes/Generator/Product.php
如果您想以编程方式创建产品,您可以根据需要制作产品 class。
它可以工作,但需要一些修正(函数数组中有 2 个逗号),我确实根据需要编辑了一些代码。
(正在处理 wp 4.9 | wc 3.5)
首先,产品需要具有已经创建和关联的属性,我的分类法是 "pa_r" 友好名称 "R" backend attribute associeated img
修正后的函数
function create_product_variation( $product_id, $variation_data ){
// Get the Variable product object (parent)
$product = wc_get_product($product_id);
$variation_post = array(
'post_title' => $product->get_title(),
'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 ($variation_data['attributes'] 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( $taxonomy ),
'query_var' => true,
'rewrite' => array( 'slug' => '$taxonomy') // 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 );
// Set/save the attribute data in the product variation
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
}
## Set/save all other data
// SKU
if( ! empty( $variation_data['sku'] ) )
$variation->set_sku( $variation_data['sku'] );
// Prices
if( empty( $variation_data['sale_price'] ) ){
$variation->set_price( $variation_data['regular_price'] );
} else {
$variation->set_price( $variation_data['sale_price'] );
$variation->set_sale_price( $variation_data['sale_price'] );
}
$variation->set_regular_price( $variation_data['regular_price'] );
// Stock
if( ! empty($variation_data['stock_qty']) ){
$variation->set_stock_quantity( $variation_data['stock_qty'] );
$variation->set_manage_stock(true);
$variation->set_stock_status('');
} else {
$variation->set_manage_stock(false);
}
$variation->set_weight(''); // weight (reseting)
$variation->save(); // Save the data
}
我用变体 [id_post、属性、sku、regular_price、库存]
中需要的数据创建了一个数组$hijos = array(
[9623,'265/70 R16','NE-CT-CO-USA-016-005','0',53],
[9624,'235/65 R17','NE-AU-CO-EUR-017-050','189000',56]
);
和 foreach 为我的产品动态创建所有变体
foreach ($hijos as $vari) {
// The variation data
$variation_data = array(
'attributes' => array(
'r' => $vari[1],
),
'sku' => $vari[2],
'regular_price' => str_replace('.', '', $vari[3]),
'stock_qty' => $vari[4]
);
// var_dump($variation_data);
create_product_variation( $vari[0], $variation_data );
}
以上答案 (LoicTheAztec) 对我帮助很大,但有一些问题而不是使用
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
使用:
update_post_meta( $variation_id, 'attribute_'.$attribute, $term_name );
因为分类法已经被修改,这导致在更改此更新值后更新 post 元时出现问题,并且在此更改后未在管理产品变体编辑中自动选择它工作得很好!
不知道为什么,但是 none 这些解决方案对我有用,所以我决定创建自己的解决方案:
<?php
/**
* Create a variable product on woocommerce
* @return int Product ID
*/
function pricode_create_product(){
$product = new WC_Product_Variable();
$product->set_description('T-shirt variable description');
$product->set_name('T-shirt variable');
$product->set_sku('test-shirt');
$product->set_price(1);
$product->set_regular_price(1);
$product->set_stock_status();
return $product->save();
}
/**
* Create Product Attributes
* @param string $name Attribute name
* @param array $options Options values
* @return Object WC_Product_Attribute
*/
function pricode_create_attributes( $name, $options ){
$attribute = new WC_Product_Attribute();
$attribute->set_id(0);
$attribute->set_name($name);
$attribute->set_options($options);
$attribute->set_visible(true);
$attribute->set_variation(true);
return $attribute;
}
/**
* [pricode_create_variations description]
* @param [type] $product_id [description]
* @param [type] $values [description]
* @return [type] [description]
*/
function pricode_create_variations( $product_id, $values, $data ){
$variation = new WC_Product_Variation();
$variation->set_parent_id( $product_id );
$variation->set_attributes($values);
$variation->set_status('publish');
$variation->set_sku($data->sku);
$variation->set_price($data->price);
$variation->set_regular_price($data->price);
$variation->set_stock_status();
$variation->save();
$product = wc_get_product($product_id);
$product->save();
}
//Adding product
$product = pricode_create_product();
//Creating Attributes
$atts = [];
$atts[] = pricode_create_attributes('color',['red', 'green']);
$atts[] = pricode_create_attributes('size',['S', 'M']);
//Adding attributes to the created product
$product->set_attributes( $atts );
$product->save();
//Setting data (following Alexander's rec
$data = new stdClass();
$data->sku = 'sku-123';
$data->price = '10';
//Create variations
pricode_create_variations( $product->get_id(), ['color' => 'red', 'size' => 'M'], $data );
希望对大家有帮助。
除了
<?php
/**
* Create a variable product on woocommerce
* @return int Product ID
*/
function pricode_create_product(){
$product = new WC_Product_Variable();
$product->set_description('T-shirt variable description');
$product->set_name('T-shirt variable');
$product->set_sku('test-shirt');
$product->set_price(1);
$product->set_regular_price(1);
$product->set_stock_status();
return $product->save();
}
/**
* Create Product Attributes
* @param string $name Attribute name
* @param array $options Options values
* @return Object WC_Product_Attribute
*/
function pricode_create_attributes( $name, $options ){
$attributes = array();
if(!empty($options)){
if(is_string($options)){
$term = wp_create_term(
$options,
wc_attribute_taxonomy_name($name)
);
if(is_array($term)){
$attributes[] = (int)$term['term_id'];
}
}
else{
for($i = 0; $i < count($options); $i++){
$term = wp_create_term(
$options[$i],
wc_attribute_taxonomy_name($name)
);
if(is_array($term)){
$attributes[] = (int)$term['term_id'];
}
}
}
}
$attribute = new WC_Product_Attribute();
/*
Set the attribute id to the id of the taxonomy to use
with wc_attribute_taxonomy_id_by_name you get the id of the taxonomy stored in {$wpdb->prefix}woocommerce_attribute_taxonomies
with wc_attribute_taxonomy_name you convert the Attribute name to the attribute name woocommerce use
@see https://woocommerce.github.io/code-reference/namespaces/default.html#function_wc_attribute_taxonomy_id_by_name
@see https://woocommerce.github.io/code-reference/namespaces/default.html#function_wc_attribute_taxonomy_name
/*
$attribute->set_id(wc_attribute_taxonomy_id_by_name(wc_attribute_taxonomy_name($name)));
$attribute->set_name(wc_attribute_taxonomy_name($name));
$attribute->set_options($attributes);
$attribute->set_visible(true);
$attribute->set_variation(true);
return $attribute;
}
/**
* [pricode_create_variations description]
* @param [type] $product_id [description]
* @param [type] $values [description]
* @return [type] [description]
*/
function pricode_create_variations( $product_id, $values ){
$variation = new WC_Product_Variation();
$variation->set_parent_id( $product_id );
$variation->set_attributes($values);
$variation->set_status('publish');
$variation->set_sku($data->sku);
$variation->set_price($data->price);
$variation->set_regular_price($data->price);
$variation->set_stock_status();
$variation->save();
$product = wc_get_product($product_id);
$product->save();
}
//Adding product
$product = pricode_create_product();
//Creating Attributes
$atts = [];
$atts[] = pricode_create_attributes('color',['red', 'green']);
$atts[] = pricode_create_attributes('size',['S', 'M']);
//Adding attributes to the created product
$product->set_attributes( $atts );
$product->save();
//Create variations
pricode_create_variations( $product->get_id(), [wc_attribute_taxonomy_name('color') => sanitize_title('red'), wc_attribute_taxonomy_name('size') => sanitize_title('M')]);
晚会来晚了,但添加到 LoicTheAztec 的答案(效果很好)如果您的新变体没有以选定的属性结束,请在保存方法之前使用以下行:
$variation->set_weight(''); //LoicTheAztec
$variation->set_attributes($variation_data["attributes"]); // Select the attributes
$variation->save(); //LoicTheAztec
被接受的文章很有魅力。如果您设法创建变体,但它没有在变体中选择任何选项,并且当您尝试保存一个重置为空时,我强烈建议检查这个线程