alleyinteractive / wp-captain-hook
WordPress中操作私有动作/过滤器回调的工具。
v1.0.0
2024-09-09 14:47 UTC
Requires
- php: ^8.0
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-10 03:39:29 UTC
README
Captain Hook 是一个库,帮助 WordPress 开发者操作被动作和过滤器钩入的对象和方法。
关于
通常,插件会在函数作用域或全局作用域之外创建一个对象实例,然后使用该实例将方法钩入动作或过滤器。以下是一个例子
class Plugin_Main { public function __construct( protected \Logger $logger ) { add_action( 'init', [ $this, 'init' ], 1 ); add_filter( 'the_content', [ $this, 'filter_the_content' ], 99 ); } public function init() { register_post_type( 'book' ); register_taxonomy( 'genre', 'book' ); } public function filter_the_content( $content ) { if ( preg_match_all( '/\[([^\)]+)\]\((\d+)\)/', $content, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $match ) { $book = get_post( $match[2] ); if ( $book ) { $content = str_replace( $match[0], '<a href="' . get_permalink( $book ) . '">' . $match[1] . '</a>', $content ); } else { $this->logger->error( 'Book not found: ' . $match[2] ); } } } return $content; } public function get_logger() { return $this->logger; } public function set_logger( \Logger $logger ) { $this->logger = $logger; } } add_action( 'after_setup_theme', function () { new Plugin_Main( new \Logger( 'path/to/file.log' ) ); } );
如果开发者想要从 init
动作中取消钩或修改 init
方法,他们需要访问 $plugin
实例。由于实例是在创建它的匿名函数作用域之外创建的,这是不可能的。
Captain Hook 为开发者提供了一种访问和操作这些对象和方法的方法,即使它们不可从全局作用域访问。该库的功能包括
- 强制删除动作或过滤器:从钩子中删除动作或过滤器。
- 重新优先级排序动作和过滤器:更改动作或过滤器方法的优先级。
- 检索对象实例:获取钩入动作或过滤器的其他方法不可访问的对象实例。
安装
使用以下命令安装最新版本
$ composer require alleyinteractive/wp-captain-hook
基本用法
强制删除动作或过滤器
<?php use function Alley\WP\remove_action_by_force; use function Alley\WP\remove_filter_by_force; remove_action_by_force( 'init', [ '\Plugin_Main', 'init' ], 1 ); remove_filter_by_force( 'the_content', [ '\Plugin_Main', 'filter_the_content' ], 99 );
重新优先级排序动作和过滤器
<?php use function Alley\WP\reprioritize_action; use function Alley\WP\reprioritize_filter; reprioritize_action( 'init', [ '\Plugin_Main', 'init' ], 1, 10 ); reprioritize_filter( 'the_content', [ '\Plugin_Main', 'the_content' ], 99, 20 );
检索对象实例
以下是一个使用上述插件代码的虚构示例。该代码使用依赖注入将基于文件的记录器传递给 Plugin_Main
类。假设我们想要将日志记录到 Redis 而不是文件,看起来我们应该能够使用 set_logger()
方法替换依赖,然而,我们无法这样做,因为我们无法访问 Plugin_Main
的实例。下面,我们利用 get_hooked_object
获取插件实例,然后调用其上的 set_logger
方法,将文件记录器替换为 Redis 记录器。
<?php use function Alley\WP\get_hooked_object; $plugin = get_hooked_object( 'init', [ '\Plugin_Main', 'init' ], 1 ); $plugin->set_logger( new \Redis_Logger() );