Question

I've this in my main plugin file:

$main_admin_class = new MainAdminClass();
$main_admin_class->init();

MainAdminClass has this code:

class MainAdminClass {
    public function init() {
        $child_admin = new ChildAdminClass();
        $child_admin->init();
    }
}

and, finally, the child class has this code

class ChildAdminClass {
    public function init() {
        add_action('admin_notices', array($this, 'printFoo'));
        //I know it works if I use 'ChildAdminClass' instead of $this
    }

    public function printFoo() {
        echo 'fooooooooooooooooooooooooooooo';
    }
}

When later I try to use remove_action in functions.php, with this code:

global $child_admin;
remove_action('admin_notices', array($child_admin, 'printFoo'));

It doesn't works, unless I call the method statically.

I'm aware that it works if I use the add_action in the MainAdminClass instead of the child, but I would like to know if it is possible to make this works.

Was it helpful?

Solution

You can't. Not how you've written it. You need to be able to access the instance of ChildAdminClass somehow, but it only exists within the MainAdminClass class and isn't exposed in any way.

In your code attempting to remove it you've referenced $child_admin as a global variable, but you didn't create it as a global variable. If you did this:

public function init() {
    global $child_admin;

    $child_admin = new ChildAdminClass();
    $child_admin->init();
}

Now this would work:

global $child_admin;
remove_action('admin_notices', array($child_admin, 'printFoo'));

But global variables aren't great. A better way to do this might be to store a reference to the instance of the child class as property on the main class:

class MainAdminClass {
    public $child_admin;

    public function init() {
        $this->child_admin = new ChildAdminClass();
        $this->child_admin->init();
    }
}

If you do it that way you can remove it like this:

remove_action('admin_notices', array($main_admin_class->child_admin, 'printFoo'));

That's assuming that $main_admin_class is available in whichever scope you're using this code in. This gets to the main issue: To remove an action from a class instance, you need to pass that exact instance. So this all comes down to variable scope and making sure that the class instances are accessible so that they can be used to remove hooks. Ultimately that's a pure PHP issue, rather than anything specific to WordPress.

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top