Точный do php action. PHP и формы

“Не используйте оператор goto” – так твердили нам преподаватели в академии, и действительно, оператор сей превращает код в полнейшую кашу. Разработчики php решили проблему кардинально – в php3 и php4 его просто нет. Чем они изначально руководствовались? Может быть хотели привить всем нам правильный стиль программирования? Ну что же, можно сказать это им вполне удалось – мы все уже привыкли, то есть вернее сказать начисто отвыкли от этого оператора, может оно и к лучшему, потому что в свое время мне пришлось придумать логическую конструкцию, которая вполне компенсировала этот самый злосчастный goto .
Не знаю у кого как, а у меня, особенно часто возникало желание использовать goto при создании обработчика html формы, когда от пользователя на сервер отправляется множество данных, которые php скрипт должен поэтапно проверить. Процесс этот проходить, как правило, в несколько этапов: печать самой формы, проверка полученных данных, предварительны показ, ну и например сохранение. Причем некоторые этапы могут повторятся: если проверка данных не прошла удачно переходим на печать формы, или если предварительный показ не устроил пользователя он может вернутся к вводу данных. Короче говоря некоторые куски кода могут задействоваться многократно. Использовать функции в этих условиях тоже не очень удобно – много входных и выходных переменных, функция должна выполнять слишком сложные действия, вообще коряво получается и читабельность кода резко падает.
И я придумал такую вот конструкцию.

