0

I am trying to replace a message from a function that got hooked in a constructor from a class from woocommerce.

This is what I tried to remove the message:

What I tried.

function remove_actions() {
    remove_action( 'product_cat_pre_add_form', array(   'WC_Admin_Taxonomies', 'product_cat_description' ));
}
add_action( 'plugins_loaded', 'remove_actions' );

Also instead of the first element from array ('WC_Admin_Taxonomies') I tried new WC_Admin_Taxonomies. Which returns true but it doesn't remove it because the instantiation adds the action, so it removes the current added action.

woocommerce/includes/admin/class-wc-admin-taxonomies.php - portion of interest

class WC_Admin_Taxonomies {
    public function __construct() {
        add_action( 'product_cat_pre_add_form', array( $this, 'product_cat_description' ) );
    }

    function product_cat_description() {
        echo wpautop( __( 'Old message', 'woocommerce' ) );
    }
}
new WC_Admin_Taxonomies();

This (_new->below) works fine, is adding the new message, but the code from first block (remove_action) above is not removing it, so I end up with 2 messages.

class WC_Admin_Taxonomies_new {
    public function __construct() {
        add_action( 'product_cat_pre_add_form', array( $this, 'product_cat_description_new' ) );
    }

    function product_cat_description_new() {
        echo wpautop( __( 'New Message', 'woocommerce' ) );
    }
}
new WC_Admin_Taxonomies_new();

Based on kovshenin answer I tried:

function instantiate_globals() {
    $GLOBALS['inst'] = new WC_Admin_Taxonomies;
}
add_action( 'plugins_loaded', 'instantiate_globals');
function remove_actions() {
    remove_action( 'product_cat_pre_add_form', array(   $GLOBALS['inst'], 'product_cat_description' )); // var_dump() - outputs true but still not removing it, I believe that filter is the issue.
}
add_action( 'plugins_loaded', 'remove_actions');
1

1 Answer 1

2

The thing with class methods is that unless they're static, they belong to an object. And in your case your object is:

new WC_Admin_Taxonomies_new();

Which means PHP will create the object and keep it in memory. But unfortunately, since you're not assigning this object to a variable, you have no way of referencing it later in your code.

Off the top of my head I can think of two ways to solve this:

First: globals, singletons, something you can use to keep a reference to your object for later use:

$GLOBALS['foo'] = new My_Class();
// ...

remove_action( 'action', array( $GLOBALS['foo'], 'method' ) );

Second: static methods.

class My_Class() {
    public static function init() {
        add_action( 'action', array( __CLASS__, 'method' ) );
    }

    public static function method() {
        // ...
    }
}
My_Class::init();

// ...

remove_action( 'action', array( 'My_Class', 'method' ) );

Hope this helps!

6
  • First of all, thank you for answering my question.Static methods are out of the question because the current class is a woocommerce non-static class that cannot be edited, and $GLOBALS tried with it and same thing it outputs the content instead of keeping a reference for later use. Edited question to see what I tried.
    – Adrian
    Commented Apr 4, 2015 at 14:46
  • The problem with what you tried is that new WC_Admin_Taxonomies_new(); and $foo = new WC_Admin_Taxonomies_new(); are two separate instances, and you're removing an action only from the one you're creating, but not the one created by WooCommerce. Your other option is to loop through all attached callbacks to a specific action at an earlier priority, and use get_class() to "guess". I'd rather submit a patch to WooCommerce :)
    – kovshenin
    Commented Apr 4, 2015 at 15:56
  • I see :D. Re-edited, now var_dump outputs true but still it doesn't get removed.
    – Adrian
    Commented Apr 4, 2015 at 16:32
  • It outputs true because your the action from your object is getting removed, but the action from WC's original object is not getting removed. Read my previous comment again.
    – kovshenin
    Commented Apr 4, 2015 at 16:42
  • Ahh I get it, was looking for de-instantiating, or destructor, but not getting applied.
    – Adrian
    Commented Apr 4, 2015 at 16:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.