以编程方式创建具有新属性值的 WooCommerce 产品变体

我在WooCommerce版本3 +中创建了一个可变产品(“父”产品)。从WordPress插件中,我想以编程方式创建具有新属性值的产品变体(“儿童”产品)。

变体属性已经在WooCommerce中设置。
因此,每次创建一个变体时,新属性的值也应以编程方式创建,并在父变量产品中进行设置。

如何做到这一点?可能吗?


更新 :我已经为此编写了更多我希望的代码行,并尝试了许多事情来解决它,使用woocommerce对象,并在使用WordPress数据库对象的数据库中添加了有关术语,termmeta,术语与post的关系的缺失数据 - 但没有什么足以使其工作。我无法确定我哪里出错了 - 这就是为什么我不能提供一个更狭窄的问题 - 堆栈溢出更适合的事情。


答案 1

2020年1月更新:更改为WC_Product方法get_name() 而不是
2018 年 9 月更新:处理分类创建(感谢 Carl F. Corneil)get_title()

从定义的可变产品ID中,您将在下面找到一个自定义函数,该函数将添加(创建)产品变体。变量父产品需要为其设置所需的属性。

您需要提供一些信息,例如:

  • 属性/值的数组
  • 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
}

代码进入函数.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 );

经过测试并正常工作。

第 2 部分:以编程方式在 WooCommerce 中创建一个可变产品和两个新属性

您将在后端获得此内容:

enter image description here

它将在前端完美运行。

相关:在Woocommerce 3中使用CRUD方法以编程方式创建产品


答案 2

我只是要把它扔在那里,因为我无法让上面的任何例子工作。不要问我为什么其他人似乎成功了。因此,我采用了极简主义的方法,并试图找出产品属性+变体的基本要素(通过在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”等),而且这样做可能不是超级未来证明。


推荐