WooCommerce get product ID [duplicate] - php

I'm currently working on a WooCommerce theme and attempting to add a sidebar to the product detail page.
I've been able to get the sidebar added (specifically, this one: http://woocommerce.wp-a2z.org/oik_file/templatescontent-widget-product-php/)
Now, I'm trying to figure out how to add a class of "active" to the currently selected product and can't seem to figure it out?
In other words, how do I do something along the lines of if the current product id is equal to the product id in the sidebar add class="active" to the li?
I've made numerous searches and haven't been able to come up with anything useful, so I'm turning here.
Any help greatly appreciated!!

2017 Update - since WooCommerce 3:
global $product;
$id = $product->get_id();
Woocommerce doesn't like you accessing those variables directly. This will get rid of any warnings from woocommerce if your wp_debug is true.

If the query hasn't been modified by a plugin for some reason, you should be able to get a single product page's "id" via
global $post;
$id = $post->ID
OR
global $product;
$id = $product->id;
EDIT: As of WooCommerce 3.0 this needs to be
global $product;
$id = $product->get_id();

Since WooCommerce 2.2 you are able to simply use the wc_get_product Method. As an argument you can pass the ID or simply leave it empty if you're already in the loop.
wc_get_product()->get_id();
OR with 2 lines
$product = wc_get_product();
$id = $product->get_id();

Retrieve the ID of the current item in the WordPress Loop.
echo get_the_ID();
hence works for the product id too. #tested #woo-commerce

The correct method is:
global $product;
$id = $product->get_id();

Save the current product id before entering your loop:
$current_product = $product->id;
Then in your loop for your sidebar, use $product->id again to compare:
<li><a <? if ($product->id == $current_product) { echo "class='on'"; }?> href="<?=get_permalink();?>"><?=the_title();?></a></li>

your can query woocommerce programatically
you can even add a product to your shopping cart.
I'm sure you can figure out how to interact with woocommerce cart once you read the code.
how to interact with woocommerce cart programatically
====================================
<?php
add_action('wp_loaded', 'add_product_to_cart');
function add_product_to_cart()
{
global $wpdb;
if (!is_admin()) {
$product_id = wc_get_product_id_by_sku('L3-670115');
$found = false;
if (is_user_logged_in()) {
if (sizeof(WC()->cart->get_cart()) > 0) {
foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if ($_product->get_id() == $product_id)
WC()->cart->remove_cart_item($cart_item_key);
}
}
} else {
if (sizeof(WC()->cart->get_cart()) > 0) {
foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if ($_product->id == $product_id)
$found = true;
}
// if product not found, add it
if (!$found)
WC()->cart->add_to_cart($product_id);
} else {
// if no products in cart, add it
WC()->cart->add_to_cart($product_id);
}
}
}
}

Related

Woocommerce dynamically change price of a variable product once a specific variation is changes

I have written this to extract the product variation prices
global $product;
if ( $product->is_type('variable') ) {
function get_product_variation_price($variation_id) {
global $woocommerce;
$product = new WC_Product_Variation($variation_id);
return $product->get_price_html();
}
$product_variations = $product->get_available_variations();
$arr_variations_id = array();
foreach ($product_variations as $variation) {
$product_variation_id = $variation['variation_id'];
$product_price = get_product_variation_price($product_variation_id);
}
$amount = get_product_variation_price($product_variation_id);
} else {
$amount = str_replace(".", ",", $product->get_price());
}
What I am trying to achieve is that if the product is a variable product, the amount variable changes to what currently selected variants set price is, however, this will always get me the first variants price. How can I achieve that?
I don't see any reason to create a plugin for showing variation prices because this is the default from woocommerce. Can you share why are you creating this plugin? Does the default function not work on your site? If you are only looking to change decimals for prices, you can change these settings from currency options.

WooCommerce user email and product meta data issue [duplicate]

