Попытка использования add_action и do_action с параметрами
В файле functions.php моей темы я пытаюсь добавить функцию с параметрами (как тест работоспособности, не для реальной функциональности), но это просто не работает.
Параметры всегда приходят пустыми, даже если я вызываю do_action с параметрами, как предложено на этой странице документации.
function alter_item ($user, $items, $action) {
global $current_user, $menu;
get_currentuserinfo();
switch ($action) {
case false:
if ($current_user->user_login == $user) {
remove_menu_page ($items);
}
break;
case true:
if ($current_user->user_login == $user) {
remove_menu_page ($items);
}
break;
}
}
add_action( 'admin_menu', 'alter_item', 10, 3 );
do_action('alter_item', 'my-user', 'plugins.php', false);
Вы используете это неправильно.
add_action
: прикрепляет функцию к хуку действия. В вашем коде вы прикрепляете функциюalter_item
к хуку действияadmin_menu
. Таким образом, когда происходит действиеadmin_menu
, выполняется функцияalter_item
. Согласно кодексу, к функциям, прикрепленным кadmin_menu
, не передаются параметры. Поэтому параметры, которые вы пытаетесь использовать вalter_item
, недействительны.do_action
: вызывает все функции, прикрепленные к хуку действия. В вашем коде вы вызываете все функции, прикрепленные к хуку действияalter_item
. Хук действияalter_item
будет пользовательским хуком, так как он не входит в ядро WP, но в вашем коде в данный момент нет функций, прикрепленных к этому действию, поэтому ничего не произойдет с вашимdo_action('alter_item'...
.
Правильный способ прикрепить функцию к admin_menu
:
function alter_item() {
//Делайте что хотите
}
//Аргумент приоритета (10 в коде ниже) является необязательным.
add_action( 'admin_menu', 'alter_item', 10 );
Правильный способ определения пользовательских действий:
do_action('alter_item', 'my-user', 'plugins.php', false);
Затем вы можете прикрепить функции к действию alter_item
следующим образом:
add_action( 'alter_item', 'alter_item_attached_function', 10, 3 );
function alter_item_attached_function( $user, $items, $action ) {
//Теперь $user, $items и $action будут 'my-user', 'plugins.php' и false
}
Если вы хотите передать информацию к основным действиям, вы можете:
- использовать допустимые параметры для каждого действия. Обратитесь к официальной документации каждого действия.
- определить глобальные переменные, использовать опции, транзиенты или пользовательские свойства/методы объектов, чтобы использовать эту информацию в разных местах вашего кода. Пример.
- Использовать анонимные функции PHP с ключевым словом
use
.
Пример использования ключевого слова use
:
$user = 'my-user';
$items = 'plugins.php';
$action = false;
add_action( 'admin_menu', function() use ($user, $items, $action) {
global $current_user, $menu;
get_currentuserinfo();
switch ($action) {
case false:
if ($current_user->user_login == $user) {
remove_menu_page ($items);
}
break;
case true:
if ($current_user->user_login == $user) {
remove_menu_page ($items);
}
break;
}
} );

ВАУ, это намного сложнее, чем я себе представлял, но на 100% логично, спасибо cybmeta!

Минусую, потому что анонимные функции, вызываемые через action_hooks, нельзя отключить. Это действительно плохая практика, потому что другие не смогут удалить/переопределить вызов. Action hooks всегда должны быть реализованы правильно.
Например:
add_action('some_action_hook', 'some_function'); // Это хорошо, можно удалить через remove_action().
add_action('admin_menu', function() { // код }); // это плохо, потому что теперь нет способа использовать remove_action для удаления этого поведения.
На самом деле, такой метод просто ленивый и небрежный, и нет реальных веских причин его использовать, кроме лени :)

Я с вами не согласен. Бывают ситуации, когда использование анонимных функций в хуках действий и фильтров может быть полностью оправдано. Кроме того, вы должны знать, что анонимные функции можно отключить (очень грязным способом, признаю). В любом случае, это был всего лишь один из множества примеров, о которых я говорил (глобальные переменные, опции, транзиенты, свойства объектов, .....). Перечитайте ответ более внимательно, не будьте ленивы при чтении ;)
