Хуки (фильтры, события)
Хуки это способ одной части кода модифицировать и взаимодействовать с другой частью кода. Хуки это то, как плагины и темы взаимодействуют с ядром WordPress, при этом не меняя кода самого ядра. Хуки также широко используются самим ядром, чтобы дать возможность включать, изменять или отключать логику кода в ядра.
Есть два типа хуков:
- События
Позволяют запустить php функцию в момент срабатывания указанного события. Позволяют добавить или изменить функционал WordPress или плагина. Прикрепленная к хуку php функция просто будет вызвана в определенный момент - когда сработает событие. В этот момент может быть выполнена какая-то задача, например вывод чего либо на экран или запись данных в базу данных, или что угодно еще.
Например, есть хук-событие wp_insert_comment, который срабатывает при добавлении комментария. Прикрепив функцию к такому событию, мы можем например, отправлять письмо автору записи, что к его записи оставлен коммент.
- Фильтры
Дают возможность изменять передаваемое значение (фильтровать значение). Значение передается в колбек функцию, она его изменяет и возвращает. Принцип работы такой же как у событий, разница лишь в том, что фильтр обязательно передает значение в прикрепляемую к нему функцию и функция должна вернуть измененное или переданное значение. Т.е. фильтр изменяет переданные данные.
Фильтры можно использовать как события, если нет подходящего события, a фильтр подходит. Так можно сделать какую-то операцию в момент срабатывания фильтра и просто вернуть переданное в фильтр значение.
Примеры использования
Чтобы использовать хук, нужно прикрепить PHP функцию к хуку. Прикрепляется она во втором параметре функции add_action/filter(). После этого прикрепленная функция будет срабатывать в момент срабатывания хука.
Примеры события:
Пример 1.
Создадим свою функцию и свой хук и заставим их работать:
// Прикрепим функцию к фильтру. // Это обычно делается в другом файле, но обязательно до вызова фильтра... add_filter( 'my_filter', 'my_filter_function' ); function my_filter_function( $str ){ return 'Здравствуйте '. $str; } // Вызов фильтра echo apply_filters( 'my_filter', 'Владимир' ); //> Здравствуйте Владимир
Пример 2.
Добавим тип записи 'movie' в результаты поиска:
Изменим запрос MySQL, который извлекает записи для основного цикла. Для этого подключиться к событию pre_get_posts и добавим новый тип записи 'movie' в результаты поиска:
## добавим тип записи 'movie' в результаты поиска add_action( 'pre_get_posts', 'search_filter' ); function search_filter( $query ) { if ( ! is_admin() && $query->is_main_query() ) { if ( $query->is_search ) { $query->set( 'post_type', array( 'post', 'movie' ) ); } } }
Пример 3.
Добавим дополнительный HTML тег в <head>
Для этого используем хук wp_head:
add_action( 'wp_head', 'prevent_google_maps_resize' ); function prevent_google_maps_resize() { echo '<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />'; }меню
Пример фильтра:
Допустим, мы делаем тему и в каком-то месте темы нам нужно вызвать функцию, но мы заранее не знаем как функция будет называться. Т.е. пользователи сами будут добавлять функцию в это место.
Для этого в этом месте шаблона мы может вызвать не функцию а событие, назовем его my_action
и затем прикрепить к этому событию функцию:
// создадим функцию для события function my_action_function( $text ){ echo 'Событие "my_action" сработало сейчас.'; } // Прикрепим функцию к событию 'my_action'. Это можно сделать в другом файле // главное до того как событие сработает. add_action('my_action', 'my_action_function'); // Вызов самого события. Вставляем эту строку в то место темы где нужно, // чтобы сработала прикрепленная к нему функция do_action( 'my_action' ); //> на месте этого кода будет выведена надпись: // 'Событие "my_action" сработало сейчас.'меню
Полное руководство по хукам WordPress
Читайте в отдельной статье → Как работают хуки в WordPress
Приоритет хука
Приоритет определяет, когда callback-функция будет выполняться по отношению к другим callback-функциям, привязанных к хуку.
Функция с приоритетом 11 будет запускаться после функции с приоритетом 10; и функция с приоритетом 9 будет запускаться раньше, чем функция с приоритетом 10. Если приоритет не указан, то он равен 10.
Если две функции прикреплены к одном хуку с одинаковым приоритетом, то они будут выполняться в порядке их прикрепления.
Например, следующие callback-функции прикреплены к хуку init и имеют разные приоритеты:
add_action( 'init', 'run_me_late', 11 ); add_action( 'init', 'run_me_early', 9 ); add_action( 'init', 'run_me_normal' ); // приоритет 10 по умолчанию add_action( 'init', 'run_me_normal_two' ); // приоритет 10 по умолчанию
В момент срабатывания хука init функции выполняться в следующем порядке:
- run_me_early()
- run_me_normal()
- run_me_normal_two()
- run_me_late()
Число передаваемых функции аргументов
В прикрепляемую функцию могут передаваться какие-то данные - параметры. Их можно использовать в момент события, чтобы создать какую-то логику.
Например, когда WordPress сохраняет запись и запускает событие save_post, хук передает два параметра в callback-функцию: ID записи и объект самой записи:
do_action( 'save_post', $post->ID, $post );
Теперь, когда callback-функция регистрируется для save_post, можно указать, сколько параметров функция должна получить. По умолчанию она получает всего один первый параметр, в данном случае $post->ID. Сделано такое ограничение для быстродействия системы хуков.
Так, если нужен второй параметр $post, то в четвертом параметре add_action нужно указать число 2 - означающее что прикрепленная функция, должна получить 2 параметра.
// прикрепляем функцию к хуку add_action( 'save_post', 'my_save_post_callback', 10, 2 ); // прикрепляемая функция, получает 2 параметра function my_save_post_callback( $post_id, $post ) { // делаем что-нибудь }меню
Создание собственных хуков
Систему хуков можно расширять. При написании плагина, в него можно добавлять свои собственные события или фильтры, чтобы дать возможность пользователям внедряться в код плагина, не меняя кода самого плагина. Так, можно придумать свой хук, добавить его в код плагина и затем, прикрепляя к этому хуку php функции, управлять вашим плагином из кода другого плагина или темы.
Чтобы создать событие или фильтр в коде, к которому потом можно будет добавлять функции, используется функция do_action() или apply_filters():
do_action( $tag, $arg_a, $arg_b, ... );
apply_filters( $tag, $value, $arg_a, $arg_b, ... );
- $tag(строка) (обязательный)
- Название создаваемого хука.
- $value(строка/массив/число/объект/логический) (обязательный)
- Значение, которое будет передаваться функции в её первом аргументе, другими словами - значение, которое нужно отфильтровать.
- $arg_a(строка/массив/число/объект/логический)
- Значение аргумента, который будет передан.
По умолчанию: аргумент не существует - $arg_b(строка/массив/число/объект/логический)
- Значение еще одного аргумента... Так можно передавать сколько угодно аргументов.
По умолчанию: аргумент не существует
Пример создания события
Допустим, у нас есть плагин опроса и при голосовании хорошо бы добавить событие этого голосования. Чтобы можно было из другого кода подключиться к нашему плагину и, допустим, при голосовании, записать какие-то данные пользователя в БД... Такой функционал может не предусматриваться плагином, но он может пригодится пользователям вашего плагина и при наличии хука, они легко его допишут...
Итак, у нас есть функция плагина add_vote() - записывает голос, в конец этой функции добавим событие:
function add_vote(){ // код функции, в котором определяется ID опроса - $poll_id и выбранный ответ - $answer // передадим эти данные в хук, они могут пригодится при использовании хука. // создаем свой хук, пусть он будет назваться - myplugin_add_vote do_action( 'myplugin_add_vote', $poll_id, $answer ); }
Все, теперь, где-то в другом коде мы можем подключить функцию к нашему событию и выполнить в момент события какие-то действия.
add_action( 'myplugin_add_vote', 'my_add_vote_logic', 10, 2 ); // 2 - два параметра function my_add_vote_logic( $poll_id, $answer ){ // просто выведем на экран параметры события и оборвем PHP wp_die( "ID опроса: $poll_id. Ответ: $answer" ); }меню
Удаление хуков
Смотрите в статье Как работают хуки в WordPress.