How to get the WC_Product object in woocommerce_after_main_content

Viewed 1885

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

1 Answers

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…

Related