Поддержка Разное Несовсем понятно, как работают т.н. фильтры.

  • Несовсем понятно, как работают т.н. «фильтры».

    Допустим, что во время работы WordPress мной и разными программами
    (плагинами) было добавлено несколько фильтров с одинаковыми
    именами «someFilter», но с разными функциями обратного вызова (CBF).
    При этом я не знаю, что плагины A, B, C используют то же имя
    фильтра, что и я:

    add_filter(«someFilter», «CBF_1», 10, …); — Добавлен плагином A
    add_filter(«someFilter», «CBF_2», 10, …); — Добавлен плагином B
    add_filter(«someFilter», «CBF_3», 20, …); — Добавлен МНОЙ.
    add_filter(«someFilter», «CBF_4», 30, …); — Добавлен плагином C

    По замыслу функции должны вернуть следующие результаты:
    CBF_1 — «Давайте возрадуемся»
    CBF_2 — «Давайте воспоём»
    CBF_3 — «WordPress — крутейший CMS»
    CBF_4 — «Слава КПСС»

    Я запускаю apply_filters("someFilter",...);
    Ожидаю получить «WordPress — крутейший CMS» (CBF_3).
    А получаю «Давайте возрадуемся» (CBF_1) потому что:
    — приоритет 10 — наименьший;
    — в списке с приоритетами 10 — первый.

    А может я получу:
    Давайте возрадуемся
    Давайте воспоём
    WordPress — крутейший CMS
    Слава КПСС

    В чём я не прав ?

    Спасибо за разъяснение.

Просмотр 4 ответов — с 1 по 4 (всего 4)
  • Модератор Sergey Biryukov

    (@sergeybiryukov)

    Live and Learn

    При этом я не знаю, что плагины A, B, C используют то же имя
    фильтра, что и я

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

    Ожидаю получить «WordPress — крутейший CMS» (CBF_3).
    А получаю «Давайте возрадуемся» (CBF_1)

    А я получаю «Слава КПСС» (CBF_4).

    потому что:
    — приоритет 10 — наименьший;
    — в списке с приоритетами 10 — первый.

    Наоборот — чем меньше приоритет, тем раньше выполняется функция.

    В данном примере происходит следующее:

    • Все функции выполняются согласно приоритету: CBF_1, CBF_2, CBF_3, CBF_4. Порядок добавления имеет значение только для первых двух, поскольку у них приоритет одинаковый. Если приоритет разный — порядок выполнения зависит именно от него, а не от порядка добавления.
    • Поскольку функция CBF_4 выполняется последней — она и даёт итоговый результат.

    Sergey Biryukov:

    В ожидании ответа на мой вопрос я решил сам смоделировать
    ситуацию и раскрутить всю эту последовательность вызовов.

    <?php
    // —- Опеделения CBF-функций.
    function CBF_1($value){echo(«</br>Internal CBF_1: » . $value . ‘</br>’); return «Returned by CBF_1»;}
    function CBF_2($value){echo(«</br>Internal CBF_2: » . $value . ‘</br>’); return «Returned by CBF_2»;}
    function CBF_3($value){echo(«</br>Internal CBF_3: » . $value . ‘</br>’); return «Returned by CBF_3»;}
    function CBF_4($value){echo(«</br>Internal CBF_4: » . $value . ‘</br>’); return «Returned by CBF_4»;}

    //—- Добавление фильтров
    add_filter(«someFilter», «CBF_4», 30);
    add_filter(«someFilter», «CBF_3», 20);
    add_filter(«someFilter», «CBF_2», 10);
    add_filter(«someFilter», «CBF_1», 10);

    // —- Применение фильтра
    echo(‘</br>’ . apply_filters(«someFilter»,’Hello filter !’));
    ?>

    Для меня неприятным моментом оказалось то, что возвращаемые
    значения этих функций передаются через аргумент следующей
    в цепочке функции:
    — выход CBF_2 -> на вход CBF_1;
    — выход CBF_1 -> на вход CBF_3;
    — выход CBF_3 -> на вход CBF_4;
    и я получаю выход CBF_4, который в реальной жизни может
    оказаться какой-то мешаниной, а не то, чего я ожидал.

    Вы отметили, что

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

    Я не понял, что вы имеете в виду: если я не знаю, кто и в какой момент
    использует то же самое имя фильтра, но с другой CBF, как я могу
    корректировать результат.

    Спасибо.

    К стати, интересный момент (отсюда)

    Новые фильтры должны иметь уникальные названия и не должны совпадать с уже имеющимися в WP названиями фильтров.

    Не понятно, что это даёт, если я могу под имеющееся уникальное название
    написать свою функцию обратного вызова и вольно или невольно мешать
    другой программе делать свою работу.
    Я могу дать случайное название своему фильтру.
    Под него написать несколько функций обратного вызова (CBF)…
    Они должны как-то согласовывать между собой свою работу…
    Как-то, по-моему, сложновато получается …

    Не понятно, что это даёт, если я могу под имеющееся уникальное название
    написать свою функцию

    Это если в нужном месте уже имеется apply_filters или do_action. А если пишете свою тему или плагин, предполагающие возможность расширения, то и хуки там должны быть свои уникальные.

    вольно или невольно мешать другой программе делать свою работу.

    Коллизии неизбежны. Принимаем это как данность.

    Они должны как-то согласовывать между собой свою работу…

    Это в принципе невозможно в мире свободного ПО. Умышленная совместимость плагина с другими плагинами скорее исключение, чем правило.

    Как-то, по-моему, сложновато получается …

    Естественно. «Программирование — это просто» — тезис из мира рекламы 🙂

Просмотр 4 ответов — с 1 по 4 (всего 4)