Удаление действий из плагина в другом плагине

14 апр. 2016 г., 11:45:21
Просмотры: 22.4K
Голосов: 9

Я пытаюсь удалить два действия, которые добавляет плагин (конкретно sportspress). Действия этого плагина следующие:

add_action('sportspress_before_single_player','sportspress_output_player_details', 15);
add_action('sportspress_single_player_content','sportspress_output_player_statistics',20);

Я создал плагин и хочу удалить эти хуки, вот мой код:

<?php
/*
Plugin Name: my plugin

Description: Плагин для переопределения хуков других плагинов
Version: 0.1
Author: Company Name
Author URI: http://www.example.com/
License: GPL2
*/


add_action('plugins_loaded','remove_hooks');
function remove_hooks(){
    remove_action( 'sportspress_before_single_player', 'sportspress_output_player_details' );
    remove_action( 'sportspress_single_player_content', 'sportspress_output_player_statistics' );
}

Я искал и пробовал много разных вариантов, но не могу заставить это работать.

9
Комментарии

В WordPress нет концепции дочерних плагинов!

Sumit Sumit
14 апр. 2016 г. 11:51:29

Тогда Google мне соврал! Я обновлю заголовок

Alex Alex
14 апр. 2016 г. 11:52:06

Отлично! Теперь укажи больше деталей о контексте, в котором добавляются действия: например, в конструкторе класса, напрямую в файле или через действия WordPress. Также используй тот же приоритет для удаления действий, например 15 и 20.

Sumit Sumit
14 апр. 2016 г. 11:56:04

Действия добавляются в конструкторе плагина (конструктор вызывает функцию 'includes', а эта функция делает "include_once" файла со всеми хуками). Я также пытался сохранить приоритеты, но это не сработало.

Alex Alex
14 апр. 2016 г. 11:58:21

Просто предположение: плагин выводит контент в области, зарезервированной для содержимого записей и страниц? Обычно так делают плагины, работающие со своими собственными типами записей, чтобы обеспечить совместимость с разными темами. Вы пробовали использовать хук the_content вместо plugins_loaded?

Luis Sanz Luis Sanz
14 апр. 2016 г. 12:16:15

Да, я пробовал использовать the_content, но это тоже не сработало

Alex Alex
14 апр. 2016 г. 12:19:19

Тогда, плагин обернут в класс? В этом случае вам, возможно, придется сначала получить доступ к классу с помощью global $pluginsClass и передать его внутрь remove_action вот так: remove_action( 'sportspress_before_single_player', array( $pluginsClass, 'sportspress_output_player_details' ) );.

Luis Sanz Luis Sanz
14 апр. 2016 г. 12:23:03

@LuisSanz Я все еще новичок в WordPress, не могли бы вы объяснить, как получить доступ к классу плагина?

Alex Alex
14 апр. 2016 г. 13:24:00

Что ж, я перезапустил сервер, и теперь все работает.

Alex Alex
15 апр. 2016 г. 11:28:38
Показать остальные 4 комментариев
Все ответы на вопрос 3
0
18

Есть две вещи, которые смущают людей при попытке удалить хук:

  1. Вызовы remove_action() или remove_filter() должны происходить после вызовов add_action() или add_filter(), и до того, как хук фактически сработает. Это означает, что вы должны знать, когда хуки были добавлены и когда они срабатывают.
  2. Вызовы remove_action() или remove_filter() должны иметь тот же приоритет, что и вызовы add_action() или add_filter().

Если эти хуки были добавлены на фильтр init с приоритетом по умолчанию, то для их удаления мы просто подключаемся к init с приоритетом больше 10 и удаляем их.

add_action( 'init', 'wpse_106269_remove_hooks', 11 );
function wpse_106269_remove_hooks(){
    remove_action( 'sportspress_before_single_player', 'sportspress_output_player_details', 15 );
    remove_action( 'sportspress_single_player_content', 'sportspress_output_player_statistics', 20 );
}

Из https://codex.wordpress.org/Function_Reference/remove_action

Важно: Для удаления хука аргументы $function_to_remove и $priority должны совпадать с теми, которые использовались при добавлении хука. Это касается как фильтров, так и действий. При неудачном удалении предупреждение выводиться не будет.

15 февр. 2017 г. 20:56:00
1

У меня была такая же проблема. Я хотел удалить действие, которое было добавлено другим плагином, и заменить его на свою функцию в разрабатываемом мной плагине, но мой файл (как сказал @Sumit) шел после файла оригинального плагина в алфавитном порядке. Тем не менее, мне удалось удалить действие.

Что сработало в моем случае — это обернуть вызов remove_action внутри другого add_action, чтобы он выполнялся после загрузки всех плагинов. Это можно сделать с помощью действия init:

add_action( 'init', 'changeActions' );
function changeActions () {
    remove_action('my_action', 'the_function_from_the_plugin', 10);
}

P.S.: Если вы хотите проверить, были ли действия успешно удалены, вы можете вывести список функций, привязанных к нужному действию, используя код из этого ответа. Я использовал тестовый шорткод, так как не работал с файлами темы (просто добавьте [test_actions] на любую страницу в панели WordPress).

add_shortcode('test_actions', 'testActions');
function testActions($attrs) {
    //получаем список всех действий, используя эту глобальную переменную
    global $wp_filter;

    //получаем только действия, привязанные к 'my_action'
    $r = $wp_filter['my_action'];

    //возвращаем дамп массива в виде строки
    return var_export($r, TRUE);
}
25 сент. 2016 г. 11:18:10
Комментарии

Это сработало и у меня!

Jono Jono
21 сент. 2023 г. 19:40:19
3

Плагины загружаются в порядке, соответствующем их именам файлов. Например, плагин с именем abc.php загружается первым, а затем xyz.php. Поэтому, если вы пытаетесь удалить действие из плагина abc.php, которое было добавлено в плагине xyz.php, это невозможно без дополнительных изменений. Потому что на момент попытки удаления действие еще не было добавлено.

Вы можете просто добавить die(__FILE__); в оба плагина, чтобы увидеть, какой из них выводит результат первым. Если ваш плагин загружается раньше, вы можете сделать две вещи для удаления действия:

  1. Переименуйте ваш плагин, чтобы он загружался после целевого плагина.
  2. Я не уверен, когда выполняются родительские действия, но существует большой список действий Action_Reference, на которые вы можете повесить удаление действия в своем плагине. Теперь вы знаете, когда следует размещать remove_action(), чтобы это было эффективно.

Надеюсь, это поможет.

14 апр. 2016 г. 12:24:50
Комментарии

Я добавил die, и первый загружаемый плагин является "родительским", так что не должно быть проблем с порядком загрузки плагинов

Alex Alex
14 апр. 2016 г. 13:21:43

Да, тогда не должно быть проблем, удалите действие plugins_loaded и напрямую разместите remove_action в вашем плагине с тем же приоритетом, это будет работать в соответствии с предоставленной вами структурой кода.

Sumit Sumit
14 апр. 2016 г. 14:11:08

Но переименовывать плагин, чтобы он запускался после другого плагина — это плохая практика, должен быть другой способ сделать это, как предложил @brian-hellekin

Sagar Guhe Sagar Guhe
30 окт. 2019 г. 10:09:29