Попытка использования add_action и do_action с параметрами

15 янв. 2015 г., 12:05:27
Просмотры: 28.4K
Голосов: 9

В файле 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);
0
Все ответы на вопрос 1
3
13

Вы используете это неправильно.

  • 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;
    }
} );
15 янв. 2015 г. 13:29:16
Комментарии

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

wxT3APyGfkYJVK wxT3APyGfkYJVK
15 янв. 2015 г. 13:48:00

Минусую, потому что анонимные функции, вызываемые через action_hooks, нельзя отключить. Это действительно плохая практика, потому что другие не смогут удалить/переопределить вызов. Action hooks всегда должны быть реализованы правильно.

Например:

add_action('some_action_hook', 'some_function'); // Это хорошо, можно удалить через remove_action().

add_action('admin_menu', function() { // код }); // это плохо, потому что теперь нет способа использовать remove_action для удаления этого поведения.

На самом деле, такой метод просто ленивый и небрежный, и нет реальных веских причин его использовать, кроме лени :)

Hybrid Web Dev Hybrid Web Dev
12 дек. 2015 г. 00:57:45

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

cybmeta cybmeta
12 дек. 2015 г. 08:43:54