Удаление хуков в WordPress: методы и примеры

Удаление хуков в WordPress (действий и фильтров)

Для удаления хука вам необходимо изменить исходный код и удалить вызов хука, что обычно невозможно, так как хуки находятся в ядре системы или в плагине. В этой статье мы поговорим о том, как удалять функции обратного вызова, привязанные к хукам.

Чтобы удалить функцию, связанную с фильтром или действием, используются следующие функции:

  • remove_action()
  • remove_filter()

Это идентичные функции, которые удаляют хук независимо от того, является ли он фильтром или действием. Тем не менее, для ясности кода лучше использовать remove_filter() для фильтров и remove_action() для действий.

Для удаления хука вам нужно знать:

  1. Имя хука, например, wp_footer.
  2. Имя функции, связанной с хуком, например, my_action_function.
  3. Приоритет выполнения хука, если он был установлен при создании хука. Если приоритет не установлен, он равен 10, и его не нужно указывать при удалении.

Если вам нужно удалить хук с приоритетом, отличным от 10, и вы его не указали, хук НЕ будет удален!

Оглавление

Пример удаления хука

Предположим, где-то в плагине функция 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!

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *