15

我的商店出售乙烯基贴纸。每个产品(贴纸)有 144 种变化(24 种颜色、3 种尺寸和 2 种方向)。每个变体都是分配唯一 SKU 所必需的。

手动填充目录是不现实的。我将制作一个表单,用户可以在其中指定产品的名称、描述和主图像,以及可能的尺寸和颜色。在处理表单时,我需要创建一个产品及其所有变体。

如何创建产品及其变体?

4

6 回答 6

17

我有类似的情况,这是我发现的。

产品实际上是一种自定义帖子类型(很明显!:P),因此您可以使用它wp_insert_post来插入新产品。插入后,您将获得新产品帖子类型的 id,用于update_post_meta将元键和元值分别设置为_visibilityvisible。如果您不设置可见性,您新添加的产品将永远不会在您的商店中可见。或者,您也可以从后端设置可见性。对于产品的各种尺寸,请使用该产品的变体。您可以为每个变体设置不同的类型、价格、SKU 等。所有这些都是后元,因此您可以使用 php 代码添加变体和东西。研究postmeta表格以查看键名。

于 2012-08-17T11:46:23.280 回答
17

正如 Jason 在他的评论中所写,REST API 是这里的必经之路。这甚至可以在没有 HTTP REST 请求的情况下完成,即使在禁用 REST 接口的 Wordpress 安装上也能正常工作。

这是我为此目的制作的一个简单函数:

$products_controler = new WC_REST_Products_Controller();
function create_item($rest_request) {
    global $products_controler;
    if (!isset($rest_request['status']))
        $rest_request['status'] = 'publish';
    $wp_rest_request = new WP_REST_Request('POST');
    $wp_rest_request->set_body_params($rest_request);
    return $products_controler->create_item($wp_rest_request);
}

在这里,$rest_request您通常会通过 REST 发送一个数组(请参阅此处的文档)。

$products_controler变量是全局变量,因为我需要多次调用此函数,并且我不想每次都重新创建该对象。随意将其本地化。

这适用于所有类型的产品(简单的、分组的、可变的……),并且它应该比通过手动添加产品更能抵抗 WooCommerce 的内部更改wp_insert_postupdate_post_meta

编辑:鉴于这个答案仍然偶尔会得到支持,这里是WooCommerce 3.0+更新。变化是不再自动添加变化,所以我们必须自己做。

这是该函数的当前版本:

protected function create_item( $rest_request ) {
    if ( ! isset( $rest_request['status'] ) ) {
        $rest_request['status'] = $this->plugin->get_option( 'default_published_status' );
    }
    if ( ! isset( $this->products_controler ) ) {
        $this->products_controler = new WC_REST_Products_Controller();
    }
    $wp_rest_request = new WP_REST_Request( 'POST' );
    $wp_rest_request->set_body_params( $rest_request );
    $res = $this->products_controler->create_item( $wp_rest_request );
    $res = $res->data;
    // The created product must have variations
    // If it doesn't, it's the new WC3+ API which forces us to build those manually
    if ( ! isset( $res['variations'] ) )
        $res['variations'] = array();
    if ( count( $res['variations'] ) == 0 && count( $rest_request['variations'] ) > 0 ) {
        if ( ! isset( $this->variations_controler ) ) {
            $this->variations_controler = new WC_REST_Product_Variations_Controller();
        }
        foreach ( $rest_request['variations'] as $variation ) {
            $wp_rest_request = new WP_REST_Request( 'POST' );
            $variation_rest = array(
                'product_id' => $res['id'],
                'regular_price' => $variation['regular_price'],
                'image' => array( 'id' => $variation['image'][0]['id'], ),
                'attributes' => $variation['attributes'],
            );
            $wp_rest_request->set_body_params( $variation_rest );
            $new_variation = $this->variations_controler->create_item( $wp_rest_request );
            $res['variations'][] = $new_variation->data;
        }
    }
    return $res;
}

这用于Kite Print 和 Dropshipping on Demand插件,从(即将发布)版本 1.1 开始,在文件api/publish_products.php.

还有一个更长的“快速”版本,称为create_products_fast直接写入数据库,使其对未来 WP/WC 更改的弹性可能降低,但它更快(在我的测试中,我们的 34 种产品范围为几秒而不是几分钟计算机)。

于 2016-10-19T13:42:04.730 回答
11

这是最合乎逻辑和最简单的方法。简单产品使用以下代码:

$objProduct = new WC_Product();

并用于代码行下方的可变产品。

$objProduct = new WC_Product_Variable();

下一步是设置元属性,如名称、价格等和变体数据(在可变产品的情况下)。

