パラメータ付きの特定のフックまたは汎用フックを起動する方が良いですか?


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コアの例はありますか?

これを処理する好ましい方法はありますか?

回答:


2

私の意見では、方法1ははるかに堅牢で拡張可能です。

方法1:フォームやその他の機能を追加または削除するには、関数を追加または削除するだけです。特に、プラグインの別のモジュールや他の外部プラグインなど、他のファイルからこれを行うことができます。これは、拡張性とモジュール性という賛成の主な議論だと思います。

方法2:フォームやその他の機能を追加または削除するには、既存の関数を変更する必要があり、バグが発生しやすくなります。方法2のようなswitchステートメントは簡単に手に負えなくなります。ケースのリストは非常に長くなる可能性があり、同じ種類のswitchステートメントを含む複数のフィルターを作成するとすぐにバグが発生しやすくなります。たとえば、検証用のフィルター、入力する空のフォームの表示、入力したフォームの内容の表示、データベース管理などが必要になる場合があります。これで、スイッチケースの非常に長いリストを持つ関数の束ができました。 、同期を保つ必要があります。

(重力フォームの人気のある拡張機能を使用して、これについていくつかの悪い経験がありました-規律付けされている場合は管理できません。たとえば、すべての関数でケースのリストを同じ順序で保持しますが、どちらもきれいではありません。)

バグの特定:方法1の方がはるかに簡単:通常、原因は、新しく追加されたフィルターまたはフォームであり、方法2の非常に長い関数で誤って導入された誤植ではありません。

例:ワードプレスのコア(例:https : //developer.wordpress.org/? s=post+type & post_type[]=wp-parser-hook )には、方法1の例がたくさんありますが、覚えていません方法2の単一インスタンス。


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
});

フィルターパラメーターのオブジェクトを通過するというあなたのアイデアは好きですが、それが私の最初の質問に答えているかどうかはわかりません。また、どういう意味ですか:「フック名を、それが呼び出される場所ではなく、その機能に固有にする」上記の例では、渡された$ dataに基づいてフォームを検証するために、「forms_validate」をフックする必要があります。これを少し明確にするために質問を変更しました
veganista '29
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.