Cakephp 3.5自定义验证从模型中读取数据

时间:2018-03-14 15:23:42

标签: php validation cakephp cakephp-3.x

我的下面的代码有效,问题是效率不高。

背景

用户可以从电子表格上传数据,以填充我正在处理的应用。 它们上载的几个字段存在于表中,用于根据需要填充视图中的选择框或字段。 例如。国家表

+----+---------+
| id | country |
+----+---------+
|  1 | UK      |
|  2 | France  |
+----+---------+

电子表格中的数据不是用户友好的ID,因此在电子表格中他们会写文字' UK' France'或者如果他们可以使用ID所以选择,但如果他们通过应用程序中的Web表单编辑数据,将使用ID。

在上传过程中,我将数据排列到一个数组中,其中每个条目都是一个可以验证的新实体,然后我通过Cake的验证器进程传递它。对于上述字段,我有一个自定义验证器,用于检查ID是否存在,或者文本是否与文本字段完全匹配。

代码

验证数据的函数存在于Uploads模型中,并在数据排列后调用(此处不包括在内):

// src/Model/Table/UploadsTable.php

protected function _validateData(array $data) {
    $Validator = TableRegistry::get('Laws')->getValidator('Upload');
    $validation = [];
    foreach( $data as $key => $row) {
        $validation[$key] = $Validator->errors($row);
    }
    return $validation;
}

Laws模型中的验证者

// src/Model/Table/LawsTable.php

public function validationUpload(Validator $validator)
{
    $validator = $this->validationDefault($validator);

    $validator->setProvider("CustomValidator",\App\Model\Validation\CustomValidator::class);

    $validator
        ->scalar('country_id')
        ->requirePresence('country_id')
        ->add('country_id', 'country', [
            'rule' => 'country',
            'provider' => 'CustomValidator',
            'message' => 'Country value not in accepted list.'
        ]);   
}

在自定义验证器

// src/Model/Validation/CustomValidator.php

class CustomValidator extends Validator
{
    public function __construct() {
        parent::__construct();
    }

    public static function country($data) {
        $table = TableRegistry::get('Countries')->find()->toArray();
        $idKey = array_column($table, 'country','id');
        $fieldKey = array_column($table, 'id', 'country');
        if(in_array($data, $idKey) || in_array($data, $fieldKey)) {
            return true;
        }
        return false;        
    }
}

问题

问题是,当用户上传电子表格时,可能有500行,而且我有几个字段遵循此方法。当执行这个脚本时,我得到几千个SQL查询,因为每行调用这些静态函数。领域。

对我来说,明显的解决方案是从方法中删除find()查询,并找到将结果传递给方法的方法,以便脚本的其余部分工作。但我不知道如何提取它们以及将这种数据收集在Cake工作流程中的位置,因为它们被静态调用。

0 个答案:

没有答案