Лучше использовать определенные хуки или общие хуки с параметрами?

8

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

Мой плагин должен иметь возможность обрабатывать разные формы с разными наборами фильтров, и я вижу 2 способа сделать это.

Способ 1

Огонь конкретных крючков для каждой формы.

Так что код, подобный этому, можно назвать формой в моем плагине:

$formId = 'contact';
$errors = apply_filters('forms_validate_' . $formId, $errors, $data);

И может быть использовано так:

add_filter('forms_validate_contact', function($errors, $data){
    if(empty($data['name'])){
        $errors['name'] = 'Name is required';
    }

    return $errors;
} 10, 2)

Способ 2

Передайте параметр вызывающей функции.

Так что код, подобный этому, можно назвать формой в моем плагине:

$formId = 'contact';
$errors = apply_filters('forms_validate', $formId, $errors, $data);

И может быть использовано так:

add_filter('forms_validate', function($formId, $error, $data){
    switch($formId){
        case 'contact':
            if(empty($data['name'])){
                $errors['name'] = 'Name is required';
            }
        break;
    }

    return $errors;
}, 10, 3)

Есть ли примеры в ядре WordPress, где решается такая проблема?

Есть ли предпочтительный метод борьбы с этим?

veganista
источник

Ответы:

2

Метод 1, на мой взгляд, гораздо более надежный и расширяемый.

Способ 1. Чтобы добавить или удалить формы или другие функции, вы просто добавляете или удаляете функции. В частности, вы можете сделать это из других файлов, таких как отдельные модули вашего плагина или других внешних плагинов. Я думаю, что это главный аргумент в его пользу: расширяемость и модульность.

Способ 2: чтобы добавить или удалить формы или другие функции, вам нужно изменить существующую функцию, которая гораздо более подвержена ошибкам. Оператор switch, такой как в методе 2, легко выходит из-под контроля. Список наблюдений может быть очень длинным, и легко вносить ошибки, если у вас есть несколько фильтров с одним и тем же типом оператора switch. Например, вам могут потребоваться фильтры для проверки, отображение пустых форм, отображение содержимого заполненных форм, управление базой данных, ... Итак, теперь у вас есть набор функций, каждая из которых содержит очень длинный список вариантов переключения. , что вы должны держать в синхронизации.

(У меня был некоторый плохой опыт этого с популярным расширением для гравитационных форм - это неуправляемо, если вы дисциплинированы, например, сохраняете список дел в одном порядке во всех функциях, но это тоже не очень красиво.)

Обнаружение ошибок: намного проще с методом 1: виновником, как правило, будет вновь добавленный фильтр или форма, а не некоторая опечатка, непреднамеренно введенная в эту очень длинную функцию метода 2.

Примеры: вы найдете множество примеров метода 1 в ядре wordpress (например, https://developer.wordpress.org/?s=post+type&post_type[]=wp-parser-hook ), но я не помню один экземпляр метода 2.

adelval
источник
4

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

пример

Создайте объект параметра с интерфейсом для внедрения зависимости:

interface Validation_Parameters {

    public function id();

    public function errors();

    // not a good name …
    public function details();
}

class Form_Validation_Parameters implements Validation_Parameters {

    private $id;

    private $errors;

    private $details;

    public function __construct( $id, $errors, $details ) {

        $this->id      = $id;
        $this->errors  = $errors;
        $this->details = $details;
    }

    public function id() {
        return $this->id;
    }

    public function errors() {
        return $this->errors;
    }

    public function details() {
        return $this->details;
    }
}

$params = new Form_Validation_Parameters( 
    'contact',
    new WP_Error(), // should be prepared better.
    [ 'request' => $_SERVER['REQUEST_URI'] ]
);

Теперь передайте это в ваш фильтр:

$valid = apply_filters( 'form_is_valid', TRUE, $params );

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

add_filter( 'form_is_valid', function( $bool, Validation_Parameters $params ) {
    // do something and return a value
});
Фуксия
источник
Хотя мне нравится ваша идея прохождения объекта для параметров фильтра, я не уверен, что он отвечает на мой первоначальный вопрос. Кроме того, что вы подразумеваете под: «Сделайте имя перехвата специфичным для того, что оно делает, а не там, где оно называется». В приведенном выше примере необходимо подключить «forms_validate» для проверки формы на основе переданных $ data, я изменили вопрос, чтобы сделать это немного яснее
veganista