How do I create a product with variations? - php

I'm trying to create a product in php with variations. I've gotten the product creation but I can't seem to figure out how to create variations for it. Googling only returns adding variations to existing products, but I'm trying to create a product completely from scratch, give it an attribute, and using that attribute to make variations from an array of strings.
$team = get_post();
$post_id = wp_insert_post(
array( 'post_title' => $team->post_title,
'post_type' => 'product',
'post_status' => 'publish'
)
);
wp_set_object_terms( $post_id, 'simple', 'variable' );
update_post_meta( $post_id, '_sku', 'FEES-'.$team->ID );
This is what I have so far.

I think you need to use "WC_Product_Variation"class for registering variations and wp_insert_post for creating the product variable.
have a look at this example, it might help you or give an idea.
Create WooCommerce Variable Product with Attributes
See more info in woocommerce docs: WC_Product_Variation

Related

WooCommerce programmatically created product ignores prices sorting filter

I have following function to create new woocommerce product on the frontend.
parse_str($_POST['form_data'], $form_data);
$insertPost = array(
//'ID' => $post_id,
'post_title' => $form_data['post_title'],
'post_status' => $form_data['post_status'],
'post_type' => 'product',
'post_content' => $form_data['post_content']
);
$insert_post = wp_insert_post( $insertPost, true);
update_post_meta( $insert_post, 'hours', $form_data['hours'] );
update_post_meta( $insert_post, 'year', $form_data['year'] );
update_post_meta( $insert_post, '_weight', $form_data['_weight'] );
update_post_meta( $insert_post, '_price', $form_data['_regular_price'] );
update_post_meta( $insert_post, '_regular_price', $form_data['_regular_price'] );
update_post_meta( $insert_post, '_sale_price', $form_data['_sale_price'] );
update_post_meta( $insert_post, '_stock_status', $form_data['_stock_status'] );
$term_taxonomy_ids = wp_set_object_terms( $insert_post, array(15), 'product_cat' );
wp_set_object_terms( $insert_post, 'simple', 'product_type' );
The code above is creating a new product and adding all data to it as expected.
The issue is when using the sort by price filter, the sorting doesn't really sort the newly product created in proper way, it just ignores it.
After searching i found in WooCommerce > Status > Tools > Product lookup tables (regenerate)
once i click the regenerate button, then it regenerate all product data and the price sorting is working as expected.
So what is missing in my function to make the price sorting work without regenerate button?
There are some custom WooCommerce database tables and cached data that your outdated code doesn't handle, so use the following (using WC_Product methods) like:
parse_str($_POST['form_data'], $form_data);
// Get an empty instance of the WC_Product Object (with the correct product type)
$product = new WC_Product_Simple(); // "simple" product type
$product->set_name($form_data['post_title']);
$product->set_status($form_data['post_status']);
$product->set_description($form_data['post_content']);
if( isset($form_data['post_excerpt']) ) {
$product->set_short_description($form_data['post_excerpt']); // Optional
}
$product->add_meta_data('hours', $form_data['hours']);
$product->add_meta_data('year', $form_data['year']);
$product->set_price($form_data['_regular_price']);
$product->set_regular_price($form_data['_regular_price']);
$product->set_sale_price($form_data['_sale_price']);
$product->set_weight($form_data['_weight']);
$product->set_stock_status($form_data['_stock_status']);
$product->set_category_ids( array(15) );
$product->save(); // Save to database
It should work now with "sort by price filter" without regenerating product data.
Related: Create programmatically a product using CRUD methods in Woocommerce 3

Woocommerce Coupons - can't update product ids using update_post_meta programmatically

