How can i get product visibility in WooCommerce loop? - php

How can i get the value of a product visibility ?
I would like to set a conditional display in a loop, based on product visibility if hidden.
Something like :
if($my_product is hidden) {
}

You can simply use the WC_Product method is_visible() on the WC_Product Object like:
global $product;
// Be sure to get the WC_Product instance object
if( ! is_a( $product, 'WC_Product' ) ) {
$product = wc_get_product( get_the_id() );
}
// Check product visibility
if( ! $product->is_visible() ) {
// Not visible
} else {
// Visible
}
It should work.

Related

Custom function that get product reviews count in WooCommerce

I'm trying to make a function that get the count of product reviews in WooCommerce product page.
I need to use it in another function in a logical operation ... Can't figure out whats wrong.
function reviews_count() {
$id = $product->get_id();
$product = wc_get_product($id);
$count = $product->get_review_count();
return $count;
}
Try the following instead (for single product_pages):
function reviews_count() {
global $product;
if ( ! is_a( $product, 'WC_Product' ) ) {
$product = wc_get_product( get_the_ID() );
}
return $product->get_review_count();
}
Or you can also add the product Id as function argument (to use it in another function) like:
function reviews_count( $product_id ) {
$product = wc_get_product( $product_id );
return $product->get_review_count();
}
So in your other function, you will be able to pass the product Id a bit like:
function my_other_function() {
global $product;
$count = reviews_count( $product->get_id() );
}

How to check if a WooCommerce product is from a custom product type?

I need to create a conditional to hide a specific part of my product page template if the product is a Gift Card type.
I tried something like this but it returning FALSE
$temp_product = wc_get_product( $product->get_id() );
var_dump( is_a( $temp_product, 'WC_Product_PW_Gift_Card' ) );
How it is possible to do get the type of product (Gift card or not)?
EDIT: I am using woocommerce gift Card plugin.
You can try to check the product type with the WC_Product get_type() method.
Try to use (where "product_type" need to be replaced with your Gift card product type slug):
global $product; // If needed (optional)
if ( ! is_a( $product, 'WC_Product' ) ) {
$product = wc_get_product( get_the_ID() );
}
if ( method_exist( $product, 'get_type' ) && $product_get_type() === 'product_type' ) {
var_dump($product); // Gift card product
}
It could work.
Now to get the product object from cart items you will use $cart_item['data'] , and on orders items you will use $item->get_product().
I got the solution for my problem so I am posting it here, hope this will help others.
public static function is_gift_card( $product ) {
if ( ! is_a( $product, 'WC_Product' ) ) {
return false;
}
if ( $product->is_type( 'variation' ) ) {
$product = wc_get_product( $product->get_parent_id() );
}
return $product->meta_exists( '_gift_card' ) && 'yes' === $product->get_meta( '_gift_card', true );
}

How to get the WC_Product object in woocommerce_after_main_content

