【问题标题】:WooCommerce: Create product by codeWooCommerce:通过代码创建产品
【发布时间】:2012-07-15 06:16:42
【问题描述】:

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

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

如何创建产品及其变体?

【问题讨论】:

  • 您需要创建图像还是打印出可能的选项?
  • 现在有一个 V2 REST API,我建议使用它来创建产品。 API 可以以不同的用户身份登录,它满足了手动构建产品时可能被忽略的所有细微之处。它还涉及将一个大型数据结构放在一起,然后将其发送出去,以便在一个操作中进行设置。
  • WooCommerce 在 3.0 中引入了新的 CRUD 对象 - 强烈建议您开始使用它,而不是使用纯 Wordpress 函数来更新反向工程数据。 github.com/woocommerce/woocommerce/wiki/CRUD-Objects-in-3.0

标签: php wordpress woocommerce


【解决方案1】:

我也遇到过类似的情况,这是我发现的。

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

【讨论】:

  • 当我设置 update_post_meta( $new_product_post_id, '_visibility', 'hidden' ); 但在产品详细信息后端页面上。它仍然显示 visible 值。怎么了?
【解决方案2】:

正如 Jason 在his comment 中所写,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 发送的数组(请参阅文档 here)。

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

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

编辑:鉴于此答案仍然偶尔会获得支持,这里是 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 and Dropshipping on Demand 插件,从(即将发布的)1.1 版开始,在文件api/publish_products.php 中。

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

【讨论】:

  • 您好,create_products_fast 版本是 WC 的一部分还是用于 Kite Print 插件?
  • @JeansK.Real 它是 Kite(现已停产)插件中的一个函数,其中通常通过许多 WP 函数(在我们的例子中是几百个调用)完成的所有 SQL 请求都仅分组5 或 6 个批量 SQL 调用,使其速度极快,但对 WP/WC 更改也不是很有弹性。作为此类情况的备份,我们有一个设置可以打开或关闭该功能(在后一种情况下,使用上述功能代替)。
【解决方案3】:

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

$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 产品。

【讨论】:

    【解决方案4】:

    基于Vedran's answer,这是通过 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 );
    

    【讨论】:

    • 谢谢!这种方式是绝对正确的,因为它使用了每次都会更改的 WooCommerce API。我测试了这段代码,它在元表和其他表中创建了所有必需的产品数据。
    【解决方案5】:

    请参考woocommerce-with-php-code,这里给出了完整的代码。

    正如前卫所说,产品是在帖子中添加的:

    post_type = "product"

    【讨论】:

      【解决方案6】:

      我使用这个代码:

      $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');
      

      【讨论】:

        猜你喜欢
        • 2020-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-20
        • 1970-01-01
        • 1970-01-01
        • 2020-06-06
        • 1970-01-01
        相关资源
        最近更新 更多