Как определить приоритет при использовании add_action()?
Я писал небольшой плагин для удаления некоторых пунктов меню для пользователей без прав администратора в панели управления, и обнаружил, что мой плагин не работал, пока я не указал приоритет в коде:
add_action('admin_bar_menu', 'remove_toolbar_items', 999);
Без 999
код не удаляет элементы в моей функции remove_toolbar_items
, а с ним работает отлично:
function remove_toolbar_items( $wp_admin_bar ) {
if ( !current_user_can( 'manage_options' ) ) {
// Удалить пункт "Новая запись"
$wp_admin_bar->remove_node('new-post');
// Удалить пункт "Комментарии"
$wp_admin_bar->remove_node('comments');
}
}
В документации для параметра приоритета говорится:
Используется для указания порядка выполнения функций, связанных с определенным действием. Меньшие числа соответствуют более раннему выполнению, а функции с одинаковым приоритетом выполняются в том порядке, в котором они были добавлены к действию. Значение по умолчанию: 10
Однако я не нашел ничего, что объясняет, как определить, какой приоритет использовать. Как определить, когда использовать приоритет и какой приоритет использовать? Чувствую, что мог бы часами ломать голову, если бы не поэкспериментировал с параметром приоритета.
Кроме того, я вижу, что приоритет по умолчанию равен 10, но существует ли известный диапазон значений приоритета?

диапазон значений приоритета? диапазон значений приоритета?
Вообще говоря, вы не можете знать a priori с каким приоритетом что-то зарегистрировано. Необходимый приоритет зависит от того, как были зарегистрированы другие колбэки. Часто это значение по умолчанию равно 10, но оно может быть в диапазоне от PHP_INT_MIN
(отрицательные числа всё ещё являются целыми) до PHP_INT_MAX
, и единственный способ убедиться — это экспериментировать и, если возможно (как в случае с ядром и любыми темами или плагинами, которые вас конкретно интересуют), изучать исходный код.

Спасибо. Кажется, в ядре должна быть небольшая встроенная утилита, которая предоставляет эту информацию.

WordPress помещает ваши действия в массив с индексированными приоритетами. Вы можете увидеть это, выведя (в админ-панели через хук admin_init
) переменную $wp_filter
:
*Примечание* как отмечает @s_ha_dum в комментариях ниже, хук admin_init
может не захватить все добавленные хуки для действия, более надежным вариантом вывода может быть использование хука shutdown
.
function filter_print() {
global $wp_filter;
print_r( $wp_filter['admin_bar_menu'] );
die();
}
add_action( 'admin_init', 'filter_print' );
Это даст нам аккуратный массив, который выглядит примерно так: (упрощенно)
Array(
[admin_bar_menu] => Array (
[0] => Array (
[wp_admin_bar_my_account_menu] => Array (
[function] => wp_admin_bar_my_account_menu
[accepted_args] => 1
)
[wp_admin_bar_sidebar_toggle] => Array (
[function] => wp_admin_bar_sidebar_toggle
[accepted_args] => 1
)
)
[4] => Array (
[wp_admin_bar_search_menu] => Array (
[function] => wp_admin_bar_search_menu
[accepted_args] => 1
)
)
[7] => Array (
[wp_admin_bar_my_account_item] => Array (
[function] => wp_admin_bar_my_account_item
[accepted_args] => 1
)
)
[10] => Array (
[wp_admin_bar_wp_menu] => Array (
[function] => wp_admin_bar_wp_menu
[accepted_args] => 1
)
)
[20] => ...
)
)
Числа 0, 4, 7, 10 и так далее — это приоритеты действий. Когда новое действие добавляется, по умолчанию ему присваивается приоритет 10, аналогично индексу 0 в примере выше, они просто группируются в один индекс массива. Учитывая, что множество хуков добавляется в это конкретное действие, вам может потребоваться выполнить свой хук в самом конце или после выполнения определенного действия (например, меню). Один из двух приоритетов может сработать так же эффективно: 81
или 201
.
В большинстве случаев приоритета по умолчанию (10) достаточно. В других случаях вам может понадобиться добавить свой хук сразу после другого (например, чтобы отменить его действие или удалить определенный элемент), и в этом случае вы можете использовать global $wp_filter;
, чтобы определить, куда его нужно поместить.

Я думал об этом, но это будет показывать только хуки, добавленные до или на admin_init
, и только те, что подключены в текущей установке. Это ничего не говорит о том, что может сделать еще не установленный плагин или тема. В любом случае, +1.

@s_ha_dum Хорошее замечание. Думаю, можно также использовать что-то вроде admin_footer
, верно? Или будет та же проблема?

Хук shutdown
был бы лучшим вариантом, но только для уже установленного кода. Даже в этом случае хуки могут подключаться условно, поэтому некоторые все равно можно пропустить.

Итак, есть способ определить приоритет действия.
Мы можем использовать следующий код: has_action( $tag, $function_to_check )
, который опционально возвращает приоритет указанной функции на данном хуке.
Ссылка: https://codex.wordpress.org/Function_Reference/has_action

Если кто-то ищет список приоритетов/ссылку на действия (Action Priority/Reference) в WordPress, полный список хуков доступен по ссылке:
