我试图创建一个具有属性和术语的可变产品,但它不起作用。
这是我的密码
create_product_variation( array(
'author' => '', // optional
'title' => 'Woo special one',
'content' => '<p>This is the product content <br>A very nice product, soft and clear…<p>',
'excerpt' => 'The product short description…',
'regular_price' => '16', // product regular price
'sale_price' => '', // product sale price (optional)
'stock' => '10', // Set a minimal stock quantity
'image_id' => '', // optional
'gallery_ids' => array(), // optional
'sku' => '', // optional
'tax_class' => '', // optional
'weight' => '', // optional
// For NEW attributes/values use NAMES (not slugs)
'attributes' => array(
'Attribute 1' => array( 'Value 1', 'Value 2' ),
'Attribute 2' => array( 'Value 1', 'Value 2', 'Value 3' ),
),
) );
function save_product_attribute_from_name( $name, $label='', $set=true ){
if( ! function_exists ('get_attribute_id_from_name') ) return;
global $wpdb;
$label = $label == '' ? ucfirst($name) : $label;
$attribute_id = get_attribute_id_from_name( $name );
if( empty($attribute_id) ){
$attribute_id = NULL;
} else {
$set = false;
}
$args = array(
'attribute_id' => $attribute_id,
'attribute_name' => $name,
'attribute_label' => $label,
'attribute_type' => 'select',
'attribute_orderby' => 'menu_order',
'attribute_public' => 0,
);
if( empty($attribute_id) ) {
$wpdb->insert( "{$wpdb->prefix}woocommerce_attribute_taxonomies", $args );
set_transient( 'wc_attribute_taxonomies', false );
}
if( $set ){
$attributes = wc_get_attribute_taxonomies();
$args['attribute_id'] = get_attribute_id_from_name( $name );
$attributes[] = (object) $args;
//print_r($attributes);
set_transient( 'wc_attribute_taxonomies', $attributes );
} else {
return;
}
}
/**
* Get the product attribute ID from the name.
*
* @since 3.0.0
* @param string $name | The name (slug).
*/
function get_attribute_id_from_name( $name ){
global $wpdb;
$attribute_id = $wpdb->get_col("SELECT attribute_id
FROM {$wpdb->prefix}woocommerce_attribute_taxonomies
WHERE attribute_name LIKE '$name'");
return reset($attribute_id);
}
/**
* Create a new variable product (with new attributes if they are).
* (Needed functions:
*
* @since 3.0.0
* @param array $data | The data to insert in the product.
*/
function create_product_variation( $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 );
// 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)
// THE PRICES (No prices yet as we need to create product variations)
// IMAGES GALLERY
if( ! empty( $data['gallery_ids'] ) && count( $data['gallery_ids'] ) > 0 )
$product->set_gallery_image_ids( $data['gallery_ids'] );
// SKU
if( ! empty( $data['sku'] ) )
$product->set_sku( $data['sku'] );
// STOCK (stock will be managed in variations)
$product->set_stock_quantity( $data['stock'] ); // Set a minimal stock quantity
$product->set_manage_stock(true);
$product->set_stock_status('');
// Tax class
if( empty( $data['tax_class'] ) )
$product->set_tax_class( $data['tax_class'] );
// WEIGHT
if( ! empty($data['weight']) )
$product->set_weight(''); // weight (reseting)
else
$product->set_weight($data['weight']);
$product->validate_props(); // Check validation
## ---------------------- VARIATION ATTRIBUTES ---------------------- ##
$product_attributes = array();
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
// NEW Attributes: Register and save them
if( ! taxonomy_exists( $taxonomy ) )
save_product_attribute_from_name( $attr_name, $attr_label );
$product_attributes[$taxonomy] = array (
'name' => $taxonomy,
'value' => '',
'position' => '',
'is_visible' => 0,
'is_variation' => 1,
'is_taxonomy' => 1
);
foreach( $terms as $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_post_terms( $product_id, $term_name, $taxonomy, true );
}
}
update_post_meta( $product_id, '_product_attributes', $product_attributes );
$product->save(); // Save the data
}
这是基于接受答案的答案
我在这里面临两个问题
有什么想法吗
使用wc\u create\u attribute
创建属性,然后显式注册分类法解决了这个问题:
/**
* Create a new global attribute if doesn't exist.
*
* @since 3.2.0
* @param string $name | Name of the attribute.
* @param string $label | Label of the attribute.
*/
function create_global_attribute($name, $label = '') {
$attributes = wc_get_attribute_taxonomies();
$slugs = wp_list_pluck( $attributes, 'attribute_name' );
if ( ! in_array( $name, $slugs ) ) {
$args = array(
'slug' => wc_sanitize_taxonomy_name( $name ),
'name' => ! empty( $label ) ? $label : ucfirst( $name ),
'type' => 'select',
'orderby' => 'menu_order',
'has_archives' => false,
);
$result = wc_create_attribute( $args );
}
}
/**
* Create a new variable product (with new attributes if they are).
*
* @since 3.0.0
* @param array $data | The data to insert in the product.
*/
function create_product_variation( $data ){
if( ! function_exists ( 'create_global_attribute' ) ) return;
$postname = sanitize_title( $data['title'] );
$author = empty( $data['author'] ) ? '1' : $data['author'];
$post_data = [
'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 );
// 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)
// THE PRICES (No prices yet as we need to create product variations)
// IMAGES GALLERY
if( ! empty( $data['gallery_ids'] ) && count( $data['gallery_ids'] ) > 0 )
$product->set_gallery_image_ids( $data['gallery_ids'] );
// SKU
if( ! empty( $data['sku'] ) )
$product->set_sku( $data['sku'] );
// STOCK (stock will be managed in variations)
$product->set_stock_quantity( $data['stock'] ); // Set a minimal stock quantity
$product->set_manage_stock( true );
$product->set_stock_status('');
// Tax class
if( empty( $data['tax_class'] ) )
$product->set_tax_class( $data['tax_class'] );
// WEIGHT
if( ! empty( $data['weight'] ) )
$product->set_weight(''); // weight (reseting)
else
$product->set_weight( $data['weight'] );
$product->validate_props(); // Check validation
## ---------------------- VARIATION ATTRIBUTES ----------------------
##
$product_attributes = array();
foreach( $data['attributes'] as $key => $terms ){
$taxonomy = wc_attribute_taxonomy_name( $key ); // The taxonomy slug
// NEW Attributes: Create if doesn't exist and register taxonomy
if( ! taxonomy_exists( $taxonomy ) ) {
create_global_attribute( $key, $key );
register_taxonomy( $taxonomy, array('product'), array(
'type' => 'select',
'orderby' => 'menu_order',
'public' => 0,
));
}
$product_attributes[$taxonomy] = [
'name' => $taxonomy,
'value' => '',
'position' => '',
'is_visible' => 0,
'is_variation' => 1,
'is_taxonomy' => 1
];
foreach( $terms as $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, ['slug' => $term_slug] ); // Create the term
}
// Set attribute values
wp_set_post_terms( $product_id, $term_name, $taxonomy, true );
}
}
update_post_meta( $product_id, '_product_attributes', $product_attributes );
$product->save(); // Save the data
}
wc\u-get\u-attribute\u-taxonomies
检索上次添加的属性,因为您添加的分类不正确,即您没有将其注册,而是直接插入数据库,因此瞬态wc\u-attribute\u-taxonomies
包含上次添加的属性:
...
if( empty($attribute_id) ) {
/**
* New taxonomy inserts directly here
* without getting registered in $wp_taxonomies
*/
$wpdb->insert( "{$wpdb->prefix}woocommerce_attribute_taxonomies", $args );
set_transient( 'wc_attribute_taxonomies', false );
}
if( $set ){
$attributes = wc_get_attribute_taxonomies();
/**
* Here $attributes containes the last attribute
* because the wc_get_attribute_taxonomies
* fetches the cached value.
* @see https://woocommerce.github.io/code-reference/files/woocommerce-includes-wc-attribute-functions.html#source-view.55
*/
$args['attribute_id'] = get_attribute_id_from_name( $name );
$attributes[] = (object) $args;
set_transient( 'wc_attribute_taxonomies', $attributes );
} else {
return;
}
...
您可以直接从数据库中获取属性,就像WooCommerce在提到的函数中所做的那样,因此代码将是:
...
if( empty($attribute_id) ) {
/**
* New taxonomy inserts directly here
* without getting registered in $wp_taxonomies
*/
$wpdb->insert( "{$wpdb->prefix}woocommerce_attribute_taxonomies", $args );
set_transient( 'wc_attribute_taxonomies', false );
}
if( $set ){
$attributes = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_name != '' ORDER BY attribute_name ASC;" );
$args['attribute_id'] = get_attribute_id_from_name( $name );
$attributes[] = (object) $args;
set_transient( 'wc_attribute_taxonomies', $attributes );
} else {
return;
}
...
当检查此术语的分类法存在时,wp\u insert\u term
返回wp\u错误。即使您在此处插入了新的分类法:
$wpdb->insert( "{$wpdb->prefix}woocommerce_attribute_taxonomies", $args );
正如我之前所说,您可以直接这样做,而无需在$wp\u分类中注册它
,这就是它不添加新术语的原因:
// 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 ) );
/**
* wp_insert_term checks the given $taxonomy exists using taxonomy_exists()
* @see https://github.com/WordPress/WordPress/blob/5.8/wp-includes/taxonomy.php#L2280
* in turn taxonomomy_exists() checks it within $wp_taxonomies
* @see https://github.com/WordPress/WordPress/blob/5.8/wp-includes/taxonomy.php#L309
*/
当我检查你的代码时,我们已经做了一些更改,现在它可以正常工作了。
源代码
add_action( 'admin_init', 'create_custom_product_attribute' );
function create_custom_product_attribute(){
create_product_variation( array(
'author' => '', // optional
'title' => 'Woo special one',
'content' => '<p>This is the product content <br>A very nice product, soft and clear…<p>',
'excerpt' => 'The product short description…',
'regular_price' => '16', // product regular price
'sale_price' => '', // product sale price (optional)
'stock' => '10', // Set a minimal stock quantity
'image_id' => '', // optional
'gallery_ids' => array(), // optional
'sku' => '', // optional
'tax_class' => '', // optional
'weight' => '', // optional
// For NEW attributes/values use NAMES (not slugs)
'attributes' => array(
'Attribute 1' => array( 'Value1', 'Value2' ),
'Attribute 2' => array( 'Value1', 'Value2', 'Value3' ),
),
) );
}
/**
* Create a new variable product (with new attributes if they are).
* (Needed functions:
*
* @since 3.0.0
* @param array $data | The data to insert in the product.
*/
function create_product_variation( $data ){
if( ! function_exists ('add_custom_attribute') ) 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 );
// Get an instance of the WC_Product_Variable object and save it
$product = new WC_Product_Variable( $product_id );
$product->save();
## ---------------------- Other optional data ---------------------- ##
// IMAGES GALLERY
if( ! empty( $data['gallery_ids'] ) && count( $data['gallery_ids'] ) > 0 )
$product->set_gallery_image_ids( $data['gallery_ids'] );
// SKU
if( ! empty( $data['sku'] ) )
$product->set_sku( $data['sku'] );
// STOCK (stock will be managed in variations)
$product->set_stock_quantity( $data['stock'] ); // Set a minimal stock quantity
$product->set_manage_stock(true);
$product->set_stock_status('');
// Tax class
if( empty( $data['tax_class'] ) )
$product->set_tax_class( $data['tax_class'] );
// WEIGHT
if( ! empty($data['weight']) )
$product->set_weight(''); // weight (reseting)
else
$product->set_weight($data['weight']);
$product->validate_props(); // Check validation
## ---------------------- VARIATION ATTRIBUTES ---------------------- ##
$product_attributes = array();
foreach( $data['attributes'] as $key => $terms ){
$attr_name = ucfirst($key);
$attr_slug = sanitize_title($key);
$taxonomy = wc_attribute_taxonomy_name(wp_unslash($key));
// NEW Attributes: Register and save them
if (taxonomy_exists($taxonomy))
{
$attribute_id = wc_attribute_taxonomy_id_by_name($attr_slug);
}else{
$attribute_id = add_custom_attribute($attr_name);
}
$product_attributes[$taxonomy] = array (
'name' => $taxonomy,
'value' => '',
'position' => '',
'is_visible' => 0,
'is_variation' => 1,
'is_taxonomy' => 1
);
if($attribute_id){
// Iterating through the variations attributes
foreach ($terms as $term_name )
{
$taxonomy = 'pa_'.$attr_slug; // 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' => $attr_name,
'query_var' => true,
'rewrite' => array( 'slug' => $attr_slug), // 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 the attribute data in the product variation
//update_post_meta($variation_id, 'attribute_'.$taxonomy, $term_slug );
}
}
}
update_post_meta( $product_id, '_product_attributes', $product_attributes );
$product->save(); // Save the data
}
/*
* Register a global woocommerce product add attribute Class.
*
* @param str $nam | name of attribute
* @param arr $vals | array of variations
*
*/
function add_custom_attribute($nam){
$attrs = array();
$attributes = wc_get_attribute_taxonomies();
$slug = sanitize_title($nam);
foreach ($attributes as $key => $value) {
array_push($attrs,$attributes[$key]->attribute_name);
}
if (!in_array( $nam, $attrs ) ) {
$args = array(
'slug' => $slug,
'name' => __( $nam, 'woocommerce' ),
'type' => 'select',
'orderby' => 'menu_order',
'has_archives' => false,
);
return wc_create_attribute($args);
}
}
现在您可以相应地更改add_操作和属性值。
我想以编程方式创建一个带有两个新变量属性的变量产品(“父”产品)——所有这些都来自WordPress插件(因此没有对API的HTTP请求)。 这两个变量属性也应该动态创建。 这怎么能做到呢? (适用于WooCommerce第3版) 更新:我已经写了更多我希望的代码,并尝试了很多方法来解决它,使用wooCommerce对象,并使用WordPress数据库对象在数据库中添加了关于术语、termmeta
问题内容: 我想以编程方式创建具有两个新的Variant属性的变量产品(“父”产品)-所有这些都来自WordPress插件(因此,无需向API发送HTTP请求)。 这两个变量属性也应该动态创建。 如何才能做到这一点 ? (使用WooCommerce版本3) 更新:我已经在此上编写了更多行代码,并使用wooCommerce对象尝试了许多解决方案,并使用WordPress数据库在数据库中添加了有关术语
在WooCommerce中,我想用我自己的定制设计展示可变产品,作为产品变化的旋转木马。我得到了代码,通过它我可以在数组中显示产品的常规价格,但我坚持在其中获取属性名和值。 基于“WooCommerce变量产品:在超文本标记语言表中显示一些变化值”的回答代码,这是我的实际代码: 这段代码给出了正确的输出,但我需要属性值和名称,这是输出屏幕截图:
我目前正在努力设置产品变化作为压缩产品目录的一种手段...我们目前有几千个单独的产品页面和变化,我正在寻找一种方法来压缩每个产品类型到一个单一的变化。销售的产品与车辆相关,因此适合每个车型的年份范围: WooCommerce的罐装可变产品为每种属性组合创造了新的变化。例如,“Body Style A”将创建两个相同的变体,我更希望有一个变体,在“年份”是2002年或2003年,而不是只指定一个值。
第一件事:这是我在stackoverflow上发布的第一个问题。换句话说,这是我在你们的帮助下无法独自解决的第一个问题(非常感谢你们,你们让世界运转起来!)。 我的问题与@LoictheAztec对另一个问题的回答有关(我原本计划在那篇文章的评论中发布我的问题,但由于我是/曾经是潜伏者,我缺乏这样做的声誉):https://stackoverflow.com/a/47766413/13263330
我试图以编程方式为一个可变产品添加两个产品变体。基于此回答线程,我使用以下缩短的函数: 我使用以下数据数组: 然后我运行以下函数: 其中,是我要对其进行更改的变量产品的id,是上面定义的数据数组。 我的问题是函数只插入foreach in函数中的最后一个数据。 i、 e.在商业中的产品变化有: 红色W1 红色W1 但我想: 蓝色W1 红色W1