I have a function that outputs text after the main_content action hook in WordPress, but Woocommerce is telling me that I have an CRITICAL Uncaught Error: Call to a member function get_id() on null in .../function.php.
I've tried passing in the global $product, and checking if it is a product before running the function. The function seems to work fine, but I'm just trying to get rid of the fatal errors.
Is there something obvious I'm missing?
Here's my function:
add_action('woocommerce_after_main_content', 'display_prewired_notes');
function display_prewired_notes() {
global $product; //Tried global variable
$product_id = $product->get_id(); //getting ID
$product_name = $product->get_name(); //get name
if (is_product() && has_term('prewired-pickguard', 'product_cat', $product_id)) { ?>
//My HTML here
<?php
}
if (is_product() && $product_id == 6599) { ?>
//More HTML for this specific product
<?php
}
};
Edit:
I've tried a few things based on #Martin 's suggestions, and I still can't get this to work.
I've tried:
1:
<?php
global $product
function display_prewired_notes($product) { // Pass it in
$product_id = $product->get_id(); //getting ID
$product_name = $product->get_name(); //get name
And I get atal error: Uncaught Error: Call to a member function get_id() on string
2:
Removing the global $product entirely, I get:
Uncaught Error: Call to a member function get_id() on null
3:
Removing the global $product and keeping the $product as a parameter: Fatal error: Uncaught Error: Call to a member function get_id() on string
The hook woocommerce_after_main_content is mainly used in 2 WooCommerce templates:
templates/archive-product.php (WooCommerce archive pages)
templates/single-product.php (WooCommerce single product pages)
So you can only get the WC_Product Object from single product pages and you need to target first single product pages using the conditional tag is_product() where you will be able to get the WC_product Object this way:
add_action( 'woocommerce_after_main_content', 'display_prewired_notes' );
function display_prewired_notes() {
// Targeting single product pages (before)
if ( ! is_product() ) return; // exit
global $product;
// To be sure, If we don't get the product object
if( ! is_a($product, 'WC_Product') ) {
// Try to get an instance of the WC_Product object from Post id
$product = wc_get_product( get_the_id() );
}
$product_name = $product->get_name(); //get product name
if ( has_term(array('prewired-pickguard'), 'product_cat', $product->get_id() ) ) {
?>
<!-- My HTML here -->
<?php
}
if ( $product->get_id() == 6599 ) {
?>
<!-- More HTML for this specific product -->
<?php
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
On archive pages as it's a loop of products, it's not possible to get a product Id or/and the WC_Product Object…

Get and use the product type in WooCommerce

I'm working on a project and I'm stuck in getting Woocommerce product types as 'simple', 'variable', 'grouped' or 'external'...
What I want to achieve:
On the Thank you page, where it says "Thank you. Your order has been received.".
I want to show a particular text there if product is 'simple' and another text is product is variable or grouped or external, so something like:
if (product->get_type() == 'simple') {// (for simple product)
//show a text
}else {// (for variable, grouped and external product)
//show another text
}
I have been able to use this:
function custome_tank_you_text($order_id) {
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product = wc_get_product( $item['product_id'] );
$product->get_type();
}
if( $product == 'simple'){ ?>
<p class="woocommerce-notice woocommerce-notice--success woocommerce-thankyou-order-received"><?php echo apply_filters( 'woocommerce_thankyou_order_received_text', __( 'Thank you for topping up your wallet. It has been updated!', 'woocommerce' ), $order ); ?></p>
<?php
} else {?>
<p class="woocommerce-notice woocommerce-notice--success woocommerce-thankyou-order-received"><?php echo apply_filters( 'woocommerce_thankyou_order_received_text', __( 'Thank you. Your order has been received!', 'woocommerce' ), $order ); ?></p>
<?php
}
}
add_shortcode('thank-u-msg', 'custome_tank_you_text');
But this will only echo the Else statement.
Is there something I'm doing wrong?
Updated:
For the product type, you can use the following WC_Product methods:
To get the product type you will use get_type() method
To check the product type inside an IF statement you will use is_type() method
See at the end of this answer how to get the WC_Product object instance.
Now since WooCommerce 3 your code is a bit outdated and with some errors… Also remember that an order can have many items, so it's needed to break the loop (keeping the first item). You can use directly the dedicated filter hook woocommerce_thankyou_order_received_text this way:
add_filter( 'woocommerce_thankyou_order_received_text', 'custom_thankyou_order_received_text', 20, 2 );
function custom_thankyou_order_received_text( $thankyou_text, $order ){
// Loop through order items
foreach ( $order->get_items() as $item ) {
// Get an instance of the WC_Product Object from the WC_Order_Item_Product
$product = $item->get_product();
if( $product->is_type('simple') ){
$thankyou_text = __( 'Thank you for topping up your wallet. It has been updated!', 'woocommerce' );
} else {
$thankyou_text = __( 'Thank you. Your order has been received!', 'woocommerce' );
}
break; // We stop the loop and keep the first item
}
return $thankyou_text;
}
Code goes in function.php file of your active child theme (or active theme). tested and works.
Related: Get Order items and WC_Order_Item_Product in WooCommerce 3
ADDITION - How to get the WC_Product object (to use is_type() or get_type() methods)
Sometimes you can't get the product type globally… as it depends on the WC_Product object.
1) From a dynamic product id variable (when you doesn't have the $product object:
$product = wc_get_product( $product_id );
or
$product = wc_get_product( get_the_id() );
2) From $product global variable on single product pages (and on product archive pages inside the loop):
global $product;
// Check that WC_Product instance $product variable is defined and accessible
if ( ! is_a( $product, 'WC_Product' ) ) {
$product = wc_get_product( get_the_id() );
3) In cart items:
// Loop throught cart items
foreach( WC()->cart->get_cart() as $cart_item ){
$product = $cart_item['data'];
}
3) In order items:
// Loop through order items
foreach ( $order->get_items() as $item ) {
$product = $item->get_product();
}

Display product data with custom shortcodes in Woocommerce single product pages

In Woocommerce, I use 3 different shortcode functions that are displaying:
The product categories list,
The product SKU
Values for a specific attribute.
My 3 function looks like this:
function display_woo_sku() {
global $product;
return $product->get_sku();
}
add_shortcode( 'woo_sku', 'display_woo_sku' );
function display_woo_farve() {
global $product;
return $product->get_attribute( 'farve' );
}
add_shortcode( 'woo_farve', 'display_woo_farve' );
function display_woo_style() {
global $post, $product;
$categ = $product->get_categories();
return $categ;
}
add_shortcode( 'woo_style', 'display_woo_style' );
This actually works, but throws errors when updating products and make issues with Facebook Pixel add ons.
I can't see What is wrong with my code, but there must be something wrong since it conflicting with plugins and third party pixel tools.
Any help is appreciated.
Your code is making some errors for many reasons… Try this instead:
function display_woo_sku() {
if( ! is_admin() && ! is_product() ) return;
global $post;
// Get an instance of the WC_Product Object
$product = wc_get_product( $post->ID );
return $product->get_sku();
}
add_shortcode( 'woo_sku', 'display_woo_sku' );
function display_woo_attr_farve() {
if( ! is_admin() && ! is_product() ) return;
global $post;
// Get an instance of the WC_Product Object
$product = wc_get_product( $post->ID );
return $product->get_attribute( 'farve' );
}
add_shortcode( 'woo_farve', 'display_woo_attr_farve' );
function display_woo_cats() {
if( ! is_admin() && ! is_product() ) return;
global $post;
// $categ = $product->get_categories(); // <== <== <== <== IS DEPRECATED
return wc_get_product_category_list( $post->ID );
}
add_shortcode( 'woo_cats', 'display_woo_cats' );
This code goes on function.php file of your active child theme (or theme). Tested and works.
It should solve your issue…

Categories