I'm trying to programmatically create a Woocommerce coupon when a form is submitted on a single page template using the ACF fields from my page template ID for the coupon properties.
Looking at the Woocommerce documentation on how to do this, they suggest setting the properties using the update_post_meta() after inserting a new coupon.
However, when doing this the product ids aren't being aded when printing out the WC_Coupon object for the generated coupon and returns an empty array.
I've made sure the ACF field landing_page_products returns an array of ids when printing this out separately but for some reason doesn't get added to the object or displays in the admin coupon screen.
I discovered that if i use the $coupon->set_product_ids($products); instead of updating the meta then this seems to work.
Can anyone explain why the update meta for the product ids isn't working?
$coupon = [
'post_title' => $coupon_code,
'post_content' => '',
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'shop_coupon'
];
$coupon_id = wp_insert_post($coupon);
// Get products meta from current landing page $post_id //
$products = get_field('landing_page_products', $post_id);
/** Set default coupon meta **/
update_post_meta($coupon_id, 'individual_use', 'yes');
update_post_meta($coupon_id, 'apply_before_tax', 'no' );
update_post_meta($coupon_id, 'free_shipping', 'no' );
update_post_meta($coupon_id, 'product_ids', $products );
WC_Coupon Object
(
[data:protected] => Array
(
[product_ids] => Array
(
)
)
I have worked on Creating and Updating Woocommerce coupons programmatically before, using: Woo Docs - Despite this doc, array() parameter for update_post_meta is not working.
This is my code (tested) working now, the 'product_ids' for update_post_meta requires string, not an array. Example code for products with IDs: 130 and 131:
update_post_meta( $_newCouponID, 'product_ids', "130, 131");
//or
$product_ids = "130, 131";
update_post_meta( $_newCouponID, 'product_ids', $product_ids);
//still use wp_update_post at the end of your code
wp_update_post($_newCouponID);
I hope this helps. Have a good day.

WooCommerce adding product variations programatically with different price will not reflect on the product page

Let me put it simple.
We have products with color and size attributes in database
The products are all variable products
Variations are added for every color and "Any" size
Then we wrote a few functions to add 2 more variations to each product for the sizes 2XL and 3XL (the products are t-shirts) with a higher price!
The variations are added beautifully, however, on the front end, the price will not change when I select the size with the increased price unless I go to a product edit page and click the update button. Only then will the price to be added to the cart change upon selecting that size.
How can make the variations with the increased price reflect on the front-end without having to click the update button for each product?
Maybe you need to run variable_product_sync() on each variable product?
function so_run_once(){
$variable_products = get_posts( array(
'posts_per_page'=> -1,
'post_type' => 'product',
'fields' => 'ids',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => 'variable',
),
)
) );
if( $variable_products ) foreach( $variable_products as $product_id ){
$_product = wc_get_product( $product_id );
$_product->variable_product_sync();
}
}
add_action( 'admin_init', 'so_run_once' );
Found a solution! We had to delete the transient meta data of each post after inserting the variation..
$transient_name = 'wc_product_children_ids_' . $proudct_id;
delete_transient( $transient_name );

automatically inserted woocommerce product still needs update?

In Wordpress, I have a function which allows me to automatically add a woocommerce product by adding a new post of a custom post type called 'daily_cartoon'.
This the code of the function:
function convert_daily_cartoon_into_product($post_id){
if( ( $_POST['post_status'] == 'publish' ) && ( $_POST['original_post_status'] != 'publish' ) ) {
// Create post object
$post = array(
'post_title' => $_POST['post_title'],
'post_type' => 'product',
'post_status' => 'publish',
'tax_input' => array( 'product_cat' => 14 )
);
// Insert the post into the database
$new_print = wp_insert_post( $post );
update_post_meta( $new_print, '_thumbnail_id', get_post_thumbnail_id( $post_id ) );
update_post_meta( $new_print, '_regular_price', 5 );
update_post_meta( $new_print, '_price', 5 );
}
}
add_action('publish_daily_cartoon', 'convert_daily_cartoon_into_product');
The new product shows up nicely in the admin area, with all the data there - i.e. price, category, published, etc.
But for some reason it doesn't show up on the website shop page until I open the new product to edit and click update.
Anybody?
Make sure you set the _visibility meta of the product to visible
For those comming here
Don't forget to check your datas, I got a similar problem and it's because WP sanitize datas once you update them manually from the dashboard. That's why it worked for those updated manually.
Into my database, my datas got some hidden spaces (example : "Paris" / " Paris").
In case you need to import products, consider to use the wp function sanitize_text_field()

WooCommerce front-end product creation

Ok I'll try and ask this in a way that will not confuse everyone with my confusion
I am trying to make a front-end form for WooCommerce so customers can make a product from the front-end.
I have all the other parts I want to implement so far working ie. Title, content and price
all posted in the correct post type. But can't get it to post to a product category
WooCommerce categories is a custom-Taxonomy named product_cat <--almost 100% sure.
product_cat children are Terms, I have three --> Base, Designs and User Designs
I want all posts from this form to automatically be under User Designs. This is what I have now
$post_information = array(
'post_title' => esc_attr(strip_tags($_POST['postTitle'])),
'post_content' => esc_attr(strip_tags($_POST['postContent'])),
'post_type' => 'product',
'post_status' => 'publish',
);
$post_id = wp_insert_post($post_information);
update_post_meta( $post_id, '_regular_price', strip_tags($_POST['_regular_price'] ) ) ;
if($post_id)
{
wp_redirect(home_url());
exit;
}
};
I have tried many variations to set terms like
wp_set_object_terms($post_id, 'designs', 'product_cat', false);
wp_set_post_terms($post_id, 'designs', 'product_cat', false);
wp_set_object_terms($post_id, $designs ,'product_cat');
wp_set_post_terms( $post_id, $designs, 'product_cat', true );
wp_set_object_terms($post_id, $base, 'product_cat');
No go, I know I'm missing something but I have no idea what. I've been looking at my screen so long my eyes are crossing,
Any help will be greatly appreciated thanks in advance
Use the following:
wp_set_post_terms( $product_id, '343', 'product_cat');
Where $product_id is the post_id of the product you're making, and 343 is the taxonomy id (you can get it from one of the taxonomy tables)

Categories