Mieux vaut tirer des crochets spécifiques ou des crochets génériques avec des paramètres?

8

Je crée un plugin de formulaire pour gérer les formulaires qui peuvent être connectés à l'aide d'actions / filtres par les développeurs.

Mon plug-in doit pouvoir gérer différentes formes avec différents ensembles de filtres et je vois 2 façons de le faire.

Méthode 1

Incendie de crochets spécifiques pour chaque forme.

Donc, un code comme celui-ci pourrait être appelé formulaire dans mon plugin:

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

Et pourrait être utilisé comme ceci:

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

    return $errors;
} 10, 2)

Méthode 2

Passez un paramètre à la fonction appelante.

Donc, un code comme celui-ci pourrait être appelé formulaire dans mon plugin:

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

Et pourrait être utilisé comme ceci:

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)

Existe-t-il des exemples dans le noyau WordPress où ce type de problème est résolu?

Existe-t-il une méthode préférée pour y faire face?

veganista
la source

Réponses:

2

La méthode 1 est à mon avis beaucoup plus robuste et extensible.

Méthode 1: pour ajouter ou supprimer des formulaires ou d'autres fonctionnalités, il vous suffit d'ajouter ou de supprimer des fonctions. En particulier, vous pouvez le faire à partir d'autres fichiers, tels que des modules séparés de votre plugin ou d'autres plugins externes. Je pense que c'est l'argument principal en sa faveur: l'extensibilité et la modularité.

Méthode 2: pour ajouter ou supprimer des formulaires ou d'autres fonctionnalités, vous devez modifier une fonction existante, qui est beaucoup plus sujette aux bogues. Une instruction switch comme celle de la méthode 2 devient facilement incontrôlable. La liste des cas peut être très longue, et il est facile d'introduire des bogues dès que vous avez plusieurs filtres avec le même type de déclaration switch. Par exemple, vous pouvez souhaiter des filtres pour la validation, l'affichage des formulaires vides à remplir, l'affichage du contenu des formulaires remplis, la gestion de la base de données, ... Alors maintenant, vous avez un tas de fonctions chacune avec une très longue liste de cas de commutation , que vous devez synchroniser.

(J'ai eu une mauvaise expérience de cela avec une extension populaire pour les formes de gravité - ce n'est pas ingérable si vous êtes discipliné, par exemple, gardez la liste des cas dans le même ordre dans toutes les fonctions, mais ce n'est pas joli non plus.)

Localisation des bogues: beaucoup plus facile avec la méthode 1: le coupable sera généralement le filtre ou le formulaire nouvellement ajouté, plutôt qu'une faute de frappe introduite par inadvertance dans cette très longue fonction de la méthode 2.

Exemples: Vous trouverez des tonnes d'exemples de la méthode 1 dans le noyau de wordpress (par exemple https://developer.wordpress.org/?s=post+type&post_type[]=wp-parser-hook ), mais je ne me souviens pas une seule instance de la méthode 2.

adelval
la source
4

Rendez le nom du hook spécifique à ce qu'il fait, pas à l'endroit où il est appelé. Ne passez pas plusieurs paramètres, car ce n'est pas facile à étendre. Passez un objet paramètre à la place.

Exemple

Créez l'objet paramètre avec une interface pour l'injection de dépendances:

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'] ]
);

Maintenant, passez-le dans votre filtre:

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

Un développeur tiers peut le lire maintenant, mais pas le modifier, afin que les autres puissent se fier à sa structure, car il n'y a aucun moyen de le corrompre.

add_filter( 'form_is_valid', function( $bool, Validation_Parameters $params ) {
    // do something and return a value
});
fuxia
la source
Bien que j'aime votre idée de passer à travers un objet pour les paramètres de filtre, je ne suis pas sûr qu'elle réponde à ma question initiale. De plus, que voulez-vous dire par: "Rendre le nom du hook spécifique à ce qu'il fait, pas à l'endroit où il est appelé" Dans l'exemple ci-dessus, le 'forms_validate' doit être connecté pour valider le formulaire en fonction des données $ transmises, je ont modifié la question pour que ce soit un peu plus clair
veganista