it’s caused by the fact that filters / actions are run outside the class; to be precise in the place where corresponding apply_filters, do_action calls have been specified.
But it does work perfectly when I use normal function call instead of closure. I apply action callback to function_x()
which applies filter callback to function_y()
and it works. It only doesn’t work when I don’t use callback to function_x()
and apply filter callback to function_y()
in action callback with a closure. That’s what I have written in the first post:
class Some_plugin {
public function __construct(){
add_action('admin_bar_menu', array($this, 'some_unnecessary_function'), 0);
}
public function some_unnecessary_function(){
add_filter('get_avatar', array($this, 'some_function'), 10);
}
public function some_function(){
//do something
}
}
$some_plugin = new Some_plugin();
some_unnecessary_function()
represents aforementioned function_x()
, and some_function()
is function_y()
. This solution works perfectly. The problem is that I don’t want to define some_unnecessary_function()
just for the sake of defining it so I can callback to it later on. I want to use closure in __construct()
in add_action()
. And I can’t do that, because I can’t create array with $this
and anonymous function, just like I can create array with $this
and a function name.
So the scope is not a direct problem here. The problem is that I cannot correctly specify the scope when using closures to WP hooks. I can do it easily when I use callback to another method, but I cannot do it when I use closure.
Does the method described above by you work at all?
Not at all, it was more of a pseudo-code. Just how I would imagine it working. Just like we use array($this, 'function_name')
, it would make sense to use array($this, function(){})
to represent the same thing, only without the need to define function_name()
just for the sake of defining it to callback to it later.
EDIT:
Okay, after finishing this post I realised that you were right all along and it makes sense. And it IS all about the scope and closures are not to blame here, it’s all because of the place where this closure is located. It’s still very, very blurry to me, though. I’ve used to think of closures as a String, for example, whereas the function definition and its content as a variable with this String (or any other data type) assigned to it. So we can do this:
some_random_function('text');
But we can also do this:
$some_string = 'text';
some_random_function($some_string);
Technically, it does not matter which option we choose, the effect will be the same (except for minor performance difference). This is how I used to think about using WP hooks with function names or with closures – we can define the function and callback to it in the hook, or we can callback directly to a closure, which would result in the same thing, just without having the function defined separately. But I begin to understand that this is not the same, right? So when we use hook, like: add_action('some_hook', array($this, 'foo')
, we are actually passing the object we want to use the method with (hence $this
– cause we want to use it with current object) and running its foo()
method? But I still can’t get my head around why it is not possible with closures! If anonymous function was used instead of ‘foo’, we should also be able to pass current object and use anonymous function within the scope of this object. I don’t get it ??
Sorry for such a long post, the more I think about it the less I know…