Create programmatically a product using CRUD methods in Woocommerce 3

You are not accessing the WC_Product_simple instance object from your custom Dropship Data Scraper plugin.

The guilty can be mostly 2 things:

  1. You have not installed Woocommerce.
  2. The plugin Dropship Data Scraper is outdated and needs changes, to handle woocommerce.

Try to include the global Woocommerce object and to enable Woocommerce support in your plugin.


To create a product programmatically using CRUD methods introduced in Woocommerce 3 here is the correct way to make it work.

If you need to handle product attributes creation or product variations creation, refer to:

All product attributes and their term values need to be created before. Same thing for product categories and product tags.

1) The code functions:

    // Custom function for product creation (For Woocommerce 3+ only)
    function create_product( $args ){

        if( ! function_exists('wc_get_product_object_type') && ! function_exists('wc_prepare_product_attributes') )
            return false;

        // Get an empty instance of the product object (defining it's type)
        $product = wc_get_product_object_type( $args['type'] );
        if( ! $product )
            return false;

        // Product name (Title) and slug
        $product->set_name( $args['name'] ); // Name (title).
        if( isset( $args['slug'] ) )
            $product->set_name( $args['slug'] );

        // Description and short description:
        $product->set_description( $args['description'] );
        $product->set_short_description( $args['short_description'] );

        // Status ('publish', 'pending', 'draft' or 'trash')
        $product->set_status( isset($args['status']) ? $args['status'] : 'publish' );

        // Visibility ('hidden', 'visible', 'search' or 'catalog')
        $product->set_catalog_visibility( isset($args['visibility']) ? $args['visibility'] : 'visible' );

        // Featured (boolean)
        $product->set_featured(  isset($args['featured']) ? $args['featured'] : false );

        // Virtual (boolean)
        $product->set_virtual( isset($args['virtual']) ? $args['virtual'] : false );

        // Prices
        $product->set_regular_price( $args['regular_price'] );
        $product->set_sale_price( isset( $args['sale_price'] ) ? $args['sale_price'] : '' );
        $product->set_price( isset( $args['sale_price'] ) ? $args['sale_price'] :  $args['regular_price'] );
        if( isset( $args['sale_price'] ) ){
            $product->set_date_on_sale_from( isset( $args['sale_from'] ) ? $args['sale_from'] : '' );
            $product->set_date_on_sale_to( isset( $args['sale_to'] ) ? $args['sale_to'] : '' );
        }

        // Downloadable (boolean)
        $product->set_downloadable(  isset($args['downloadable']) ? $args['downloadable'] : false );
        if( isset($args['downloadable']) && $args['downloadable'] ) {
            $product->set_downloads(  isset($args['downloads']) ? $args['downloads'] : array() );
            $product->set_download_limit(  isset($args['download_limit']) ? $args['download_limit'] : '-1' );
            $product->set_download_expiry(  isset($args['download_expiry']) ? $args['download_expiry'] : '-1' );
        }

        // Taxes
        if ( get_option( 'woocommerce_calc_taxes' ) === 'yes' ) {
            $product->set_tax_status(  isset($args['tax_status']) ? $args['tax_status'] : 'taxable' );
            $product->set_tax_class(  isset($args['tax_class']) ? $args['tax_class'] : '' );
        }

        // SKU and Stock (Not a virtual product)
        if( isset($args['virtual']) && ! $args['virtual'] ) {
            $product->set_sku( isset( $args['sku'] ) ? $args['sku'] : '' );
            $product->set_manage_stock( isset( $args['manage_stock'] ) ? $args['manage_stock'] : false );
            $product->set_stock_status( isset( $args['stock_status'] ) ? $args['stock_status'] : 'instock' );
            if( isset( $args['manage_stock'] ) && $args['manage_stock'] ) {
                $product->set_stock_status( $args['stock_qty'] );
                $product->set_backorders( isset( $args['backorders'] ) ? $args['backorders'] : 'no' ); // 'yes', 'no' or 'notify'
            }
        }

        // Sold Individually
        $product->set_sold_individually( isset( $args['sold_individually'] ) ? $args['sold_individually'] : false );

        // Weight, dimensions and shipping class
        $product->set_weight( isset( $args['weight'] ) ? $args['weight'] : '' );
        $product->set_length( isset( $args['length'] ) ? $args['length'] : '' );
        $product->set_width( isset(  $args['width'] ) ?  $args['width']  : '' );
        $product->set_height( isset( $args['height'] ) ? $args['height'] : '' );
        if( isset( $args['shipping_class_id'] ) )
            $product->set_shipping_class_id( $args['shipping_class_id'] );

        // Upsell and Cross sell (IDs)
        $product->set_upsell_ids( isset( $args['upsells'] ) ? $args['upsells'] : '' );
        $product->set_cross_sell_ids( isset( $args['cross_sells'] ) ? $args['upsells'] : '' );

        // Attributes et default attributes
        if( isset( $args['attributes'] ) )
            $product->set_attributes( wc_prepare_product_attributes($args['attributes']) );
        if( isset( $args['default_attributes'] ) )
            $product->set_default_attributes( $args['default_attributes'] ); // Needs a special formatting

        // Reviews, purchase note and menu order
        $product->set_reviews_allowed( isset( $args['reviews'] ) ? $args['reviews'] : false );
        $product->set_purchase_note( isset( $args['note'] ) ? $args['note'] : '' );
        if( isset( $args['menu_order'] ) )
            $product->set_menu_order( $args['menu_order'] );

        // Product categories and Tags
        if( isset( $args['category_ids'] ) )
            $product->set_category_ids( $args['category_ids'] );
        if( isset( $args['tag_ids'] ) )
            $product->set_tag_ids( $args['tag_ids'] );


        // Images and Gallery
        $product->set_image_id( isset( $args['image_id'] ) ? $args['image_id'] : "" );
        $product->set_gallery_image_ids( isset( $args['gallery_ids'] ) ? $args['gallery_ids'] : array() );

        ## --- SAVE PRODUCT --- ##
        $product_id = $product->save();

        return $product_id;
    }

    // Utility function that returns the correct product object instance
    function wc_get_product_object_type( $type="simple" ) {
        // Get an instance of the WC_Product object (depending on his type)
        if( $type === 'variable' ){
            $product = new WC_Product_Variable();
        } elseif( $type === 'grouped' ){
            $product = new WC_Product_Grouped();
        } elseif( $type === 'external' ){
            $product = new WC_Product_External();
        } else {
            $product = new WC_Product_Simple(); // "simple" By default
        } 
        
        if( ! is_a( $product, 'WC_Product' ) )
            return false;
        else
            return $product;
    }

    // Utility function that prepare product attributes before saving
    function wc_prepare_product_attributes( $attributes ){
        global $woocommerce;

        $data = array();
        $position = 0;

        foreach( $attributes as $taxonomy => $values ){
            if( ! taxonomy_exists( $taxonomy ) )
                continue;

            // Get an instance of the WC_Product_Attribute Object
            $attribute = new WC_Product_Attribute();

            $term_ids = array();

            // Loop through the term names
            foreach( $values['term_names'] as $term_name ){
                if( term_exists( $term_name, $taxonomy ) )
                    // Get and set the term ID in the array from the term name
                    $term_ids[] = get_term_by( 'name', $term_name, $taxonomy )->term_id;
                else
                    continue;
            }

            $taxonomy_id = wc_attribute_taxonomy_id_by_name( $taxonomy ); // Get taxonomy ID

            $attribute->set_id( $taxonomy_id );
            $attribute->set_name( $taxonomy );
            $attribute->set_options( $term_ids );
            $attribute->set_position( $position );
            $attribute->set_visible( $values['is_visible'] );
            $attribute->set_variation( $values['for_variation'] );

            $data[$taxonomy] = $attribute; // Set in an array

            $position++; // Increase position
        }
        return $data;
    }

2) USAGE: – Example for a simple product creation with 2 product attributes “Color” and “Size”:


    $product_id = create_product( array(
        'type'               => '', // Simple product by default
        'name'               => __("The product title", "woocommerce"),
        'description'        => __("The product description…", "woocommerce"),
        'short_description'  => __("The product short description…", "woocommerce"),
        // 'sku'                => '',
        'regular_price'      => '5.00', // product price
        // 'sale_price'         => '',
        'reviews_allowed'    => true,
        'attributes'         => array(
            // Taxonomy and term name values
            'pa_color' => array(
                'term_names' => array('Red', 'Blue'),
                'is_visible' => true,
                'for_variation' => false,
            ),
            'pa_size' =>  array(
                'term_names' => array('X Large'),
                'is_visible' => true,
                'for_variation' => false,
            ),
        ),
    ) );  

// Displaying the created product ID
echo $product_id;

Tested and works using only Woocommerce 3 CRUD methods.

Leave a Comment