admin管理员组文章数量:1316004
I'd like themes to be able to alter a default array of data inside a plugin class. It's currently set up like:
namespace Example;
class Example_Class {
private $stuff;
public function __construct() {
$this->stuff = $this->set_stuff();
}
public function set_stuff() {
$things = array(
'first' => 'First',
'second' => 'Second',
);
return apply_filters( 'my_cool_filter', $things );
}
}
Then to test it I put this in the theme's functions.php:
function change_things( $things ) {
$things = array(
'third' => 'Third',
'fourth' => 'Fourth',
);
return $things;
}
add_filter( 'my_cool_filter', 'change_things' );
However it's not working. The $stuff
property is still getting set as the original default array, so add_filter()
isn't having any effect. It would seem to be the same question as this, but I can't see what I'm doing wrong.
EDIT:
The class is in a plugin and instantiated as part of the plugin loading - called from the main plugin file. The methods in the class manage settings and the main one that uses the property is hooked to admin_init
, but if I add die( var_dump( $this->stuff ) )
inside the constructor just after it's set, I get the original array instead of the filtered array. I think it's clear from what everyone is saying that it must be an issue of things happening in the wrong order, but don't plugins always load before the theme?
I'd like themes to be able to alter a default array of data inside a plugin class. It's currently set up like:
namespace Example;
class Example_Class {
private $stuff;
public function __construct() {
$this->stuff = $this->set_stuff();
}
public function set_stuff() {
$things = array(
'first' => 'First',
'second' => 'Second',
);
return apply_filters( 'my_cool_filter', $things );
}
}
Then to test it I put this in the theme's functions.php:
function change_things( $things ) {
$things = array(
'third' => 'Third',
'fourth' => 'Fourth',
);
return $things;
}
add_filter( 'my_cool_filter', 'change_things' );
However it's not working. The $stuff
property is still getting set as the original default array, so add_filter()
isn't having any effect. It would seem to be the same question as this, but I can't see what I'm doing wrong.
EDIT:
The class is in a plugin and instantiated as part of the plugin loading - called from the main plugin file. The methods in the class manage settings and the main one that uses the property is hooked to admin_init
, but if I add die( var_dump( $this->stuff ) )
inside the constructor just after it's set, I get the original array instead of the filtered array. I think it's clear from what everyone is saying that it must be an issue of things happening in the wrong order, but don't plugins always load before the theme?
1 Answer
Reset to default 0Your code is good — you are using both apply_filters()
and add_filter()
correctly.
But the timing/hook does not seem correct.
I think it's clear from what everyone is saying that it must be an issue of things happening in the wrong order, but don't plugins always load before the theme?
Wrong order: Yes — you most likely called
apply_filters()
before the filter (change_things()
) is added (viaadd_filter()
) or that you instantiated the classExample_Class
in the wrong place/hook (i.e. instantiated too early).Don't plugins always load before the theme? Yes they do, therefore you need to ensure your filter is added on-time — and the earliest hook you'd use to ensure your code runs after the theme is loaded would be
after_setup_theme
:/** * Fires after the theme is loaded. * * @since 3.0.0 */ do_action( 'after_setup_theme' );
See this Codex article for a list of the hooks and their order of execution on a WordPress page, both admin and non-admin sides, but for an up-to-date list, try Query Monitor or the other options here.
So for example, if you instantiated the class in plugins_loaded
, then the property Example_Class::$stuff
would not be filtered by the change_things()
.
And here are two examples demonstrating how should and should not the class be instantiated:
On-time/good instantiation —
admin_init
runs afterafter_setup_theme
:// In main plugin file: // Note: I used closure merely for testing purposes. add_action( 'admin_init', function () { require_once '/path/to/class-example-class.php'; new Example\Example_Class; // the $this->stuff in the class would now be the $things returned by // change_things() } );
And as you may have guessed it, you can use
after_setup_theme
in place of theadmin_init
. But in most plugins, they initialize things via theinit
hook which runs after WordPress setups things like the theme and current user:/** * Fires after WordPress has finished loading but before any headers are sent. * * Most of WP is loaded at this stage, and the user is authenticated. WP continues * to load on the {@see 'init'} hook that follows (e.g. widgets), and many plugins instantiate * themselves on it for all sorts of reasons (e.g. they need a user, a taxonomy, etc.). * * If you wish to plug an action once WP is loaded, use the {@see 'wp_loaded'} hook below. * * @since 1.5.0 */ do_action( 'init' );
Too-early instantiation —
plugins_loaded
runs beforeafter_setup_theme
:// In main plugin file: add_action( 'plugins_loaded', function () { require_once '/path/to/class-example-class.php'; new Example\Example_Class; // change_things() was not executed } );
本文标签: phpHow to use applyfilters() inside a plugin class
版权声明:本文标题:php - How to use apply_filters() inside a plugin class? 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741994348a2409738.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
new Example\Example_Class
)? – Sally CJ Commented Nov 12, 2020 at 15:09apply_filters
is being used correctly. However, we have no information about how your class is being created, when it's being created, where it's being created, or how you tested thestuff
variable, can you edit your question and include that information? – Tom J Nowell ♦ Commented Nov 12, 2020 at 17:23do_action
must be happening before theapply_filters
but I'm not sure how to check that. Would it throw an error if I enable wp_debug? – Shoelaced Commented Nov 12, 2020 at 22:25