Внутри WordPress действия и фильтры

Прошли те времена, когда разработчики WordPress, желая расширить функциональность CMS, были вынуждены изменять и взламывать непосредственно исходный код WordPress, в результате чего головная боль при модернизации и распространении модификаций. Когда в 2004 году вышел WordPress 1.2, была введена новая архитектура плагинов, которую теперь обычно связывают с действиями, фильтрами, хуками и Plugin API.


WordPress Actions and Filters

Ядро WordPress было тщательно сдобрено действиями и фильтрами, так что мог быть подцеплен внешний код (в виде тем и плагинов), вводя новую функциональность в стандартный поток. Plugin API обеспечивает изящный интерфейс для работы с действиями и фильтрами. Данная статья объединяет понимание внутренней работы, элегантности и красоты Plugin API. Это поможет разработчикам плагинов и тем  WordPress обрести более глубокое понимание того, что происходит за кулисами, почему некоторые вещи будут работать, а другие не будут, и куда смотреть, когда они неожиданно не работают.

Предупреждение

Это подробное пошаговое руководство по некоторой части исходного кода ядра WordPress. Чтобы наиболее полно понять, осознать и получить удовольствие от него, вам необходимы базовые знания PHP и функций WordPress , а также исходного кода WordPress 3+ (который можно рассматривать онлайн) и мужество копаться и пачкать свои руки.

Plugin API

Функции, которые разработчики тем и плагинов наиболее часто используют:

Эти функции хорошо известны, хорошо документированы, и обильно используются в большинстве тем и плагинов. Страница Кодекса для Plugin API дает некоторые основные примеры хуков WordPress в действии. Исходный код Plugin API чувстует себя как дома в файле /wp-includes/plugin.php. Не стесняйтесь, откройте его в вашем любимом текстовом редакторе или просмотрите его онлайн, чтоб следовать вместе.

API довольно компактный, всего лишь примерно 350 строк кода (остальные комментарии). Он предоставляет 22 функции, 14 из которых работают непосредственно с действиями и фильтрами, а остальные это вспомогательные функции и утилиты, которые относятся к анализу пути плагина, активации и дезактивации.

Plugin API становятся доступным на самых ранних стадиях процесса загрузки WordPress, а самое раннее действие, которое может быть подключено это muplugins_loaded, оно срабатывает после всех подключенных “обязательных к использованию” и общесетевых плагинов, но оно довольно бесполезное, если ваш плагин ни относится к таким плагинам. Действие plugins_loaded срабатывает сразу же после того, как все нужные файлы плагина включаются в область видимости. Наконец, срабатывает действие, after_setup_theme как только подключается файл functions.php активного шаблона.

Справочник действий и справочник фильтров содержит описания многих действий и фильтров, доступных во время исполнения обычных сценариев по запросу.

$Wp_filter

Plugin API предоставляет функции, которые действуют на глобальный массив $wp_filter, это простой ассоциативный массив с определенной структурой. Все функции действий и фильтров считываются и записываются в этот глобальный общедоступный ассоциативный массив, который полностью отделяет API от кода ядра WordPress. Фактически, вы можете включить файл plugin.php, относящийся к Plugin API, в любой другой PHP проект или фреймворк и использовать все функции действий и фильтров (do / apply, add remove, has, current) без каких-либо изменений вообще. На самом деле, практически не измененный файл поставляется с BackPress, набором независимых библиотек, которые выросли из WordPress. Секрет заключается в высокой гибкости API и простоте его концепции.

Глобальный массив $wp_filter изначально задается в WordPress как неопределенная переменная, полностью лишенная каких-либо данных. Данные записываются как только добавляется действие или фильтр через функцию add_action() или add_filter(). Таким образом, это будет нашей отправной точкой. Обе функции имеют одинаковый прототип в плане аргументов:

function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1)

Эта функция определена на строке 65. Она очень проста. Обратите внимание, она возвращает значение true совершенно независимо от того, что происходит внутри. Функция add_action() ( на строке 331) вызывает функцию add_filter() без каких-либо изменений. Это означает, что $wp_filter не делает различий между фильтрами и действиями когда ставит их в очередь. Структура данных $wp_filter достаточно проста и может быть представлена ​​на следующей диаграмме:

WordPress filter structure Структура данных $wp_filter.

Массив “функции” (т.е. массив содержащий вызов функции и ряд аргументов которые она принимает) определяется вспомогательной функцией wp_filter_build_unique_id() (строка 750), она возвращает уникальный idx функции обратного вызова, упорядоченный по приоритету — “priority” и прикрепленный к тегу — “tag” (который  является именем фильтра или действия). Это формирует перечень действий с уникальными вызываемыми функциями, которые будут вызываться только один раз, независимо от того, сколько раз добавлен один и тот же вызов (уникальный идентификатор гарантирует этого)

разберемся с действиями!

Действия, как правило, выполняются с помощью функции do_action(), которая имеет следующий прототип:

function do_action($tag, $arg = '', ...)

Определение функции находится на строке 359,  более чем желательно, чтоб вы прочитали фрагменты кода, и после этого вернулись к пошаговому объяснению.

Прежде всего глобальная переменная $wp_actions отслеживает сколько раз было запущено конкретное действие. Это простой ассоциативный массив с тегом действия или именем в качестве ключа. Функция did_action()  (строка 423) возвращает число, соответствующее количеству вызовов действия через доступ к массиву $wp_actions. Далее, вызывается действие all через функцию _wp_call_all_hook(). Эта функция просто вставляет все зарегистрированные или добавленные хуки в массив $wp_filter['all'] с помощью PHP функции call_user_func_array() (мы посмотрим на замечательный пример применение действия all чуть позже). После этого следуют простые проверки того, существует ли действие.

Далее, вы заметите, что тег действия помещается в глобальный массив $wp_current_filter. Функция current_filter() (строка 306) возвращает последнее значение, хранящееся в этом глобальном массиве. Обратный вызов функций действия и фильтра может подтянуть еще больше действий и фильтров, ссылаясь на другие обратные вызовы функций, что приведет к длинным цепочкам. Можно проследить всю цепочку хуков, глядя на глобальный массив $wp_current_filter во время выполнения обратного вызова функции. Тем не менее, эти цепи обычно ограничиваются не больше чем парой ссылок, если  конечно вы не делаете так:

add_action( 'my_action', 'my_function' );
add_action( 'my_action_2', 'my_function_2' );
add_action( 'my_action_3', 'my_function_3' );
add_action( 'my_action_4', 'my_function_4' );
function my_function() { do_action( 'my_action_2'); }
function my_function_2() { do_action( 'my_action_3'); }
function my_function_3() { do_action( 'my_action_4'); }
function my_function_4() { var_dump( $GLOBALS['wp_current_filter']); }

do_action( 'my_action' );

/* array(4) {
[0]=> string(9) "my_action"
[1]=> string(11) "my_action_2"
[2]=> string(11) "m ...

Если вы хотите прочитать полностью статью, посетите сайт наших спонсоров

Comments are closed.