Besser bestimmte Hooks oder generische Hooks mit Parametern abfeuern?

8

Ich erstelle ein Formular-Plugin für Formulare, die von Entwicklern mithilfe von Aktionen / Filtern eingebunden werden können.

Mein Plug-In muss in der Lage sein, verschiedene Formulare mit unterschiedlichen Filtersätzen zu verarbeiten, und ich sehe zwei Möglichkeiten, dies zu tun.

Methode 1

Feuer von bestimmten Haken für jede Form.

Code wie dieser könnte also in meinem Plugin als Form bezeichnet werden:

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

Und könnte so verwendet werden:

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

    return $errors;
} 10, 2)

Methode 2

Übergeben Sie einen Parameter an die aufrufende Funktion.

Code wie dieser könnte also in meinem Plugin als Form bezeichnet werden:

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

Und könnte so verwendet werden:

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)

Gibt es Beispiele im WordPress-Kern, in denen diese Art von Problem angegangen wird?

Gibt es eine bevorzugte Methode, um damit umzugehen?

veganista
quelle

Antworten:

2

Methode 1 ist meiner Meinung nach viel robuster und erweiterbarer.

Methode 1: Um Formulare oder andere Funktionen hinzuzufügen oder zu entfernen, fügen Sie einfach Funktionen hinzu oder entfernen sie. Dies können Sie insbesondere aus anderen Dateien heraus tun, z. B. aus separaten Modulen Ihres Plugins oder anderen externen Plugins. Ich denke, dies ist das Hauptargument dafür: Erweiterbarkeit und Modularität.

Methode 2: Um Formulare oder andere Funktionen hinzuzufügen oder zu entfernen, müssen Sie eine vorhandene Funktion ändern, die viel fehleranfälliger ist. Eine switch-Anweisung wie die in Methode 2 gerät leicht außer Kontrolle. Die Liste der Fälle kann sehr lang werden, und es ist einfach, Fehler einzuführen, sobald Sie mehrere Filter mit derselben Art von switch-Anweisung haben. Beispielsweise möchten Sie möglicherweise Filter zur Validierung, zum Ausfüllen leerer Formulare, zum Anzeigen des Inhalts ausgefüllter Formulare, zur Datenbankverwaltung usw. Sie haben jetzt eine Reihe von Funktionen mit jeweils einer sehr langen Liste von Switch-Fällen , dass Sie synchron bleiben müssen.

(Ich habe einige schlechte Erfahrungen mit einer beliebten Erweiterung für Schwerkraftformen gemacht - es ist nicht unüberschaubar, wenn Sie diszipliniert sind, z. B. die Liste der Fälle in allen Funktionen in derselben Reihenfolge zu halten, aber es ist auch nicht schön.)

Auffinden von Fehlern: Mit Methode 1 viel einfacher: Der Schuldige ist normalerweise der neu hinzugefügte Filter oder die neu hinzugefügte Form, anstatt ein Tippfehler, der versehentlich in diese sehr lange Funktion von Methode 2 eingeführt wurde.

Beispiele: Im WordPress-Kern finden Sie unzählige Beispiele für Methode 1 (z. B. https://developer.wordpress.org/?s=post+type&post_type[‹=wp-parser-hook ), aber ich erinnere mich nicht eine einzelne Instanz von Methode 2.

adelval
quelle
4

Machen Sie den Hook-Namen spezifisch für das, was er tut, nicht für den Ort, an dem er aufgerufen wird. Übergeben Sie nicht mehrere Parameter, da dies nicht einfach zu erweitern ist. Übergeben Sie stattdessen ein Parameterobjekt.

Beispiel

Erstellen Sie das Parameterobjekt mit einer Schnittstelle für die Abhängigkeitsinjektion:

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

Übergeben Sie es nun in Ihren Filter:

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

Ein Entwickler eines Drittanbieters kann es jetzt lesen, aber nicht ändern, sodass sich die anderen auf seine Struktur verlassen können, da es keine Möglichkeit gibt, es zu beschädigen.

add_filter( 'form_is_valid', function( $bool, Validation_Parameters $params ) {
    // do something and return a value
});
Fuxia
quelle
Obwohl mir Ihre Idee gefällt, ein Objekt für die Filterparameter zu durchlaufen, bin ich mir nicht sicher, ob es meine ursprüngliche Frage beantwortet. Was meinen Sie auch mit: "Machen Sie den Hook-Namen spezifisch für das, was er tut, nicht dort, wo er heißt". Im obigen Beispiel sollte das 'forms_validate' eingebunden werden, um das Formular basierend auf den übergebenen $ -Daten zu validieren habe die Frage geändert, um dies ein bisschen klarer zu machen
veganista