$objProduct->set_name("Product Title");
$objProduct->set_status("publish");  // can be publish,draft or any wordpress post status
$objProduct->set_catalog_visibility('visible'); // add the product visibility status
$objProduct->set_description("Product Description");
$objProduct->set_sku("product-sku"); //can be blank in case you don't have sku, but You can't add duplicate sku's
$objProduct->set_price(10.55); // set product price
$objProduct->set_regular_price(10.55); // set product regular price
$objProduct->set_manage_stock(true); // true or false
$objProduct->set_stock_quantity(10);
$objProduct->set_stock_status('instock'); // in stock or out of stock value
$objProduct->set_backorders('no');
$objProduct->set_reviews_allowed(true);
$objProduct->set_sold_individually(false);
$objProduct->set_category_ids(array(1,2,3)); // array of category ids, You can get category id from WooCommerce Product Category Section of Wordpress Admin

如果您要上传产品图片,请使用以下代码

function uploadMedia($image_url){
    require_once('wp-admin/includes/image.php');
    require_once('wp-admin/includes/file.php');
    require_once('wp-admin/includes/media.php');
    $media = media_sideload_image($image_url,0);
    $attachments = get_posts(array(
        'post_type' => 'attachment',
        'post_status' => null,
        'post_parent' => 0,
        'orderby' => 'post_date',
        'order' => 'DESC'
    ));
    return $attachments[0]->ID;
}
// above function uploadMedia, I have written which takes an image url as an argument and upload image to wordpress and returns the media id, later we will use this id to assign the image to product.
$productImagesIDs = array(); // define an array to store the media ids.
$images = array("image1 url","image2 url","image3 url"); // images url array of product
foreach($images as $image){
    $mediaID = uploadMedia($image); // calling the uploadMedia function and passing image url to get the uploaded media id
    if($mediaID) $productImagesIDs[] = $mediaID; // storing media ids in a array.
}
if($productImagesIDs){
    $objProduct->set_image_id($productImagesIDs[0]); // set the first image as primary image of the product

        //in case we have more than 1 image, then add them to product gallery. 
    if(count($productImagesIDs) > 1){
        $objProduct->set_gallery_image_ids($productImagesIDs);
    }
}

保存产品以获取 WooCommerce 产品 ID

$product_id = $objProduct->save(); // it will save the product and return the generated product id

注意:对于简单的产品,以上步骤就足够了,以下步骤适用于可变产品或具有属性的产品。

下面的代码用于添加产品属性。

$attributes = array(
    array("name"=>"Size","options"=>array("S","L","XL","XXL"),"position"=>1,"visible"=>1,"variation"=>1),
    array("name"=>"Color","options"=>array("Red","Blue","Black","White"),"position"=>2,"visible"=>1,"variation"=>1)
);
if($attributes){
    $productAttributes=array();
    foreach($attributes as $attribute){
        $attr = wc_sanitize_taxonomy_name(stripslashes($attribute["name"])); // remove any unwanted chars and return the valid string for taxonomy name
        $attr = 'pa_'.$attr; // woocommerce prepend pa_ to each attribute name
        if($attribute["options"]){
            foreach($attribute["options"] as $option){
                wp_set_object_terms($product_id,$option,$attr,true); // save the possible option value for the attribute which will be used for variation later
            }
        }
        $productAttributes[sanitize_title($attr)] = array(
            'name' => sanitize_title($attr),
            'value' => $attribute["options"],
            'position' => $attribute["position"],
            'is_visible' => $attribute["visible"],
            'is_variation' => $attribute["variation"],
            'is_taxonomy' => '1'
        );
    }
    update_post_meta($product_id,'_product_attributes',$productAttributes); // save the meta entry for product attributes
}

下面的代码用于添加产品变体。

$variations = array(
    array("regular_price"=>10.11,"price"=>10.11,"sku"=>"ABC1","attributes"=>array(array("name"=>"Size","option"=>"L"),array("name"=>"Color","option"=>"Red")),"manage_stock"=>1,"stock_quantity"=>10),
    array("regular_price"=>10.11,"price"=>10.11,"sku"=>"ABC2","attributes"=>array(array("name"=>"Size","option"=>"XL"),array("name"=>"Color","option"=>"Red")),"manage_stock"=>1,"stock_quantity"=>10)
    
);
if($variations){
    try{
        foreach($variations as $variation){
            $objVariation = new WC_Product_Variation();
            $objVariation->set_price($variation["price"]);
            $objVariation->set_regular_price($variation["regular_price"]);
            $objVariation->set_parent_id($product_id);
            if(isset($variation["sku"]) && $variation["sku"]){
                $objVariation->set_sku($variation["sku"]);
            }
            $objVariation->set_manage_stock($variation["manage_stock"]);
            $objVariation->set_stock_quantity($variation["stock_quantity"]);
            $objVariation->set_stock_status('instock'); // in stock or out of stock value
            $var_attributes = array();
            foreach($variation["attributes"] as $vattribute){
                $taxonomy = "pa_".wc_sanitize_taxonomy_name(stripslashes($vattribute["name"])); // name of variant attribute should be same as the name used for creating product attributes
                $attr_val_slug =  wc_sanitize_taxonomy_name(stripslashes($vattribute["option"]));
                $var_attributes[$taxonomy]=$attr_val_slug;
            }
            $objVariation->set_attributes($var_attributes);
            $objVariation->save();
        }
    }
    catch(Exception $e){
        // handle exception here
    }
}

