Удаление хуков в WordPress (действий и фильтров)
Для удаления хука вам необходимо изменить исходный код и удалить вызов хука, что обычно невозможно, так как хуки находятся в ядре системы или в плагине. В этой статье мы поговорим о том, как удалять функции обратного вызова, привязанные к хукам.
Чтобы удалить функцию, связанную с фильтром или действием, используются следующие функции:
remove_action()
remove_filter()
Это идентичные функции, которые удаляют хук независимо от того, является ли он фильтром или действием. Тем не менее, для ясности кода лучше использовать remove_filter()
для фильтров и remove_action()
для действий.
Для удаления хука вам нужно знать:
- Имя хука, например,
wp_footer
. - Имя функции, связанной с хуком, например,
my_action_function
. - Приоритет выполнения хука, если он был установлен при создании хука. Если приоритет не установлен, он равен 10, и его не нужно указывать при удалении.
Если вам нужно удалить хук с приоритетом, отличным от 10, и вы его не указали, хук НЕ будет удален!
Оглавление
- Пример удаления хука
- Другой пример удаления хука
- Удаление с учетом приоритета
- Удаление хука статического метода класса
- Удаление хука нестатического метода класса (если есть доступ к $this - экземпля��у класса)
- Удаление хука нестатического метода класса (если НЕТ доступа к $this - экземпляру класса)
- Удаление хука, добавленного анонимной функцией (closure)
Пример удаления хука
Предположим, где-то в плагине функция my_action_function
привязана к действию wp_footer
, которое выводит текст в подвале темы:
add_action( 'wp_footer', 'my_action_function' );
function my_action_function( $text ){
echo 'Это текст в подвале!';
}
В теме нам нужно удалить это действие, чтобы текст в подвале не отображался. Для этого вы можете добавить следующий код в файл functions.php
вашей темы:
remove_action( 'wp_footer', 'my_action_function' );
Важно: Хук должен быть удален после того, как он добавлен, но прежде чем будет выполнен.
Другой пример удаления хука
Демонстрация добавления и удаления хука:
// добавляем функцию к действию my_action
add_action( 'my_action', 'my_action_function' );
function my_action_function( $text ){
echo 'Привет!';
}
// создаем действие
do_action( 'my_action' ); //> Привет!
// удаляем ранее добавленное действие
remove_action( 'my_action', 'my_action_function' );
// создаем действие снова
do_action( 'my_action' ); // ничего не выведет...
Удаление с учетом приоритета
Приоритет должен соответствовать тому, который был установлен при добавлении хука.
// если добавлено так
add_filter( 'my_filter', 'function_name', 99 );
// тогда его следует удалить так
remove_filter( 'my_filter', 'function_name', 99 );
Удаление хука статического метода класса
// добавлено так
add_filter( 'my_filter', [ 'My_Class', 'static_method_name' ], 15 );
// его следует удалить так
remove_filter( 'my_filter', [ 'My_Class', 'static_method_name' ], 15 );
Удаление хука нестатического метода класса (если есть доступ к $this - экземпляру класса)
class A {
function __construct(){
add_action( 'my_action', [ $this, 'method_name' ], 15 );
}
function method_name(){
echo 'Привет!';
}
}
$class = new A(); // экземпляр
// для удаления необходимо найти переменную, в которой хранится
// экземпляр класса, в данном случае это $class
remove_action( 'my_action', [ $class, 'method_name' ], 15 );
Удаление хука нестатического метода класса (если НЕТ доступа к $this - экземпляру класса)
��евозможно удалить хук для объекта класса, к которому у вас нет доступа, используя стандартные функции WordPress. Тем не менее, вы можете сделать это с помощью следующих пользовательских функций:
callbacks ) ) {
return [];
}
$find_class_name = ltrim( $static_callback[0], '' );
$find_method_name = $static_callback[1] ?? '';
$found = [];
foreach ( $wp_hook->callbacks as $the_priority => $hooks_data ) {
foreach ( $hooks_data as $hook_data ) {
$real_callback = $hook_data['function'] ?? null;
if ( ! is_array( $real_callback ) ) {
continue;
}
[ $object, $the_method_name ] = $real_callback;
$class_name = is_object( $object ) ? get_class( $object ) : $object;
if (
$class_name !== $find_class_name ||
( $find_method_name && $the_method_name !== $find_method_name ) ||
( null !== $priority && $the_priority !== $priority )
) {
continue;
}
$found[] = [
'instance' => $object,
'method' => $the_method_name,
'priority' => $the_priority,
];
}
}
return $found;
}
Пример использования
Предположим, у нас есть следующий класс:
namespace MySpace;
class MyClass {
public function __construct() {
add_action( 'some_action_hook', [ $this, 'my_method' ], 11 );
add_filter( 'some_filter_hook', [ $this, 'my_method' ], 11 );
}
public function my_method() {
die( 'my_method вызван: ' . current_filter() );
}
}
new MySpaceMyClass();
Теперь будет невозможно удалить хуки этого класса с помощью стандартных функций WordPress, так как для удаления хука нам нужно иметь доступ к конкретному экземпляру класса, который у нас нет. Однако благодаря приведенным выше функциям мы можем сделать это, просто указав имя класса, метод и приоритет.
Удаление хука, добавленного анонимной функцией (closure)
Удалить хук, созданный с помощью анони��ной функции, не так просто. Например, следующий код не будет работать:
add_action( 'my_action', function(){ echo 'Привет!'; } );
remove_action( 'my_action', function(){ echo 'Привет!'; } ); // не работает!
Чтобы надёжно удалить хук с использованием анонимной функции, вы можете сделать это, если функция была создана в переменной и у вас есть доступ к этой переменной:
$my_func = function(){
echo 'Привет!';
};
add_action( 'my_action', $my_func );
remove_action( 'my_action', $my_func ); // Работает!
Менее надежный, но всё же способ удалить хук с анонимной функцией, когда у вас нет доступа к функции:
function remove_closure_hook( $name, $priority = 10, $accepted_args = 1 ): bool {
global $wp_filter;
if ( empty( $wp_filter[ $name ]->callbacks[ $priority ] ) ) {
return false;
}
$callbacks = &$wp_filter[ $name ]->callbacks[ $priority ];
foreach ( $callbacks as $key => $hook ) {
if ( ! ( $hook['function'] instanceof Closure ) ) {
continue;
}
if ( $hook['accepted_args'] !== $accepted_args ) {
continue;
}
unset( $callbacks[ $key ] );
return true;
}
return false;
}
Пример использования:
add_action( 'my_action', function(){
echo 'Привет!';
} );
do_action( 'my_action' ); // Привет!
remove_closure_hook( 'my_action', 10, 1 );
do_action( 'my_action' ); // (пусто)
Таким образом, мы рассмотрели, как удалить хуки в WordPress, включая сложные случаи с классами и анонимными функциями. Пользуйтесь этими методами, чтобы легко управлять поведением вашего сайта на WordPress!