【问题标题】:Checking if at least one field is set using CakePHP 3 validation使用 CakePHP 3 验证检查是否设置了至少一个字段
【发布时间】:2017-05-02 09:54:18
【问题描述】:

我正在尝试在 CakePHP 3 中编写一个验证规则来检查是否设置了前名和姓氏或公司名称。

验证器:

$validator
    ->add('prename', 'custom', [
        'rule' => [$this, 'validateName'],
        'message' => __('Prename and lastname OR company name must be set.')
    ]);

$validator
    ->add('lastname', 'custom', [
        'rule' => [$this, 'validateName'],
        'message' => __('Prename and lastname OR company name must be set.')
    ]);

$validator
    ->add('name', 'custom', [
        'rule' => [$this, 'validateName'],
        'message' => __('Prename and lastname OR company name must be set.')
    ]);

规则定义:

public function validateName($check, array $context)
{
    if((!empty($context['data']['prename']) && !empty($context['data']['lastname'])) || !empty($context['data']['name'])){
        return true;
    } else {
        return false;
    }
}

但验证的行为与预期不符。如果我输入公司名称,我会收到 prename 和 lastname 的验证错误,表明这些字段是必需的。当我输入前名和姓氏时,它说公司名称是必需的。

我做错了什么?

【问题讨论】:

  • 如果你想让这些文件为空,请使用 allowEmpty()
  • 这不是我想要的,但还是谢谢。

标签: php validation cakephp cakephp-3.0


【解决方案1】:

我在 cakePhp 3.x 中也遇到过这种奇怪的行为。我设法解决了这个问题。

下面是解决问题的代码

    $validator
        ->notEmpty('company_name', 'Prename and lastname OR company name must be set.', function ($context){      
            if((!empty($context['data']['prename']) && !empty($context['data']['lastname'])) || !empty($context['data']['name'])){

                return false;
            } else {
                return true;
            }
        });

    $validator
        ->notEmpty('prename', 'Prename and lastname OR company name must be set.', function ($context){
            if((!empty($context['data']['prename']) && !empty($context['data']['lastname'])) || !empty($context['data']['name'])){

                return false;
            } else {
                return true;
            }
        });
    $validator
        ->notEmpty('lastname', 'Prename and lastname OR company name must be set.', function ($context){
           if((!empty($context['data']['prename']) && !empty($context['data']['lastname'])) || !empty($context['data']['name'])){
                return false;
            } else {

                return true;
            }
        });

我希望这将是您的问题的解决方案。

【讨论】:

    【解决方案2】:

    提供的答案都没有 100% 有效,所以我将发布我想出的答案。我正在使用 conditional validation,如 CakePHP 3 文档中所述。

    CustomersTable.php:

    public function validationDefault(Validator $validator)
    {
        $validator->notEmpty('name', __("Required when prename and lastname is empty."), function ($context) {
            return !$context['data']['prename'] && !$context['data']['lastname'];
        });
    
        $validator->notEmpty('prename', __('Required when company or lastname is empty.'), function ($context) {
            return !$context['data']['name'];
        });
    
        $validator->notEmpty('lastname', __('Required if company or prename is empty.'), function ($context) {
            return !$context['data']['name'];
        });
    
        return $validator;
    }
    

    这种方法可以在提交数据时正确验证数据。但是,一些浏览器表示必须填写这些字段,因为它们是必需的。为了避免这种情况,我们必须将字段定义为required => false:

    add.ctp 查看文件:

    echo $this->Form->input('prename', [
       'label' => ['text' => __('Prename (*): ')],
       'required' => false,
    ]);
    
    echo $this->Form->input('lastname', [
       'label' => ['text' => __('Lastname (*): ')],
       'required' => false,
    ]);
    
    echo $this->Form->input('name', [
       'label' => ['text' => __('Company name (*): ')],
       'required' => false,
    ]);
    

    【讨论】:

      【解决方案3】:

      我们在生产环境中运行以下代码,与您的非常相似:

      $validator
          ->add('various_fee_text', 'custom', [
              'rule' => [$this, 'variousFieldsChecker'],
              'message' => __('Udfyld både Tekst og DKK feltet'),
          ])
          ->allowEmpty('various_fee_text');
      

      有效性规则:

      /**
       * Method checks whether or not various fee text and various fee prices are either both empty, both set or "dirt",
       * meaning only one of them is set and the other is empty. We want either both to be set or both to be empty.
       *
       * @return bool depending on it's OK or not
       */
      public function variousFieldsChecker($value, $context)
      {
          $varioustext = $context['data']['various_fee_text'];
          $variousPrice = $context['data']['various_fee_price'];
      
          if (!empty($varioustext) && !empty($variousPrice)) {
              return true;
          } elseif ((empty($varioustext) && empty($variousPrice))) {
              return true;
          }
      
          return false;
      }
      

      我认为您需要像之前建议的那样附加->allowEmpty()。

      【讨论】:

        【解决方案4】:

        为此 CakePhp 提供创建自定义验证。您需要在模型类上创建两个验证函数,并在控制器函数上有条件地调用它们。您可以创建验证函数,如

            public function validationName($validator){
        
               $validator
               ->requirePresence('prename')
               ->notEmpty('prename', 'Prename must be set.')
        
               ->requirePresence('lastname')
               ->notEmpty('lastname', 'Lastname must be set.')
        
               ->allowEmpty('name');
        
               return $validator;
           }
        
        
        
        public function validationCompany($validator){
        
               $validator
               ->requirePresence('name')
               ->notEmpty('name', 'Company name must be set.')
        
               ->allowEmpty('prename')
               ->allowEmpty('lastname');
        
               return $validator;
           }
        

        在控制器上,您可以有条件地调用这些函数,如

        $validator = 'company';
        if(empty($this->request->data[''])){
          $validator = 'name';
        }
        $entity = $this->{$this->modelClass}->newEntity();
        $entitydata = $this->{$this->modelClass}->patchEntity($entity, $this->request->data, ['validate' => $validator]);
        
        $this->{$this->modelClass}->save($entitydata);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-10
          • 2022-01-11
          • 1970-01-01
          • 1970-01-01
          • 2012-04-14
          • 2012-08-18
          相关资源
          最近更新 更多