Ferex
Ferex

Reputation: 575

Empty $woocommerce global variable (WC() works instead)

I have this code:

add_action('woocommerce_init', 'on_woocommerce');

function on_woocommerce(){
    function log_cart(){
        global $woocommerce;
        $cart_content = $woocommerce->cart->get_cart();
        log_debug($cart_content,'$cart_content');
    }
    if(HLP_DEBUG){
        log_cart();
    }
}  

But it gives me error because $woocommerce is null.

Instead if I use this:

add_action('woocommerce_init', 'on_woocommerce');

function on_woocommerce(){
    function log_cart(){
       $cart_content = WC()->cart->get_cart();
       log_debug($cart_content,'$cart_content');
    }
    if(HLP_DEBUG){
        log_cart();
    }
}

Everything it's right and working.

The code is inside another function executed on woocommerce_init HOOK. For what is my knowledge both should work.

Could you explain why the first one doesn't?

Upvotes: 0

Views: 9315

Answers (1)

chugadie
chugadie

Reputation: 2883

The behavior you describe is possible if you hook onto "woocommerce_loaded", but it is not possible if you hook onto "woocommerce_init".

The last line of wp-content/plugins/woocommerce/woocommerce.php is

// Global for backwards compatibility.
$GLOBALS['woocommerce'] = WC();

This suggests that using global $woocommerce is deprecated.

The last line is global code, that runs after the file is included. So, during the creation of the class WC the constructor gets run.

    /**
     * WooCommerce Constructor.
     */
    public function __construct() {
            $this->define_constants();
            $this->includes();
            $this->init_hooks();

            do_action( 'woocommerce_loaded' );
    }

init_hooks() adds WC's init function to the higher WP init action. Then the woocommerce_loaded action is fired. This is fired before the constructor completes, and before the object is added to the globals array.

After the woocommerce_loaded action is done, the constructor returns, and the WC object is added to the globals. There is no way WP's init action can be fired, and woocommerce is hooked into it, without the global being available.

This is for WC 2.5.5, I have checked the source code back to 2.3.0, other versions may be different.

You may have a rogue plugin or theme that is calling woocomerce_init before the WC() object is made, or before it returns (i.e. on the woocommerce_loaded action).

The only real explanation is that your function on_woocommerce() is being called from another hook or in another way accidentally. There is no way that the global function WC() could be defined, but the very next line of source code hasn't executed (which is store the result of WC() in a global variable).

Upvotes: 3

Related Questions