I'm currently working on a WooCommerce theme and attempting to add a sidebar to the product detail page.
I've been able to get the sidebar added (specifically, this one: http://woocommerce.wp-a2z.org/oik_file/templatescontent-widget-product-php/)
Now, I'm trying to figure out how to add a class of "active" to the currently selected product and can't seem to figure it out?
In other words, how do I do something along the lines of if the current product id is equal to the product id in the sidebar add class="active" to the li?
I've made numerous searches and haven't been able to come up with anything useful, so I'm turning here.
Any help greatly appreciated!!
2017 Update - since WooCommerce 3:
global $product;
$id = $product->get_id();
Woocommerce doesn't like you accessing those variables directly. This will get rid of any warnings from woocommerce if your wp_debug is true.
If the query hasn't been modified by a plugin for some reason, you should be able to get a single product page's "id" via
global $post;
$id = $post->ID
OR
global $product;
$id = $product->id;
EDIT: As of WooCommerce 3.0 this needs to be
global $product;
$id = $product->get_id();
Since WooCommerce 2.2 you are able to simply use the wc_get_product Method. As an argument you can pass the ID or simply leave it empty if you're already in the loop.
wc_get_product()->get_id();
OR with 2 lines
$product = wc_get_product();
$id = $product->get_id();
Retrieve the ID of the current item in the WordPress Loop.
echo get_the_ID();
hence works for the product id too. #tested #woo-commerce
The correct method is:
global $product;
$id = $product->get_id();
Save the current product id before entering your loop:
$current_product = $product->id;
Then in your loop for your sidebar, use $product->id again to compare:
<li><a <? if ($product->id == $current_product) { echo "class='on'"; }?> href="<?=get_permalink();?>"><?=the_title();?></a></li>
your can query woocommerce programatically
you can even add a product to your shopping cart.
I'm sure you can figure out how to interact with woocommerce cart once you read the code.
how to interact with woocommerce cart programatically
====================================
<?php
add_action('wp_loaded', 'add_product_to_cart');
function add_product_to_cart()
{
global $wpdb;
if (!is_admin()) {
$product_id = wc_get_product_id_by_sku('L3-670115');
$found = false;
if (is_user_logged_in()) {
if (sizeof(WC()->cart->get_cart()) > 0) {
foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if ($_product->get_id() == $product_id)
WC()->cart->remove_cart_item($cart_item_key);
}
}
} else {
if (sizeof(WC()->cart->get_cart()) > 0) {
foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if ($_product->id == $product_id)
$found = true;
}
// if product not found, add it
if (!$found)
WC()->cart->add_to_cart($product_id);
} else {
// if no products in cart, add it
WC()->cart->add_to_cart($product_id);
}
}
}
}

Show Message in Woocommerce Cart only for specific product variation Attribute