就是这样上面的代码足以添加带有图像、属性和变体的简单或可变 WooCommerce 产品。

于 2020-10-09T23:53:10.287 回答
10

根据Vedran 的回答,这是通过 PHP 发布 WooCommerce 产品的最少代码:

$data = [
    'name' => 'Test product',
    'description' => 'Lorem ipsum',
];
$request = new WP_REST_Request( 'POST' );
$request->set_body_params( $data );
$products_controller = new WC_REST_Products_Controller;
$response = $products_controller->create_item( $request );
于 2017-07-28T02:37:44.313 回答
2

请参阅woocommerce-with-php-code,其中给出了完整代码。

正如前卫所说,产品在后期添加:

post_type = "product"

于 2014-06-04T10:13:43.167 回答
0

我使用这个代码:

$sku = 21333;
$size = 'S';
$stock = 2;
$price_a = 60;
$price_b = 30;

$product_parent = get_product_by_sku($sku);
$product = new WC_Product_Variable($product_parent->id);
$variations = $product->get_available_variations();

// First off all delete all variations
foreach($variations as $prod_variation) {
  $metaid=mysql_query("SELECT meta_id FROM wp_postmeta WHERE post_id = ".$prod_variation['variation_id']);
  while ($row = mysql_fetch_assoc($metaid)) {
    mysql_query("DELETE FROM wp_postmeta WHERE meta_id = ".$row['meta_id']);
  }
  mysql_query("DELETE FROM wp_posts WHERE ID = ".$prod_variation['variation_id']);
}

// Now add new variation
$thevariation = array(
  'post_title'=> '',
  'post_name' => 'product-' . $product_parent->id . '-variation',
  'post_status' => 'publish',
  'post_parent' => $product_parent->id,
  'post_type' => 'product_variation',
  'guid'=>home_url() . '/?product_variation=product-' . $product_parent->id . '-variation'
);
$variation_id = wp_insert_post( $thevariation );
update_post_meta($variation_id, 'post_title', 'Variation #' . $variation_id . ' of '. $product_parent->id);

wp_set_object_terms( $variation_id, $size, 'pa_size' );
update_post_meta($variation_id, 'attribute_pa_size', $size);

update_post_meta($variation_id, '_regular_price', $price_a);
update_post_meta($variation_id, '_downloadable_files', '');
update_post_meta($variation_id, '_download_expiry', '');
update_post_meta($variation_id, '_download_limit', '');
update_post_meta($variation_id, '_sale_price_dates_to', '');
update_post_meta($variation_id, '_sale_price_dates_from', '');
update_post_meta($variation_id, '_backorders', 'no');
update_post_meta($variation_id, '_stock_status', 'instock');
update_post_meta($variation_id, '_height', '');
update_post_meta($variation_id, '_manage_stock', 'yes');
update_post_meta($variation_id, '_width', '');
update_post_meta($variation_id, '_sale_price_dates_from', '');
update_post_meta($variation_id, '_backorders', 'no');
update_post_meta($variation_id, '_stock_status', 'instock');
update_post_meta($variation_id, '_manage_stock', 'yes');
update_post_meta($variation_id, '_height', '');
update_post_meta($variation_id, '_width', '');
update_post_meta($variation_id, '_length', '');
update_post_meta($variation_id, '_weight', '');
update_post_meta($variation_id, '_downloadable', 'no');
update_post_meta($variation_id, '_virtual', 'no');
update_post_meta($variation_id, '_thumbnail_id', '0');
update_post_meta($variation_id, '_sku', '');

update_post_meta($variation_id, '_sale_price', $price_b);
update_post_meta($variation_id, '_price', $price_b);
update_post_meta($product_parent->id, '_min_variation_price', $price_b);
update_post_meta($product_parent->id, '_max_variation_price', $price_b);
update_post_meta($product_parent->id, '_min_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_max_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_min_variation_regular_price', $price_a);
update_post_meta($product_parent->id, '_max_variation_regular_price', $price_a);
update_post_meta($product_parent->id, '_min_regular_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_max_regular_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_min_variation_sale_price', $price_b);
update_post_meta($product_parent->id, '_max_variation_sale_price', $price_b);
update_post_meta($product_parent->id, '_min_sale_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_max_sale_price_variation_id', $variation_id);
update_post_meta($product_parent->id, '_price', $price_b);

update_post_meta( $variation_id, '_stock', $stock );
update_post_meta($product_parent->id, 'post_status', 'publish');
于 2017-07-12T10:30:41.823 回答