do {

switch ($action ) {

default :

break ;

case "PRINT_FORM" :

Печатаем главную форму

break ;

case "CHECK_FORM" :

Проверяем правильность данных

break ;

case "PREVIEW_FORM" :

Предворительный просмотр

break ;

case "SAVE_FORM" :

Сохраняем данные

break ;

} while (true ) ;

Здесь основной оператор множественного выбора switch заключен в бесконечный цикл do-while – таким образом мы группируем нужные действия в секциях case: break; и можем неограниченно переходить из одной секции к другой. В секции default: удобно сделать предварительный разбор данных например если входных данных нет то $action = ‘PRINT_FORM’ печатаем форму, если есть например $_POST [‘submit’] то тогда отправляем на обработку полученных данных $action = ‘CHECK_FORM’ . Передача управления между блоками switch происходит с помощью изменения переменной $action , ну а выход из цикла с помощью break 2; или exit ;
Так например в блоке печати основной формы можно смело поставить break 2; т.к вывод формы предполагает окончание скрипта.
Конструкция очень гибкая и читабельная. Но есть один недостаток – если неправильно обработаны данные можно попасть в бесконечный цикл и скрипт зависает – это неприятно придется ждать целых 30 сек.
Давайте установим ограничение на кол-во циклов оператора do-while , 20 хватит с головой. Теперь если мы что-то накасячили скрипт намотает 20 оборотов, остановится и вывалит предупреждение об екстренном останове.
Отлаживать такую кострукцию очень удобно – достаточно после оператора swith распечатывать переменную $action и мы получим полную последовательность исполнения блоков.

DO { // в начале каждого цикла печатаем название // выполненной секции очень удобно для отладки echo $action." "; SWITCH ($action) { default: break; case "PRINT_FORM": /* печатаем главную форму */ break; case "CHECK_FORM": /* проверяем правильность данных */ break; case "PREVIEW_FORM": /* предворительный просмотр */ break; case "SAVE_FORM": /* сохраняем данные */ break; }// end switch } WHILE ((($i++) < 20) or die("Принудительный останов цикла"));

DO {

// в начале каждого цикла печатаем название

// выполненной секции очень удобно для отладки

echo $action . " " ; < / strong >

SWITCH ($action ) {

default :

break ;

case "PRINT_FORM" :

печатаем главную форму

break ;

RxGroovy has several Do variants.

  • Javadoc:
  • Javadoc:

  • Javadoc:

The doOnRequest operator (new in RxGroovy 1.1) registers an Action which will be called whenever an observer requests additional items from the resulting Observable. That Action receives as its parameter the number of items that the observer is requesting.

  • Javadoc:

  • Javadoc:

  • Javadoc:

  • Javadoc:

  • Javadoc:

before

  • Javadoc:

after the resulting Observable terminates, whether normally or with an error.

Sample Code

def numbers = Observable.from(); numbers.finallyDo({ println("Finally"); }).subscribe({ println(it); }, // onNext { println("Error: " + it.getMessage()); }, // onError { println("Sequence complete"); } // onCompleted);

1 2 3 4 5 Sequence complete Finally

  • Javadoc:

RxJava has several Do variants.

The doOnEach operator allows you to establish a callback that the resulting Observable will call each time it emits an item. You can pass this callback either in the form of an Action that takes an onNext variety of Notification as its sole parameter, or you can pass in an Observer whose onNext method will be called as if it had subscribed to the Observable.

  • Javadoc:
  • Javadoc:

The doOnNext operator is much like doOnEach(Action1) except that the Action that you pass it as a parameter does not accept a Notification but instead simply accepts the emitted item.

Sample Code

Observable.just(1, 2, 3) .doOnNext(new Action1() { @Override public void call(Integer item) { if(item > 1) { throw new RuntimeException("Item exceeds maximum value"); } } }).subscribe(new Subscriber() { @Override public void onNext(Integer item) { System.out.println("Next: " + item); } @Override public void onError(Throwable error) { System.err.println("Error: " + error.getMessage()); } @Override public void onCompleted() { System.out.println("Sequence complete."); } });

Next: 1 Error: Item exceeds maximum value

  • Javadoc:

The doOnRequest operator (new in RxJava 1.1) registers an Action which will be called whenever an observer requests additional items from the resulting Observable. That Action receives as its parameter the number of items that the observer is requesting.

  • Javadoc:

The doOnSubscribe operator registers an Action which will be called whenever an observer subscribes to the resulting Observable.

  • Javadoc:

The doOnUnsubscribe operator registers an Action which will be called whenever an observer unsubscribes from the resulting Observable.

  • Javadoc:

The doOnCompleted operator registers an Action which will be called if the resulting Observable terminates normally, calling onCompleted .

  • Javadoc:

The doOnError operator registers an Action which will be called if the resulting Observable terminates abnormally, calling onError . This Action will be passed the Throwable representing the error.

  • Javadoc:

The doOnTerminate operator registers an Action which will be called just before the resulting Observable terminates, whether normally or with an error.

  • Javadoc:

finallyDo is deprecated since RxJava 1.1.1, in favor of doAfterTerminate with the same behavior.

The finallyDo operator registers an Action which will be called just after the resulting Observable terminates, whether normally or with an error.

  • Javadoc:

The doAfterTerminate operator registers an Action which will be called just after the resulting Observable terminates, whether normally or with an error.

  • Javadoc:


RxJS implements the basic Do operator as do or tap (two names for the same operator). You have two choices for how to use this operator:

  1. You can pass it an Observer, in which case do / tap will call that Observer’s methods as though that Observer had subscribed to the resulting Observable.
  2. You can pass in a set of 1-3 individual functions (onNext , onError , and onCompleted) that do / tap will call along with the similarly-named functions of any of its observers.

Sample Code

/* Using an observer */ var observer = Rx.Observer.create(function (x) { console.log("Do Next: %s", x); }, function (err) { console.log("Do Error: %s", err); }, function () { console.log("Do Completed"); }); var source = Rx.Observable.range(0, 3) .do(observer); var subscription = source.subscribe(function (x) { console.log("Next: %s", x); }, function (err) { console.log("Error: %s", err); }, function () { console.log("Completed"); });

/* Using a function */ var source = Rx.Observable.range(0, 3) .do(function (x) { console.log("Do Next:", x); }, function (err) { console.log("Do Error:", err); }, function () { console.log("Do Completed"); }); var subscription = source.subscribe(function (x) { console.log("Next: %s", x); }, function (err) { console.log("Error: %s", err); }, function () { console.log("Completed"); });

Do Next: 0 Next: 0 Do Next: 1 Next: 1 Do Next: 2 Next: 2 Do Completed Completed


RxJS also implements doOnNext or tapOnNext (two names for the same operator). It is a specialized form of Do that responds only to the onNext case, by calling a callback function you provide as a parameter. You may also optionally pass a second parameter that will be the “ this ” object from the point of view of your callback function when it executes.

Sample Code

var source = Rx.Observable.range(0, 3) .doOnNext(function () { this.log("Do Next: %s", x); }, console); var subscription = source.subscribe(function (x) { console.log("Next: %s", x); }, function (err) { console.log("Error: %s", err); }, function () { console.log("Completed"); });

Do Next: 0 Next: 0 Do Next: 1 Next: 1 Do Next: 2 Next: 2 Completed


RxJS also implements doOnError or tapOnError (two names for the same operator). It is a specialized form of Do that responds only to the onError case, by calling a callback function you provide as a parameter. You may also optionally pass a second parameter that will be the “ this ” object from the point of view of your callback function when it executes.

Sample Code

var source = Rx.Observable.throw(new Error()); .doOnError(function (err) { this.log("Do Error: %s", err); }, console); var subscription = source.subscribe(function (x) { console.log("Next: %s", x); }, function (err) { console.log("Error: %s", err); }, function () { console.log("Completed"); });

Do Error: Error Error: Error


RxJS also implements doOnCompleted or tapOnCompleted (two names for the same operator). It is a specialized form of Do that responds only to the onCompleted case, by calling a callback function you provide as a parameter. You may also optionally pass a second parameter that will be the “ this ” object from the point of view of your callback function when it executes.

Sample Code

var source = Rx.Observable.range(0, 3) .doOnCompleted(function () { this.log("Do Completed"); }, console); var subscription = source.subscribe(function (x) { console.log("Next: %s", x); }, function (err) { console.log("Error: %s", err); }, function () { console.log("Completed"); });

Next: 0 Next: 1 Next: 2 Do Completed Completed


RxJS also implements a finally operator. It takes a function that will be called after the resulting Observable terminates, whether normally (onCompleted) or abnormally (onError).

Sample Code

var source = Rx.Observable.throw(new Error()) .finally(function () { console.log("Finally"); }); var subscription = source.subscribe(function (x) { console.log("Next: " + x); }, function (err) { console.log("Error: " + err); }, function () { console.log("Completed"); });

Error: Error Finally

do / tap , doOnNext / tapOnNext , doOnError / tapOnError , doOnCompleted / tapOnCompleted , and finally are found in each of the following distributions:

  • rx.js
  • rx.all.js
  • rx.all.compat.js
  • rx.compat.js
  • rx.lite.js
  • rx.lite.compat.js

RxPHP implements this operator as do .

Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence. This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline. When using do, it is important to note that the Observer may receive additional events after a stream has completed or errored (such as when using a repeat or resubscribing). If you are using an Observable that extends the AbstractObservable, you will not receive these events. For this special case, use the DoObserver. doOnNext, doOnError, and doOnCompleted uses the DoObserver internally and will receive these additional events.

Sample Code

//from https://github.com/ReactiveX/RxPHP/blob/master/demo/do/do.php $source = \Rx\Observable::range(0, 3) ->do(function ($x) { echo "Do Next:", $x, PHP_EOL; }, function (Throwable $err) { echo "Do Error:", $err->getMessage(), PHP_EOL; }, function () { echo "Do Completed", PHP_EOL; }); $subscription = $source->subscribe($stdoutObserver);

Do Next:0 Next value: 0 Do Next:1 Next value: 1 Do Next:2 Next value: 2 Do Completed Complete!

RxPHP also has an operator doOnError .

Sample Code

//from https://github.com/ReactiveX/RxPHP/blob/master/demo/do/doOnError.php $source = \Rx\Observable::error(new Exception("Oops")) ->doOnError(function (Throwable $err) { echo "Do Error:", $err->getMessage(), PHP_EOL; }); $subscription = $source->subscribe($stdoutObserver);

Do Error:Oops Exception: Oops

RxPHP also has an operator doOnCompleted .

Sample Code

//from https://github.com/ReactiveX/RxPHP/blob/master/demo/do/doOnCompleted.php $source = \Rx\Observable::empty() ->doOnCompleted(function () { echo "Do Completed", PHP_EOL; }); $subscription = $source->subscribe($stdoutObserver);

Do Completed Complete!

RxPHP also has an operator finally .

Will call a specified function when the source terminates on complete or error.

Sample Code

//from https://github.com/ReactiveX/RxPHP/blob/master/demo/finally/finally.php Rx\Observable::range(1, 3) ->finally(function() { echo "Finally\n"; }) ->subscribe($stdoutObserver);

Next value: 1 Next value: 2 Next value: 3 Complete! Finally

//from https://github.com/ReactiveX/RxPHP/blob/master/demo/finally/finally-error.php Rx\Observable::range(1, 3) ->map(function($value) { if ($value == 2) { throw new \Exception("error"); } return $value; }) ->finally(function() { echo "Finally\n"; }) ->subscribe($stdoutObserver);

Next value: 1 Exception: error Finally

Прикрепляет указанную PHP функцию на указанный хук. Указанная функция сработает в момент события, которое в свою очередь запускается с помощью do_action() .

Хук на который цепляется функция создается (инициализируется) с помощью функции do_action() .

Действия (actions), в отличии от фильтров (add_filter()), нужны, чтобы выполнить какое-либо действие в нужный момент, тогда как фильтры передают и получают обратно данные, которые затем используются.

Неофициально: фильтры - это те же самые события, работают они точно также и их можно использовать как события (вместо add_filter() можно использовать функцию add_action() и наоборот). Например, можно не изменяя возвращать полученные данные, но помимо этого выполнять какую-нибудь операцию (например запись в БД). Правда это бывает нужно очень редко. Все места где нужно вмешаться в код движка, разработчики, пытаются предусмотреть и вставить в это место событие.

✈ 1 раз = 0.000018с = очень быстро | 50000 раз = 0.07с = скорость света | PHP 7.0.8, WP 4.7

Хуков нет.

Возвращает

Всегда true.

Использование

add_action($tag, $function_to_add, $priority, $accepted_args); $tag(строка) (обязательный) Название действия, к которому будем цеплять функцию. $function_to_add(строка/замыкание) (обязательный) Название функции, которая должна быть вызвана во время срабатывания действия, т.е. функция которую цепляем к хуку. Формат передачи функции - обычно строка, . $priority(число) Приоритет выполнения функции. Если на этот же хук "прицеплены" еще функции, то приоритет будет решать последовательность их выполнения. Меньше число - раньше выполняется, т.е. 10 будет выполняться раньше чем 20.
По умолчанию: 10 $accepted_args(число) Число аргументов, которые принимает функция. Разумеется действие должно передавать это число аргументов.
По умолчанию: 1

Примеры

#1 Обычный хук

Будем отправлять письмо друзьям, при публикации нового поста:

Add_action("publish_post", "email_friends"); function email_friends($post_ID){ $friends = "[email protected], [email protected]"; wp_mail($friends, "sally"s blog updated", "I just put something on my blog: http://blog.example.com"); return $post_ID; }

Точно так же можно зарегистрировать этот хук через add_filter():

Add_filter("publish_post", "email_friends");

#2 Получение аргумента

do_action() передает аргумент в функцию и его можно использовать. В предыдущем примере это был ID поста, но мы его не использовали, потому он нам не был нужен. Теперь, пример того, как использовать передаваемый аргумент:

Add_action("comment_id_not_found", "echo_comment_id", 10, 1); function echo_comment_id($comment_ID){ echo "I just received ". $comment_ID; }

#3 Анонимная функция

В качестве колбэк функции можно передавать анонимную функцию, например:

Add_action("wp_head", function(){ echo "something"; });

Такие анонимные функции не работают совместно с PHP ускорителями.

#4 Добавление события из PHP класса

Если для события нужно использовать как-либо метод PHP класса, то во втором аргументе, вместо названия функции, нужно указать массив, где первым аргументом будет название класса (для static метода) или экземпляр класса (для public метода), а вторым название метода этого класса.

Экземпляр класса находится в переменной $this:

// Подключение метода класса за пределами класса add_action("wp_head", array("My_Class", "my_static_method")); class My_Class { public function __construct() { // Подключение метода класса внутри класса add_action("save_post", array($this, "my_public_method")); add_action("save_post", array(__CLASS__, "my_static_method")); } public function my_public_method($post_id) { // код функции } static function my_static_method($post_id) { // код функции } }

Заметки

Чтобы узнать сколько аргументов передает действие, найдите его в коде и посмотрите. Например, тут передается 2 аргумента:

Do_action("save_post", $post_ID, $post);

и для такого хука, код зацепки будет выглядеть так:

Add_action("save_post", "my_save_post", 10, 2);

а функция будет иметь 2 аргумента:

Function my_save_post($post_ID, $post){ // здесь код функции }

Создает событие (зацепку для произвольной функции). Чтобы функция сработала в момент события её нужно подключить к этому событию с помощью функции add_action() .

Кроме событий в WP есть еще фильтры (filters), принцип работы такой же. Разницы лишь в том, что фильтр должен вернуть полученную переменную, т.е. он фильтрует (изменяет) данные, а событие позволяет запустить пользовательскую функцию в момент срабатывания этого события. Фильтры запускаются функцией apply_filters()

✈ 1 раз = 0.00007с = очень быстро | 50000 раз = 0.03с = скорость света

Хуков нет.

Возвращает

Ничего не возвращает.

Использование

do_action($tag, $arg_a, $arg_b, ...); $tag(строка) (обязательный) Название создаваемого хука. $arg_a Значение аргумента, который будет передан.
$arg_b(строка/массив/число/объект/логический) Значение еще одного аргумента...
По умолчанию: аргумент не существует $arg_с(строка/массив/число/объект/логический) Функции можно передавать бесконечно много аргументов...

Примеры

#1. Пример использования

Эту функцию можно использовать в плагинах, темах и т.д., когда нужно внедрится в процесс выполнения кода, откуда-нибудь из другого места. Например, "зацепку" (хук) (do_action) мы установили в плагине, а "цепляться" за нее будем из файла functions.php в тот момент, когда будет срабатывать наша "зацепка".

Допустим, мы использовали такой код в плагине:

Теперь мы может сделать какое-нибудь действие в момент срабатывания функции do_action и при этом описать наше действие можно, например, из файла functions.php, разместив в нем такой код:

Function do_my_hook($a, $b){ // если переданная переменная $a равна true, // то, например, удалим запись 10 if($a===true) wp_delete_post(10); // а тут просто выведем переменную на экран echo "
".$b; // выведет значение второй переменной } // Регистрируем хук через // add_action($tag, $function_to_add, $priority, $accepted_args); add_action("my_hook", "do_my_hook", 10, 2);

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

Код do action : wp-includes/plugin.php WP 5.2.2

do_action($args); array_pop($wp_current_filter); }

Мы создали фундамент для будущего плагина, который распознает система WordPress. Сегодня мы займемся непосредственно изменением базового функционала системы.

Поможет нам в этом система «хуков» (hooks), «событий» (actions) и фильтров (filters). Эти три понятия и есть основа каждого плагина для WordPress.

Hooks

В WordPress есть два типа хуков:

  • Action hook: помечает место в коде, которое выполняет определенное действие, например, необходимо внести какие-либо данные и сохранить в базе.
  • Filter hook: помечает фильтр, который будет изменять какое-либо значение (переменную), так что в дальнейшем код будет использовать модифицированное значение.

Actions

Работа с событиями (actions)

Общая логика управления событиями в WordPress проста:

  1. Пометить место, где действие должно выполниться с помощью хука (action hook) с необходимыми параметрами.
  2. Создать функцию, которая будет выполнять нужные действия, используя параметры переданные хуком.
  3. Зарегистрировать событие, которое будет выполняться при срабатывании хука, с определенным приоритетом.
  4. Когда WordPress загружает страницу и находит hook, система выполнит все функции, которые зарегистрированы на этот хук.

Для выполнения первого пункта система предоставляет функцию ‘do_action’:

Do_action($tag, $arg_1, $arg_2, ... , $arg_n);

Она принимает следующие аргументы: $tag – название “хука”, $arg_1, $arg_2, … , $arg_n – параметры, с которыми будет вызвана функция. Аргументов может быть любое количество, либо 0.

Система сама по себе имеет много уже определенных хуков:

Do_action("init");

Это очень простой пример без дополнительных аргументов. Данных хук срабатывает, когда большая часть системы уже настроена и пришло время создавать собственные объекты, рубрики, посты и т.п.

Do_action("save_post", $post_id, $post);

В этом примере хук срабатывает при сохранении записи с двумя аргументами post_id — идентификатор записи и post — сама запись.

Создание хуков доступно любому разработчику для создания собственного плагина (или темы). Благодаря этому мы имеем мощный инструмент для управления поведением системы.

Do_action("my_truly_custom_hook");

Когда мы создали хук и написали функцию, нам необходимо зарегистрировать функцию с помощью «add_action»

Add_action($tag, $function_to_add, $priority, $accepted_args_number);

Функция ‘add_action’ принимает два обязательных параметра: $tag: название соответствующего хука и $function_to_add: имя функции, которую необходимо вызвать. Другие два параметра дополнительные: $priority: целочисленная переменная, которая определяет порядок выполнения функции (по-умолчанию — 10), $accepted_args_number: количество аргументов, которое принимает функция (по-умолчанию — 1).

Рассмотрим пример, чтобы понять весь процесс. Допустим, мы хотим добавить небольшое уведомление внизу нашего сайта. Мы можем использовать хук ‘wp_footer’ для этого, потому что он является обязательной частью кода, который использует каждая тема.

Function msp_helloworld_footer_notice(){ echo "

Hello, I"m your custom notice
"; } add_action("wp_footer", "msp_helloworld_footer_notice");

В этом примере мы создали функцию, которая просто выводит разметку для оповещения и зарегистрировали её в ‘wp_footer’. Как только мы добавим этот код в файл нашего плагина (см. предыдущий ) мы увидим результат на странице:

Оповещение плагина WordPress

Работа с фильтрами (filters)

Фильтры работают по той же схеме, что и события. Но фильтры не просто выполняют определенный кусок кода, они изменяют значения, переданные им хуком. Это означает, что каждый фильтр имеет связанное с ним значение (переменную), с которым он работает.

Функция-фильтр будет принимать это значение и преобразовывать его для дальнейшего использования. Хуки для фильтров немного отличаются от хуков для событий (action hooks).

Apply_filters($tag, $value_to_filter, $arg_1, $arg_2, ... , $arg_n);

Функция ‘apply_filter’ создает хук для фильтра с именем $tag и обязательным параметром $value_to_filter (он может быть пустым, но должен быть объявлен). Остальные аргументы необязательны работают так же как и для событий.

Filter_function($value_to_filter, $arg_1, $arg_2, ... , $arg_n){ //фильтр return $value_to_filter; //значение необходимо вернуть }

Это «скелет» фильтра, который демонстрирует, что фильтр должен:

  1. принимать хотя бы 1 аргумент;
  2. возвращать модифицированное значение.
add_filter($tag, $function_to_add, $priority, $accepted_args);

Функция ‘add_filter’ регистрирует функцию с названием, содержащимся в $function_to_add для хука $tag. Остальные аргументы - $priority и $accepted_args — работают так же как и у хуков для событий.

Рассмотрим пример: обычная для плагина задача — добавить что-нибудь в конец поста. Если подробнее рассмотреть функцию ‘the_content’, которая используется для вывода содержимого записи, мы найдем такой хук:

$content = apply_filters("the_content", $content);

Используя его мы можем легко добавить что-либо в конец поста.

Function msp_helloworld_post_footer($content) { $content .= "

"; return $content; } add_filter("the_content", "msp_helloworld_post_footer", 100);

Обратите внимание, что мы используем большое число для приоритета, что убедиться, что до выполнения ‘msp_helloworld_post_footer’ все стандартные фильтры отработают. После включения кода в наш плагин мы увидим результат:


Как найти хук

Теперь нам понятно, что для выполнения определенных действий, нам необходимо знать о существующих хуках.

«Кодекс» WordPress предоставляет списки хуков для фильтров и событий Action Reference и Filter Reference .

Дополнительные действия с хуками

Так же как и добавить, хук можно удалить, используя похожий синтаксис.

Удалить события можно так:

Remove_action($tag, $function_to_remove, $priority, $accepted_args); remove_all_actions($tag, $priority);

Как вы догадались, ‘remove_action’ удаляет определенное событие, зарегистрированное для данного хука (необходимо правильно указать приоритет и количество аргументов, так как было указано при регистрации), и ‘remove_all_actions’ помогает удалить все события, зарегистрированные для хука (если приоритет опущен, функция удалит все события).

Фильтры можно удалять так же:

Remove_filter($tag, $function_to_remove, $priority, $accepted_args); remove_all_filters($tag, $priority);

API для плагинов в WordPress также предоставляет функции для проверки зарегистрирована ли функция для данного хука:

Has_action($tag, $function_to_check); has_filter($tag, $function_to_check);

Обе функции проверяют зарегистрирована ли данная функция для хука и возвращают true в случае успеха, иначе flase. Внутри функции у нас есть возможность проверить, что хук вызвал её:

If("hook_to_check_name" === current_filter()){}

Несмотря на название ‘current_filter’ работает не только с фильтрами но и с событиями.

Нетривиальный пример

Оживим «скелет» нашего плагина, который мы подготовили в прошлом уроке.

Заполним файл ‘core.php’ (главная часть нашего плагина, в которой сосредоточена основная часть функций) кодом, который решает задачу, которая реально может возникнуть в ходе работы. Для её решения мы будем использовать actions и filters.

Пусть ваш WordPress сайт принимает посты разных авторов от гостей, но не позволяет создавать аккаунты. Это значит, что пользователь, который опубликовал пост и реальный автор — разные люди и нам необходимо убедиться, что автор будет указан в посте. Мы можем сделать это с помощью таксономии.

Создадим собственную таксономию для обработки имя автора и его короткой биографии. Мы сможем использовать имя автора как другие термины таксономии (теги, например) в посте. Код:

/** регистрация фильтров и событий **/ function msp_helloworld_init(){ add_action("init", "msp_helloworld_taxonomies"); add_filter("the_content", "msp_helloworld_author_block_filter"); add_filter("post_class", "msp_helloworld_post_class"); } add_action("plugins_loaded", "msp_helloworld_init"); /** taxonomy **/ function msp_helloworld_taxonomies(){ $args = array("labels" => array("name" => "Guest authors", "singular_name" => "Guest author"), "show_in_nav_menus" => false); register_taxonomy("gauthor", array("post"), $args); } /** разметка блока автора **/ function msp_helloworld_author_block(){ global $post; $author_terms = wp_get_object_terms($post->ID, "gauthor"); if(empty($author_terms)) return; $name = stripslashes($author_terms->name); $url = esc_url(get_term_link($author_terms)); $desc = wp_filter_post_kses($author_terms->description); $out = "

"; $out .= "
This is a guest post by {$name}
"; $out .= "
{$desc}
"; return $out; } /** добавить разметку в конец поста **/ function msp_helloworld_author_block_filter($content){ if(is_single()) $content .= msp_helloworld_author_block(); return $content; } /** добавить CSS class к посту **/ function msp_helloworld_post_class($post_class){ global $post; $author_terms = wp_get_object_terms($post->ID, "gauthor"); if(!empty($author_terms)){ $post_class = "gauthor"; } return $post_class; }

Как видите, мы создали функцию для регистрации собственной таксономии и привязали её к хуку ‘init’. После мы создали шаблон, отвечающий за отображение блока автора, используя функцию WordPress ‘wp_get_object_terms’. После мы вставили блок с информацией об авторе в конец поста с помощью фильтра ‘the_content’. И, наконец, мы добавили собственный CSS класс. Результат работы: