I want to know if it is possible to get all variations from a product - both available variations and unavailable variations. For example if a variation doesn't have a price set, it will be marked as unavailable.
When I call $product->get_available_variations() it only returns the available variations. Any way to get unavailable variations as well?
To get all variations of a product you can make an API call using the wc_get_product() function to get the product object and then use the get_available_variations() method to get the available variations or the get_children() method to get all variations, both available and unavailable.
Here is an example of how this can be done:
<?php
require_once( 'path/to/woocommerce/woocommerce.php' );
$product_id = 1234; // ID of the product
$product = wc_get_product( $product_id );
$variations = $product->get_children();
foreach ( $variations as $variation_id ) {
$variation = wc_get_product( $variation_id );
if ( $variation->is_in_stock() && $variation->is_purchasable() ) {
// Available variation
} else {
// Unavailable variation
}
}
This will retrieve all variations for the product with the specified ID, and loop through each one, checking if it is in stock and purchasable, marking as available or unavailable accordingly.
Solved:
I managed to get all variation ids by calling $product->get_children()
Related
I am trying to get the product categories for the woocommerce order item at woocommerce_checkout_create_order_line_item hook.
I am able to successfully get the product_id (thanks to help I got here) but now trying to get the product's categories the array comes back empty trying $product->get_categories() and alternatively trying wc_get_product_category_list($product->get_id().
I can't figure out what I am doing wrong.
add_action('woocommerce_checkout_create_order_line_item',
'add_order_item_custom_meta', 10, 4 );
function add_order_item_custom_meta( $item, $cart_item_key, $cart_item, $order ) {
$product = $item->get_product(); // The WC_Product instance Object
$cat_names = $product->get_categories(); // one attempt
$cat_names = wc_get_product_category_list($product->get_id()); // another attempt
$arrlength = count($cat_names);
for($x = 0; $x<$arrlength; $x++) {
$cat_name = $cat_names[$x];
}
$item->update_meta_data( '_raw_product_id', $product->get_id() );
$item->update_meta_data( '_raw_product_name', $cat_name );
}
So the add_action and the function work. The "$product=..." works and I can use it below in the 2nd to the last line of code as $product->get_id() and the correct value is stored as metadata as desired.
So since $product->get_id() works I thought it logical that $product->get_categories() would work. But it returns a null array.
I then read somewhere that it was deprecated and I should use wc_get_product_category_list. So I tried that and also no luck.
So I am now stuck and can't figure out what is wrong with my code. Thanks for any help.
As you mentioned get_categories() method of WC_Product class is deprecated. Instead you can use get_category_ids() method. However this method returns product category IDs, and It seems that you need category names so we can get the names from WP_Term objects.
Final code would be something like this:
add_action('woocommerce_checkout_create_order_line_item', 'add_order_item_custom_meta', 10, 4 );
function add_order_item_custom_meta($item, $cart_item_key, $cart_item, $order)
{
$product = $item->get_product(); // The WC_Product instance Object
$cat_ids = $product->get_category_ids(); // returns an array of cat IDs
$cat_names = [];
foreach ( (array) $cat_ids as $cat_id) {
$cat_term = get_term_by('id', (int)$cat_id, 'product_cat');
if($cat_term){
$cat_names[] = $cat_term->name; // You may want to get slugs by $cat_term->slug
}
}
$item->update_meta_data( '_raw_product_id', $product->get_id() );
$item->update_meta_data( '_raw_product_name', $cat_names );
}
Note: foreach loop is the preferred way of doing this kind of stuff (instead of using a for loop).
I would like to display variable products shipping class set for each variant.
I realize that I may need to have a mix of php and Javascript but I would like to get the PHP side right first.
I am guessing the best way to start is to use:
if( $product->is_type( 'simple' ) ) {
$product = wc_get_product();
$shipping_class = $product->get_shipping_class();
} elseif( $product->is_type( 'variable' ) ) {
$product = wc_get_product();
$shipping_class = $product->get_shipping_class();
}
But I am not sure how to get the product variant shipping class or if I am doing this correctly. Looking into wc_get_product_variation or variation to see if it has the answer.
Any help would be appreciated possibly display all as an array and use javascript to hide the selected.
How do I get the variant shipping class?
To get the variations shipping classes of a defined variable product Id, two ways:
1) Using wp_get_post_terms() function for product_shipping_class taxonomy:
// Get the WC_Product_Variable instance Object (if needed)
$product = wc_get_product( $product_id );
// Initializing
$shipping_classes = array();
// Loop through the visible variations IDs
foreach ( $product->get_visible_children() as $variation_id ) {
// Get the variation shipping class WP_Term object
$term = wp_get_post_terms( $variation_id, 'product_shipping_class' );
if( empty($term) ) {
// Get the parent product shipping class WP_Term object
$term = wp_get_post_terms( $product->get_id(), 'product_shipping_class' );
// Set the shipping class slug in an indexed array
$shipping_classes[$variation_id] = $term->slug;
}
}
// Raw output (for testing)
var_dump($shipping_classes);
This will give you an array of variation Id / shipping class pairs.
2) Using get_shipping_class_id() WC_Product method:
// Get the WC_Product_Variable instance Object (if needed)
$product = wc_get_product( $product_id );
// Initializing
$shipping_classes = array();
// Loop through the visible variations IDs
foreach ( $product->get_visible_children() as $variation_id ) {
// Get the Product Variation instance Object
$variation = wc_get_product($variation_id);
// Get the shipping class ID
$term_id = $variation->get_shipping_class_id();
// The shipping class WP_Term Object
$term = get_term_by('term_id', $term_id, 'product_shipping_class');
// Set the shipping class slug in an indexed array
$shipping_classes[$variation_id] = $term->slug;
}
// Raw output (for testing)
var_dump($shipping_classes);
I am trying to show the price of a product in a post by code using HTML.
I am trying to utilize $product->get_price(). however, I need to be able to call the product by identifying it, using its code or something like it.
So Basically, all I want to do is to show the price of a particular product in the post by using a product ID as reference for example.
Any idea?
If you have the product's ID you can use that to create a product object:
$_product = wc_get_product( $product_id );
Then from the object you can run any of WooCommerce's product methods.
$_product->get_regular_price();
$_product->get_sale_price();
$_product->get_price();
Hope this one helps.
you use wc_get_product function :
$_product = wc_get_product( $product_id );
$_product->get_regular_price();
$_product->get_sale_price();
$_product->get_price();
I'm building an e-commerce site. I'm having some trouble with WooCommerce Variable Product.
The "Add to Cart" button works fine with simple products, but does not work with variable products. It gives a "Please choose product options…" notice.
I looked everywhere and tried several suggestions online, none of them work. So I looked into WooCommerce source file: class-wc-form-handler.php.
In the function add_to_cart_handler_variable:
function add_to_cart_handler_variable( $product_id ) {
$adding_to_cart = wc_get_product( $product_id );
$variation_id = empty( $_REQUEST['variation_id'] ) ? '' : absint( $_REQUEST['variation_id'] );
$quantity = empty( $_REQUEST['quantity'] ) ? 1 : wc_stock_amount( $_REQUEST['quantity'] );
$missing_attributes = array();
$variations = array();
$attributes = $adding_to_cart->get_attributes();
$variation = wc_get_product( $variation_id );
...
if ( $missing_attributes ) {
wc_add_notice( sprintf( _n( '%s is a required field', '%s are required fields', sizeof( $missing_attributes ), 'woocommerce' ), wc_format_list_of_items( $missing_attributes ) ), 'error' );
} elseif ( empty( $variation_id ) ) {
wc_add_notice( __( 'Please choose product options…', 'woocommerce' ), 'error' );
} else {
// Add to cart validation
$passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations );
if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations ) !== false ) {
wc_add_to_cart_message( $product_id );
return true;
}
}
return false;
}
The error is caught in the elseif clause.
So I tried to echo out $variation_id, $variations, and $variation. None of them has anything in it because when I echo $variation_id: it doesn't output anything.
How can the error be resolved?
On shop page you can't use add-to-cart button for variable products, because you need first to go on single product page to chose the options for this variable product before adding it to cart.
On variable product pages, normally you have some displayed options to chose for a variable product, before using "add to cart" button. If you don't do it, you get the error message… So at this point:
The options are not displayed in the product page (Bad settings in your backend product page, a bug with your theme or some additional plugin):
Check your product backend settings
Try to switch to default wordpress theme (to see if this issue is still there)
Try to disable most of all plugins.
the options are displayed: So chose your options first for this product, then add to cart
If this issue is related to your theme, contact the author of your theme and open a support thread or ticket…
OUPUTTING PRODUCT VARIATIONS FOR A PRODUCT ID:
To get product variations programmatically for a variable product ID:
$product = wc_get_product( $product_id );
$product_variations = $product->get_available_variations();
echo var_dump($product_variations); // Displaying the array
Then to get the first variation ID:
$product = wc_get_product( $product_id );
$product_variations = $product->get_available_variations();
$variation_product_id = $product_variations [0]['variation_id'];
echo $variation_product_id; // Displaying the variation ID
Or to get an array of all variations ID of this product ID:
$product = wc_get_product( $product_id );
$product_variations = $product->get_available_variations();
$arr_variations_id = array();
foreach ($product_variations as $variation) {
$product_variation_id = $variation['variation_id'];
array_push( $arr_variations_id, $product_variation_id );
}
echo var_dump($arr_variations_id); // Displaying the array of variations ID
A reference : Change "Add to Cart" button to "Go to Product" in the Shop Page
Just in case anyone else is building a custom theme and encounters this issue with variations not adding to the cart as expected - you may need to check your theme is loading the /woocommerce/assets/js/frontend/add-to-cart-variation.min.js script - add the following to wherever you enqueue your scripts to manually add it:
wp_enqueue_script('wc-add-to-cart-variation');
This solved the issue for me.
While we all have variation swatches in common the error (bizarre as this sounds) lays with the theme being incompatible. To test simply switch to 2020 theme and the ordering should work. I would recommend then making 2020 suite your needs and stop using the theme where the developers take days off when woocommerce updates are rolled out! Disabling the swatches wont help as the code is already there. Good luck.
I was facing the same issue.....delete your variation swatches plugin and the problem will be solved
Had the same issue....deactivated the autoptimize plugin and the problem was solved.
Also,to know which plugin to disable, you can simply load the page or the website, inspect element or developers mode, then check the console to see the source of the error which you can then relate to the relevant plugin and then disable from your wp dashboard.
I use wishlist plugin and when I tried to add variable product to cart I have got: 'The selected product isn't a variation of Product name, please choose product options by visiting Product name.'
The problem was that my product haven't default variation. So user added to wishlist product without selected variation. So when after user tries to add this product to cart error appears.
Here is FIX: just set default variation to all cariation products!
(Manually or via code). So user COULD NOT add product with EMPTY variation. Variation will be selected by default or user changes variation by himself.
So now in wishlist we have variation selected and all works as it should. It will work on all pages, archives, wishlists etc. Good luck! ;)
you’ll need to modify the functions.php file. Simply go to wp-content/yourtheme/functions.php on your child theme. Here, we’ll show you the full code and then we’ll explain its main parts. So the full PHP script to create WooCommerce default product attributes programmatically is the following:
add_action('woocommerce_before_single_product_summary', 'quadlayers_product_default_attributes');
function quadlayers_product_default_attributes() {
global $product;
if (!count($default_attributes = get_post_meta($product->get_id(), '_default_attributes'))) {
$new_defaults = array();
$product_attributes = $product->get_attributes();
if (count($product_attributes)) {
foreach ($product_attributes as $key => $attributes) {
$values = explode(',', $product->get_attribute($key));
if (isset($values[0]) && !isset($default_attributes[$key])) {
$new_defaults[$key] = sanitize_key($values[0]);
}
}
update_post_meta($product->get_id(), '_default_attributes', $new_defaults);
}
}
}
I'm currently adding a product to the shopping cart like this:
$woocommerce->cart->add_to_cart( $product_id, $quantity );
I've noticed the add_to_cart() method actually accepts 5 parameters. See the following (taken from the WooCommerce docs):
add_to_cart( string $product_id, string $quantity = 1, integer $variation_id = '', array $variation = '', array $cart_item_data = array() )
Can someone give an example what the last 3 parameters would be used for?
$variation_id
$variation
$cart_item_data [An array containing any other cart item data for this product.]
There is some description of what these are in the method documentation but it isn't hugely explanatory:
int $variation_id
array $variation attribute values
array $cart_item_data extra cart item data we want to pass into the item
Ref: http://docs.woothemes.com/wc-apidocs/class-WC_Cart.html#_add_to_cart
For the last 3 parameters, you can use them like so:
$variation_id : This would be the specific post ID of the variation, if the product is a variation. If the product you're adding is a simple product or not a variable product, you can leave this blank or set it to 0.
$variation : When you select a variation of a variable product, this array contains what the variation attributes are and what values the customer selected.
$cart_item_data : This is an array of data that allows you to store custom data to the product in your cart. For example, if you wanted to store some meta data about the product that would be useful later on, you can add it here. It will then be available when you loop over your cart items.
Here's an example from a snippet of code I wrote for a plugin:
$gift_item = \wc_get_product($gift_item_id);
$gift_variation_id = 0;
$variation_data = [];
// The Gift is a variation, so get the variation options that are associated with this product variation.
if ($gift_item->is_type('variation')) {
$gift_variation_id = $gift_item->get_id();
$variation_data = wc_get_product_variation_attributes($gift_variation_id);
}
//Check to see if the product is already in our cart and has an item meta of being a gift item
$gift_item_hash = $cart->generate_cart_id($gift_item->get_parent_id() ?: $gift_item->get_id(), $gift_variation_id, $variation_data, [
'gift' => true
]);
if ($cart->find_product_in_cart($gift_item_hash) === false) {
// Add the Gift to our cart. Add some meta data to the item so we can change it's price at checkout.
$gift_cart_item_key = $cart->add_to_cart($gift_item_id, $new_gift_quantity, $gift_variation_id, $variation_data, ['gift' => true]);
}