Inserting parent variable product first:
$parent_product = array(
'post_title' => 'Euro Washing Machine',
'post_content' => 'Some Description',
'post_type' => 'product',
'post_status' => 'publish',
'post_parent' => '',
'meta_input' => array(
'_rrp' => 220,
'_sku' =>'wedf4532d',
'_visibility' => 'visible'
)
);
$parent_product_id = wp_insert_post( $parent_product, true );
if ( ! $parent_product_id ) {
return 0;
}
wp_set_object_terms( $parent_product_id, 'variable', 'product_type' );
wp_set_object_terms( $parent_product_id, 'brand-new', 'pa_' . 'condition' );
$parent_data_attributes[ 'pa_' . 'condition' ] = array(
'name' => 'pa_' . 'condition',
'value' => 'brand-new',
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '1'
);
update_post_meta( $parent_product_id, '_product_attributes', $parent_data_attributes );
Insert Product Variation with attribute pa_condition
$variation_product = array(
'post_title' => 'Euro Washing Machine',
'post_name' => 'product-' . $parent_product_id . '-variation',
'post_status' => 'publish',
'post_parent' => $parent_product_id,
'post_type' => 'product_variation'
);
$variation_product_id = wp_insert_post( $variation_product );
update_post_meta( $variation_product_id, '_price', 221 );
update_post_meta( $variation_product_id, '_sale_price', 221 );
update_post_meta( $variation_product_id, '_regular_price', 221 );
update_post_meta( $variation_product_id, '_manage_stock', 'true' );
update_post_meta( $variation_product_id, '_stock', 1 );
$variation = new WC_Product_Variation($variation_product_id);
$variation->set_attributes( array(
'pa_condition' => 'brand-new'
) );
$variation->save();
Programmatically added variation showing on admin area but not showing on Front-End. If I logged in to admin and just hit update the product then it appears on the front.
Can you please tell me, What I am missing here?
I got this problem due to setting up the product category on the variable product after creating all variations.
$ret = wp_set_object_terms($variable_product_id, $term_id, 'product_cat');
If I set the category on the variable product before creating all the variations then it solved the issue. Now I can see all variations on my category pages.
Related
I need to add an inventory to a woocomerce website. I currently have an array that looks like this:
[0] => Array
(
[name] => Lenovo 0A36307
[product_id] => 0
[type] => simple
[description] => Technical Specifications:
Manufacturer: Lenovo
Model: 0A36307
Model compatible Lenovo Thinkpad x220, x230
Excellent quality at better than new prices.
[regular_price] => 119.99
[old_price] => 50.00
[manage_stock] => 1
[stock] => 0
[weight] => 0
[has_variations] => 0
[image] => [.......]/s/files/1/0016/1133/3750/products/batterie_20lenovo_200a36307_20x230_fin_c23370c7-1d32-4403-90ff-f4e27a9522f7.jpg
[woo_cat_id] => 51
[woo_cat] => Laptop
[woo_sub_cat] => Lenovo
)
[...]
[woo_cat_id] is equal to the terme_id in wp_terms (I asumed that was the categorie ID)
I started looping the above array to add the items. The code looks like this:
logger("Checking if ".$product['name']." exists or not");
$check_sku=get_product_by_sku($product['product_id']);
if (empty($check_sku) ){
logger("Product does not exists proceed with insert");
$item = [
'post_title' => $product['name'],
'post_status' => 'publish',
'post_type' => 'product',
'post_content' => $product['description']
];
$postId = wp_insert_post($item);
}else{
logger("Product exists proceed with update");
$id= $check_sku->get_id();
$my_post = array(
'ID' => $id,
'post_title' => $product['name'],
'post_status' => 'publish',
'post_type' => 'product',
'post_content' => $product['description']
);
$postId = wp_update_post( $my_post );
}
logger("Creating product meta");
update_post_meta( $postId, '_visibility', 'visible' );
update_post_meta( $postId, '_stock_status', 'instock');
update_post_meta( $postId, '_regular_price', $product['regular_price'] );
update_post_meta( $postId, '_price', $product['regular_price'] );
update_post_meta( $postId, '_weight', $product['weight'] );
update_post_meta( $postId, '_sku', $product['product_id'] );
update_post_meta( $postId, '_stock', $product['stock'] );
update_post_meta( $postId, '_manage_stock', 'yes' );
logger("Adding product to category: ".$product['woo_cat']." (".$product['woo_cat_id'].")");
wp_set_object_terms( $postId, $product['woo_cat_id'], 'product_cat' );
The product is added but it somehow created a category using the [woo_cat_id] as the name instead of associating it to the existing category.
Also as you can see in the above picture, there's a subcategory for brands. How can I verify by name if the subcategory [woo_sub_cat] exists for the parent [woo_cat] and if not create it then associate it?
Am I wrong in using wp_set_object_terms()? or is there something else I can use?
https://developer.wordpress.org/reference/functions/wp_set_object_terms/
Inetead of wp_set_object_terms, you could use:
$p = wc_get_product( $postId );
//set categories with setter method
$p->set_category_ids( [$product['woo_cat_id']] );
$p->save();
I am trying to add 2 product variations programmatically for a variable product.
Based on this answer thread, I am using the following shortened function:
function create_product_variation( $product_id, $variation_data ){
$product = wc_get_product($product_id);
$variation_post = array(
'post_title' => $product->get_name(),
'post_name' => 'product-'.$product_id.'-variation',
'post_status' => 'publish',
'post_parent' => $product_id,
'post_type' => 'product_variation',
'guid' => $product->get_permalink()
);
$variation_id = wp_insert_post( $variation_post );
$variation = new WC_Product_Variation( $variation_id );
foreach($variation_data as $_variation_data){
foreach($_variation_data['attributes'] as $attribute => $term_name){
$taxonomy = 'pa_'.$attribute;
if( !taxonomy_exists( $taxonomy ) ){
register_taxonomy(
$taxonomy,
'product_variation',
array(
'hierarchical' => false,
'label' => ucfirst($attribute),
'query_var' => true,
'rewrite' => array( 'slug' => sanitize_title($attribute)),
)
);
}
if( ! term_exists( $term_name, $taxonomy ) )
wp_insert_term( $term_name, $taxonomy );
$term_slug = get_term_by('name', $term_name, $taxonomy )->slug;
$post_term_names = wp_get_post_terms( $product_id, $taxonomy, array('fields' => 'names') );
if( ! in_array( $term_name, $post_term_names ) )
wp_set_post_terms( $product_id, $term_name, $taxonomy, true );
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
}
}
$variation->save();
}
I use the following data array:
$variations_data = array(
array(
'attributes' => array(
'color' => 'Blue',
'warranty-and-insurance' => 'W1',
),
'sku' => ,
'regular_price' => 2000,
'sale_price' => 1800,
'stock_qty' => 5,
),
array(
'attributes' => array(
'color' => 'Red',
'warranty-and-insurance' => 'W1',
),
'sku' => ,
'regular_price' => 3000,
'sale_price' => 2800,
'stock_qty' => 3,
)
);
Then I run the function with the following:
create_product_variation( $variable_product_id, $variations_data );
where $variable_product_id is the id of the variable product which I want to make variations for it and $variations_data the data array defined above.
My problem is that the update_post_meta() function just insert the last data from the foreach in function.
i.e. in product variation in woocommerce there are:
Red W1
Red W1
but I want:
Blue W1
Red W1
In your code, the first foreach loop need to be just before the following line of code:
$variation_id = wp_insert_post( $variation_post );
like:
function create_product_variations( $product_id, $variations_data ){
$product = wc_get_product($product_id);
$variation_post = array(
'post_title' => $product->get_name(),
'post_name' => 'product-'.$product_id.'-variation',
'post_status' => 'publish',
'post_parent' => $product_id,
'post_type' => 'product_variation',
'guid' => $product->get_permalink()
);
foreach( $variations_data as $variation_data ){
$variation_id = wp_insert_post( $variation_post );
$variation = new WC_Product_Variation( $variation_id );
foreach($_variation_data['attributes'] as $attribute => $term_name){
$taxonomy = 'pa_'.$attribute;
if( ! taxonomy_exists( $taxonomy ) ){
register_taxonomy(
$taxonomy,
'product_variation',
array(
'hierarchical' => false,
'label' => ucfirst($attribute),
'query_var' => true,
'rewrite' => array( 'slug' => sanitize_title($attribute)),
)
);
}
if( ! term_exists( $term_name, $taxonomy ) )
wp_insert_term( $term_name, $taxonomy );
$term_slug = get_term_by('name', $term_name, $taxonomy )->slug;
$post_term_names = wp_get_post_terms( $product_id, $taxonomy, array('fields' => 'names') );
if( ! in_array( $term_name, $post_term_names ) )
wp_set_post_terms( $product_id, $term_name, $taxonomy, true );
update_post_meta( $variation_id, 'attribute_'.$taxonomy, $term_slug );
}
$variation->save();
}
}
As wp_insert_post() create a product variation in database, with a unique variation ID, so it need to be done for each variation in your data array.
This should solve your main related problem.
Related:
Create programmatically a WooCommerce product variation with new attribute values
Create programmatically a variable product and two new attributes in WooCommerce
I have a store with 8k products that I imported with a plugin made by me.
The products, the categories and the variations are all correct.
All shop is correct.
But the problem is the page of each category does not output the products until I give them to manually save one by one.
I have disabled the theme and the plugin and the same thing continues with the originals.
If I change the query manually by overriding the archive-product, all the products are seen, but the pagination and category listing remain the same.
Could it be for some meta-post?
Any solution?
Thank you very much to all.
My function to generate a basic and variant product:
$post = array(
'post_author' => 1,
'post_content' => $this->getDescription(),
'post_status' => 'publish',
'post_title' => $this->getName(),
'post_parent' => '',
'post_type' => 'product'
);
$postId = wp_insert_post($post);
$this->setId($postId);
if ($this->getId()) {
update_post_meta($this->getId(), '_sku', $this->getSku());
update_post_meta($this->getId(), '_visibility', 'visible');
wp_set_object_terms($postId, $this->getCategories(), 'product_cat');
$this->getImageXML();
update_post_meta($this->getId(), '_price', $this->price);
update_post_meta($this->getId(), '_regular_price', $this->price);
wp_set_object_terms($this->getId(), $this->getType(), 'product_type', false);
if ($this->getType() == 'simple') {
update_post_meta($this->getId(), '_manage_stock', 'yes');
update_post_meta($this->getId(), '_stock', $this->getStock());
} else {
$talla = wc_attribute_taxonomy_name('Größe');
$attributes = array(
$talla => array(
'name' => $talla,
'value' => '',
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '1'
)
);
wp_set_object_terms($this->getId(), $this->getAtributos(), $talla);
update_post_meta($this->getId(), '_product_attributes', $attributes);
foreach ($this->getVariants() as $key => $variant) {
$variation = array(
'post_title' => 'Product #' . $this->getId() . ' Variation',
'post_content' => '',
'post_status' => 'publish',
'post_parent' => $this->getId(),
'post_type' => 'product_variation'
);
$variationId = wp_insert_post($variation);
update_post_meta($variationId, '_sku', $variant['ean']);
update_post_meta($variationId, '_regular_price', $this->price);
update_post_meta($variationId, '_price', $this->price);
update_post_meta($variationId, '_manage_stock', 'yes');
update_post_meta($variationId, '_stock', $variant['stock']);
if ($variant['stock'] > 0) {
update_post_meta($variationId, '_stock_status', 'instock');
} else {
update_post_meta($variationId, '_stock_status', 'outofstock');
}
update_post_meta($variationId, 'attribute_' . $talla, strtolower(str_replace('/', '', $variant['talla'])));
}
WC_Product_Variable::sync($this->getId());
WC_Product_Variable::sync_attributes($this->getId());
}
}
I found the solution to my problem:
Add this two meta_tags to product:
update_post_meta($yourID, 'total_sales', 0);
update_post_meta($yourID, '_stock_status', 'instock');
or
update_post_meta($yourID, 'total_sales', 0);
update_post_meta($yourID, '_stock_status', 'outofstock');
In my case total_sale is 0 because they are new products.
When I execute the code below, there will be added a product to WooCommerce Products with variations of the attributes 'pa_size' and 'pa_color' after I pushed a button.
When I preview the product, everything works fine.
However, when I'm going to edit and save that product, there are no attributes existing. On top of that, the variations disappear when I'm saving the product again.
I've searched the internet for at least three days, so if someone knows a proper solution I would be grateful.
Code:
class Product {
function __construct () {
// In a class constructor
$this->size_tax = wc_attribute_taxonomy_name( 'Size' );
$this->color_tax = wc_attribute_taxonomy_name( 'Color' );
}
function addProduct() {
// Insert the main product first
// It will be used as a parent for other variations (think of it as a container)
$product_id = wp_insert_post( array(
'post_title' => "Product Example",
'post_content' => "Product post content goes here...",
'post_status' => "publish",
'post_excerpt' => "This is the description",
'post_name' => "test_prod_vars2", //name/slug
'post_type' => "product"
) );
// Insert the attributes (I will be using size and color for variations)
$attributes = array(
$this->size_tax => array(
'name' => $this->size_tax,
'value' =>'',
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '1'
),
$this->color_tax => array(
'name' => $this->color_tax,
'value' => '',
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '1'
)
);
update_post_meta( $product_id, '_product_attributes', $attributes );
// Assign sizes and colors to the main product
// Set product type as variable
wp_set_object_terms( $product_id, 'variable', 'product_type', false );
// Start creating variations
$sizes = array('small', 'medium', 'large');
$prices = array('5', '10', '15');
$colors = array('red', 'white', 'blue');
for($i=0; $i<count($sizes); $i++) {
for($j=0; $j<count($colors); $j++) {
$parent_id = $product_id;
$variation = array(
'post_title' => 'Product #' . $parent_id . ' Variation',
'post_content' => '',
'post_status' => 'publish',
'post_parent' => $parent_id,
'post_type' => 'product_variation'
);
// The variation id
$variation_id = wp_insert_post( $variation );
update_post_meta( $variation_id, '_price', $prices[$i] );
// Assign the size and color of this variation
update_post_meta( $variation_id, 'attribute_' . $this->size_tax, $sizes[$i] );
update_post_meta( $variation_id, 'attribute_' . $this->color_tax, $colors[$j] );
// Update parent if variable so price sorting works and stays in sync with the cheapest child
WC_Product_Variable::sync( $parent_id );
}
}
}
}
if(isset($_POST['button'])) {
$product = new Product;
$product->addProduct();
}
If your attribute
'is_taxonomy' => '1'
then you have to insert taxonomy slug instead of text based value.
Try 'is_taxonomy' => '0' as a fast check.
add_action( 'init', 'add_product_to_cart' );
function add_product_to_cart() {
if ( isset($_POST['mix']) && !empty($_POST['mix']) && isset($_POST['mix_name']) && !empty($_POST['mix_name']) ) {
global $woocommerce;
$mix_name = $_POST['mix_name'];
$my_post = array(
'post_title' => $mix_name,
'post_content' => 'A mix by Customer',
'post_status' => 'publish',
'post_author' => 1,
'post_type' =>'product'
);
// Insert the post into the database
$product_ID = wp_insert_post( $my_post );
$term = get_term_by('name', 'Mix', 'product_cat');
wp_set_object_terms($product_ID, $term->term_id, 'product_cat');//set category for this product
// Set product type as variable
wp_set_object_terms( $product_ID, 'variable', 'product_type' , false);
$attributes = array(
'strain'=>array(
'name'=>'strain',
'value'=>'',
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '1'),
'level'=>array(
'name' => 'level',
'value' => '',
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '1'
)
);
update_post_meta( $product_ID, '_product_attributes', $attributes );
// Assign sizes and colors to the main product
wp_set_object_terms( $product_ID, array( 'black berry kush', 'la confidential' ), 'strain' );
wp_set_object_terms( $product_ID, array( 'thc 30%', 'thc 20%' ) , 'level' );
// Start creating variations
// The variation is simply a post
// with the main product set as its parent
// you might want to put that in a loop or something
// to create multiple variations with multiple values
$parent_id = $product_ID;
$variation = array(
'post_title' => 'Product #' . $parent_id . ' Variation',
'post_content' => '',
'post_status' => 'publish',
'post_parent' => $parent_id,
'post_type' => 'product_variation'
);
// The variation id
$variation_id = wp_insert_post( $variation );
if ( $product_ID ){
add_post_meta($product_ID, '_regular_price', 100 );
add_post_meta($product_ID, '_price', 100 );
add_post_meta($product_ID, '_stock_status', 'instock' );
// Assign the size and color of this variation
update_post_meta( $variation_id, 'attribute_strain', 'black berry kush' );
update_post_meta( $variation_id, 'attribute_level', 'thc 20%' );
update_post_meta( $variation_id, '_regular_price', 100 );
update_post_meta( $variation_id, '_price', 100 );
update_post_meta($variation_id, '_stock_status', 'instock' );
update_post_meta($variation_id, '_visibility', 'visible' );
//Getting error on this line.
$addcart = $woocommerce->cart->add_to_cart( $product_ID, $variation_id, $quantity=1 );
if($addcart) {
wp_safe_redirect( WC()->cart->get_checkout_url() );
exit;
} else {
wc_print_notices();
_e('Can\'t add');
}
}
}
}
I create a function to create a variation product to add to the cart when The button is clicked. I don't know what wrong with the code but it's said
Sorry, this product cannot be purchased.
If add to cart for with only $product_ID, it's successful but when it is with $variation_ID, it return false. Can someone tell me how to set the attribute for the variation product.
Thanks a lot