WooCommerce:按代码创建产品

Bee*_*her 14 php wordpress woocommerce

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

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

如何创建产品及其变体?

小智 16

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

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


Ved*_*ego 14

正如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);
}
Run Code Online (Sandbox Code Playgroud)

$rest_request是一个你通常通过REST发送的数组(参见这里的文档).

$products_controler,因为我需要多次调用这个函数,我不想每次都重新创建对象变量是全球性的.随意使它成为本地的.

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

编辑:鉴于这个答案仍然得到偶尔的upvote,这是一个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;
}
Run Code Online (Sandbox Code Playgroud)

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

还有一个更长的"快速"版本被称为create_products_fast直接写入数据库,使其对未来WP/WC更改的可能性降低,但速度要快得多(我的测试中34个产品系列的几秒钟与几分钟相比)电脑).


小智 10

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

$objProduct = new WC_Product();
Run Code Online (Sandbox Code Playgroud)

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

$objProduct = new WC_Product_Variable();
Run Code Online (Sandbox Code Playgroud)

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

$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
Run Code Online (Sandbox Code Playgroud)

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

保存产品以获取 WooCommerce 产品 ID

$product_id = $objProduct->save(); // it will save the product and return the generated product id
Run Code Online (Sandbox Code Playgroud)

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

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

$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
}
Run Code Online (Sandbox Code Playgroud)

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

$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
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Sop*_*rus 8

根据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 );
Run Code Online (Sandbox Code Playgroud)