I am adding a custom message to the Cart page, but so that it only appears if an added product has a custom variation atribute selected.
After researching I came up to:
add_action( 'woocommerce_after_cart', 'wnd_after_cart' );
function wnd_after_cart() {
if($attribute_slug == 'no_review'){
echo '<div class="wnd_after_cart"><h4>There will be no item manual review</h4><br /> </div>';
}
}
But its not working. Does anyone know what am I doing wrong?
add_action( 'woocommerce_after_cart', 'wnd_after_cart' );
function wnd_after_cart() {
echo '<div class="wnd_after_cart"><h4>There will be no item manual review</h4><br /> </div>';
}
Works very well, but I can't get the code to display the message only IF my custom attribute is selected.
Any help is appreciated…
Edit:
I set my product Atributes (example:Shirt size, Slug:'Shirt_Size') , and their variations within this atribute (Example: S (Slug:'Size_S'), M(Slug:'Size_M'), XL(Slug:'Size_XL') )
I'm trying to display the message when a specific Attribute Variation is selected (Example: The slug for S, 'Size_S')
I'm using clothes/shirt sizes since its a more common example to help illustrate.
In case I didn't explain very well, basically the code is searching for the attribute slug that you can see here in this video at 0:23
https://www.youtube.com/watch?v=QyMuq-WkV0o
But I'm trying to make it search for the slugs of the attribute variations that can be seen at 0:35
(the attribute attributes, or attribute variations, or attribute childs, I'm not sure what to name them)
#LoicTheAztec code seems to be working very well, but it's searching for the slug of the attribute (Shirt_Size), and not for the attribute variations shown previosly.
When I set the code to find 'Shirt_size', it will disply the message, but when I set it to find 'Size_S', it stops working.
Did this make sense?
Thank you for the attention and advice once again.
There is some missing code like getting your $attribute_slug from variations in cart items:
add_action( 'woocommerce_after_cart', 'checking_variation_attributes_message' );
function checking_variation_attributes_message() {
$found = false;
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item ){
$product = $cart_item['data'];
if( ! $product->is_type('variation')){
continue; // Jump to next cart item
}
$variation_attributes = $product->get_variation_attributes();
foreach ( $variation_attributes as $variation_attribute => $term_slug ){
$attribute_slug = str_replace('attribute_pa_', '', $variation_attribute);
if( $attribute_slug == 'no_review' ){
$found = true;
break;
}
}
}
if($found){
echo '<div class="wnd_after_cart"><h4>There will be no item manual review</h4><br /> </div>';
}
}
Update: Or if you are looking for a product attribute term slug instead, use it this way:
add_action( 'woocommerce_after_cart', 'checking_variation_attributes_message' );
function checking_variation_attributes_message() {
$found = false;
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item ){
$product = $cart_item['data'];
if( ! $product->is_type('variation')){
continue; // Jump to next cart item
}
$variation_attributes = $product->get_variation_attributes();
foreach ( $variation_attributes as $variation_attribute => $term_slug ){
$attribute_slug = str_replace('attribute_pa_', '', $variation_attribute);
if( $term_slug == 'no_review' ){
$found = true;
break;
}
}
}
if($found){
echo '<div class="wnd_after_cart"><h4>There will be no item manual review</h4><br /> </div>';
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.

Get order title(s) in Woocommerce

I'm trying to get the names of the ordered products through my functions.php file with a loop. Heres's my code:
global $woocommerce;
$items = $woocommerce->cart->get_cart();
foreach($items as $item => $values) {
$_product = $values['data']->post;
}
And then i call the title like this:
$_product->post_title
This works, it returns me the name of the product I ordered. The thing is when i have 2 or more products it still returns me 1 name. How can i make it so it returns all the names in the cart.
The new syntax in woocommerce relative to cart is made with WC() without any need of calling global woocommerce;
So your code will be this:
$products_in_cart= array();
$products_post_title_in_cart = array();
$products_ids_in_cart= array();
foreach(WC()->cart->get_cart() as $cart_item) {
$products_in_cart[] = $cart_item['data']->post;
$products_post_title_in_cart[] = $cart_item['data']->post->post_title;
$products_ids_in_cart[] = $cart_item['product_id'];
}
// The first product (or item of the cart)
$_product = $products_in_cart[0]; // product post data
$product_id = $products_ids_in_cart[0]; // product ID
$products_post_title_in_cart[0] // product post title
// The Second product (or item of the cart)
$_product = $products_in_cart[1]; // product post data
$product_id = $products_ids_in_cart[1]; // product ID
$products_post_title_in_cart[1] // product post title
// etc … for all other products you increase the key of the arrays to get the correct values
<?php
global $woocommerce;
$items = $woocommerce->cart->get_cart();
$arr_product=array();
foreach($items as $item => $values) {
$arr_product[]= $_product->post_title;
}
print_r($arr_product,true); // echo print_r(); thats why get 1
?>
Try this code, Its returns all the names in the cart.
global $woocommerce;
$cart_item = $woocommerce->cart->get_cart();
echo "<pre>";
print_r($cart_item);
exit();

How to add filter or hook for "woocommerce_add_to_cart"

I want add to cart two product at the same time, one is original (current) product and second is from drop-down list
add_action('woocommerce_add_to_cart', 'custome_add_to_cart');
$cnt=2
function custome_add_to_cart() {
global $woocommerce;
$cnt = $cnt + 1;
echo $cnt."X";
echo $p_id=$_POST['assessories'];
$woocommerce->cart->add_to_cart($p_id, 1);
}
Output:-
As you can see in output image below , it adding same drop-down item many time in cart but i want only 1 quantity to add to cart. it seems that add_to_cart function run many times.
What should i do or how to add filter with passing second drop-down product as parameter to add to cart function ? so i can add this product also in cart.
This should work:
add_action('woocommerce_add_to_cart', 'custom_add_to_cart');
function custom_add_to_cart() {
global $woocommerce;
$product_id = $_POST['assessories'];
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
Based on following source: https://docs.woothemes.com/document/automatically-add-product-to-cart-on-visit/
The woocommerce "add_to_cart" functions run the hook "woocommerce_add_to_cart". So, in your code "add_to_cart" is run, which is running "woocommerce_add_to_cart" which runs your code, which runs "add_to_cart", etcetera etcetera... You created a recursive loop.
You need to find an alternative way, or stop calling $woocommerce->cart->add_to_cart($p_id, 1); in your own code.
What you might be looking for is a variable product with some attributes!
Anyway if really you want to do that then you just need the remove_action function :
add_action('woocommerce_add_to_cart', 'custome_add_to_cart');
function custome_add_to_cart() {
$p_id=$_POST['assessories'];
remove_action('woocommerce_add_to_cart', __FUNCTION__);
WC()->cart->add_to_cart( $p_id );
}
This prevents the action from looping indefinitely and is pretty simple.. So it will be added only once for that product. You might want to get the added to cart quantity and give it as a second parameter to the WC()->cart->add_to_cart function so they are both the same quantity
The __FUNCTION__ is a magic PHP tag just giving you the name of the current fucnction as a string, si if the function name is not the same it will still work
This might be old, but have you tried unsetting the assessories param after adding to cart?, this would break the loop.
function custome_add_to_cart() {
global $woocommerce;
if(isset($_POST['assessories'])){
$cnt = $cnt + 1;
echo $cnt . "X";
echo $p_id = $_POST['assessories'];
$woocommerce->cart->add_to_cart($p_id, 1);
unset($_POST['assessories']);
}
}

Categories