问题描述

我正在创建一个表单插件来处理可以通过开发人员使用动作/过滤器挂钩的表单。

我的 plug-in 需要能够处理不同的形式与不同的过滤器集,我看到两种方法。

方法 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 核心中有哪些例子可以解决这类问题?

有没有办法处理这个?

最佳解决方案

使钩子名称具体到它的作用,而不是在哪里被调用。不要传递多个参数,因为这不容易扩展。换一个参数对象。

例子

使用用于依赖注入的接口创建参数对象:

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

一个 third-party 开发人员现在可以读取它,但不能改变它,所以其他人可以依靠它的结构,因为没有办法破坏它。

add_filter( 'form_is_valid', function( $bool, Validation_Parameters $params ) {
    // do something and return a value
});

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。