perl_noobee
perl_noobee

Reputation: 63

Cakephp 3 Not Recognizing Custom Validation Rule Method and Validation Messages Not Showing

First issue is I have the following validators and public function in my table

UsersTable.php

   $validator
        ->scalar('name')
        ->maxLength('name', 45)
        ->requirePresence('name', 'create')
        ->notEmptyString('name', 'You must enter a name for the user.');

   $validator
       ->add('name', 'custom', array('rule' => 'checkExistingUser', 'message' => 'This user already appears to be in the system.', 'on' => 'create'));

   public function checkExistingUser($value,$context)
{
    return $this->find('all', ['conditions' => ['Users.name' => $context['data']['name'], 'Users.user_type_id' => $context['data']['user_type_id']]])->count() < 1 ;

}

When I save the form below I receive the message "Method checkExistingUser does not exist". Why doesn't it recognize the method when it's clearly defined in the table model? Am I missing something?

add.ctp

<?php echo $this->Form->create($user);?>
    <fieldset>
            <legend><?php echo __('Add User'); ?></legend>
    <?php
            echo $this->Form->control('name', ['type' => 'text']);
        echo $this->Form->control('user_type_id');
    echo $this->Form->control('owner', array('type' => 'text', 'label' => "Owner Name"));
    echo $this->Form->control('owner_contact', array('type' => 'text', 'label' => "Owner Contact (phone, email etc)"));
    echo $this->Form->control('description', ['type' => 'textarea']);
            echo $this->Form->control('ia_exception', array('type' => 'text', 'label' => "IA Exception Number"));
            echo $this->Form->control('is_manual', array('type' => 'checkbox', 'label' => "Password Updated Manually"));
            echo $this->Form->control('Environment', ['type' => 'select', 'multiple' => 'true', 'label' => 'Environment(s)']);
    ?>
    </fieldset>
<div class="buttons">
<?php
echo $this->Form->button('Save', ['type'=> 'submit', 'name' => 'submit']);
echo $this->Form->button('Cancel', ['type' => 'button', 'name'=>'cancel', 'onClick' => 'history.go(-1);return true;']);
echo $this->Form->end();
?>
</div>

UsersController.php

    function add() {

            $user = $this->Users->newEntity();

            if ($this->request->is('post')) {
                    $user = $this->Users->patchEntity($user, $this->request->data);

                    if ($this->Users->save($user)) {
                            $this->Flash->set('The user has been saved');
                            return $this->redirect(array('action' => 'index'));
                    } else {
                            $this->Flash->set('The user could not be saved. Please, try again.');
                    }
            }
            $userTypes = $this->Users->UserTypes->find('list');
            $changeSteps = $this->Users->ChangeSteps->find('list');
            $environments = $this->Users->Environments->find('list');
            $this->set(compact('user','userTypes', 'changeSteps', 'environments'));
    }

Second issue is when I try to submit my form to check that the validator is working correctly for an empty name field I don't receive the message 'You must enter a name for the user'. Instead I receive a message stating 'This field is required'. Why is it not showing my message from notEmptyString? And where is 'This field is required' coming from?

Upvotes: 1

Views: 804

Answers (2)

gdm
gdm

Reputation: 7920

Be careful with custom methods for validation during patching, because Cake expects string to be returned, otherwise it will rendere default meassage. So for example, if we use a custom validation function during patching

 // in a Controller
 $this->Users->patchEntity($user, $data, ['validate' => 'custom');

Same applies for closures.

 // in UserTable.php
 public function validationCustom(Validator $validator) {
        $validator = $this->validationDefault($validator);
        $validator           
        ->minLength('password',8,'At least 8 digits');
        $validator->add('password',  
            'strength_light',[
                'rule' => 'passwordCheck',
                'provider' => 'table',               
                'message' => 'At least a number and a capital letter'
            ]
            );
        return $validator;
    }
    public function passwordCheck ($value = "") {            
        return preg_match("/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}/",$value);
}

This will return default message and not the custom one ("At least..") because we set a callable not-cakephp function as rule for custom validation, so the message should be returned by the called function:

 public function passwordCheck ($value = "") {            
     if (!preg_match("/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}/",$value))
         return "At least a number and a capital letter";

    }

Upvotes: 0

perl_noobee
perl_noobee

Reputation: 63

For the first issue, I had to add a provider in my validator.

I changed

 $validator
   ->add('name', 'custom', array('rule' => 'checkExistingUser', 'message' => 'This user already appears to be in the system.', 'on' => 'create'));

To this

  $validator
       ->add('name', 'custom', ['rule' => 'checkExistingUser', 'provider' => 'table', 'message' => 'This user already appears to be in the system.', 'on' => 'create']);

Upvotes: 2

Related Questions