35

I am trying to edit the short-description template to be different on variable (single) product pages than on simple products. the code in that page is here:

global $post;
if ( ! $post->post_excerpt )
    return;
?>
<div itemprop="description">
    <?php echo apply_filters( 'woocommerce_short_description', $post->post_excerpt ) ?>
</div>

I want to add some code to the if statement that will be something like

if post has variations, don't display short description, if simple product DO display

but I can't find any way in the code to distinguish between a regular simple product post and one that is variable (has variations). And looking through the API docs over at the Woo site (http://docs.woothemes.com/wc-apidocs/) I found nothing of that sort.

Akshat
  • 247
  • 5
  • 12
Stephen
  • 8,038
  • 6
  • 41
  • 59

5 Answers5

100

Use $product->is_type() function to check the product type. To check if the product is a variable product use:

global $product;

// $product->is_type( $type ) checks the product type, string/array $type ( 'simple', 'grouped', 'variable', 'external' ), returns boolean

if ( $product->is_type( 'variable' ) ) {}

There is also $product->get_type() function that returns the internal type of a product as a string.

Danijel
  • 12,408
  • 5
  • 38
  • 54
  • 2
    And there is another type for products named `variation` which is a single child of a variable product and its useful if you want to access or edit fields of each variation for variable products in a loop. – Mojtaba Rezaeian Dec 25 '18 at 13:22
  • @MojtabaRezaeian Does It mean that if I get the product from the line item of an order `$item->get_product()` then the type would be `variation`? – svelandiag Nov 10 '20 at 20:27
  • Downvote Fatal error: Uncaught Error: Call to a member function is_type() on null in – Dev Mar 02 '23 at 07:52
30

After much heartache, I have found the following two solutions:

In the product loop, you can use this:

 if( $product->has_child() ) { 

but for some reason in the short description on the single product page, I had to use this:

global $post;
$children = get_pages('child_of='.$post->ID);
if( count( $children ) !== 0 ) {

Hope this helps others that were struggling as I was...

Stephen
  • 8,038
  • 6
  • 41
  • 59
  • 2
    Actually, I figured out how to make the has_child tag work on the single product page as well, I needed to add a special global: `global $post, $product, $woocommerce_loop; if( $product->has_child() ) { ` – Stephen Feb 04 '14 at 01:34
  • Thank you for your solution, this has helped me too. – Ivandude Jun 26 '14 at 02:21
  • Thanks Stephen, this saved me a lot of hunting around the internet!! – seveninstl Sep 03 '15 at 19:36
9

Variable product always is based on WC_Product_Variable class. E.g. WooCommerce Subscriptions follows this approach.

So, the checking can be:

is_a( $product, 'WC_Product_Variable' )

This ensures that the type of product is variable regardless of the presence of children. And it's fast.

  • Excellent solution. Theme developers should use it or get_type depending on the situation. – Mizuho Ogino May 29 '21 at 01:11
  • 1
    Yes, and note, that get_type returns different types depend on particular derived implementation, e.g. WC_Product_Variable_Subscription::get_type() returns 'variable-subscription' and WC_Product_Variable::get_type() returns 'variable'. So to check for variability we need to compare all possible variable types that may be not so convenient and universal in general checking. – Seraphinite Solutions May 30 '21 at 12:18
2

For some reason if you have deleted your variation, the has_child() function it still turns true.

So I used the below solution

if(empty($product->get_available_variations())) {
  // Your code goes here
}
Mario Shtika
  • 1,436
  • 19
  • 31
  • Fatal error: Uncaught Error: Call to a member function get_available_variations() on null – Dev Mar 02 '23 at 07:54
  • It looks like you are not getting the product right, or your product does not exits. Maybe for testing purposes you can use `$product = wc_get_product(ENTER_A_PRODUCT_ID_IN_HERE);` – Mario Shtika Mar 03 '23 at 11:47
0

This is the solution for me, using on body_class filter:

if ( is_singular( 'product' ) ) {

    $product = wc_get_product( get_the_ID() );

    if ( $product->is_type( 'variable' ) ) {
        ...
    }

}