formsvalidationcakephpcakephp-3.3

Validating a form that is not ‘add’ or ‘edit’ in Cakephp3.3


I’m learning Cakephp3.3 and have run into a problem trying to validate a form prior to saving.

I created a new form in ‘src/Template/Users’ called ‘register.ctp’ and added an action called ‘register’ in ‘src/Controller/UsersController’.

I want to validate form submissions before saving but can’t figure out how to make this work.

FWIW, pre-save validation works perfectly for the ‘add’ and ‘edit’ forms, though I think this happens by default in Cakephp3.

Is there a way to make these same validation rules apply for the ‘register’ form?

FYI, the 'register' action is actually updating an existing user record previously created for an anonymous user.

Here's the controller action:

<?php
namespace App\Controller;

use App\Controller\AppController;
use Cake\Event\Event;

class UsersController extends AppController
{

//<snipped methods>

public function register()
{
    if($this->request->session()->read('Auth.User'))
    {
        $id = $this->request->session()->read('Auth.User.id');
        if ($this->request->is(['patch', 'post', 'put'])) 
        {
            $user = $this->Users->get($id, [
                'contain' => []
            ]);
            $user = $this->Users->patchEntity($user, $this->request->data);

            if ($this->Users->save($user)) 
            {
                $this->Flash->success(__('Your free trial period has started.'));
                return $this->redirect("/Home/index");
            } 
            else 
            {
                $this->Flash->error(__('We were unable to start your trial. Please, try again.'));
            }
        }
    } 
    else 
    {
        $this->Flash->error(__('Your demo session has expired. Please start again.'));
    }

    $this->set(compact('user'));
    $this->set('_serialize', ['user']);
}
}

Here's the UsersTable Model with the validation rules:

<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

class UsersTable extends Table
{

public function initialize(array $config)
{
    parent::initialize($config);

    $this->table('users');
    $this->displayField('id');
    $this->primaryKey('id');

    $this->addBehavior('Timestamp');

}

public function validationDefault(Validator $validator)
{
    $validator
        ->integer('id')
        ->allowEmpty('id', 'create');

    $validator
        ->email('email')
        ->requirePresence('email')
        ->notEmpty('An email address is required.');

    $validator
        ->requirePresence('password')
        ->notEmpty('A password is required.');

    $validator
        ->requirePresence('firstname')
        ->notEmpty('firstname')
        ->add('firstname', 'minlength',['rule' => ['minlength', 1]]);

    $validator
        ->requirePresence('lastname')
        ->notEmpty('lastname')
        ->add('lastname', 'minlength',['rule' => ['minlength', 1]]);

    $validator
        ->integer('status')
        ->requirePresence('status', 'create')
        ->notEmpty('status');

    $validator
        ->add('role', 'inList', [
            'rule' => ['inlist', ['admin','author','subscriber']],
            'message' => 'Please enter a valid role.'
            ]);

    $validator
        ->requirePresence('referer', 'create')
        ->allowEmpty('referer');

    $validator
        ->integer('plan_id')
        ->requirePresence('plan_id', 'create')
        ->notEmpty('plan_id');

    return $validator;
}

public function buildRules(RulesChecker $rules)
{
    $rules->add($rules->isUnique(['email']));
    return $rules;
}
}

And here's the register.ctp form:

<div class="users form large-12 columns ">
    <?= $this->Form->create() ?>
        <fieldset>
            <legend><?= __('Sign Up For Your No-Risk Free Trial!') ?></legend>
            <?= $this->Form->input('firstname'); ?>
            <?= $this->Form->input('lastname'); ?>
            <?= $this->Form->input('email'); ?>
            <?= $this->Form->input('password'); ?>
        </fieldset>
        <?= $this->Form->button(__('Start My Free Trial Now')) ?>
    <?= $this->Form->end() ?>
</div>

Any help would be greatly appreciated!


Solution

  • if you want to save then the Default validation rules will be apply. if you don't want to apply the default rule then just add the 'validate' => false param

    $user = $this->Users->patchEntity($user, $this->request->data,['validate' => false])
    

    if you want to custom validation rule only for register options then need to create new function in your TABLE

    class UsersTable extends Table
    {
        public function validationRegister($validator)
        {
            $validator
            ->email('email')
            ->requirePresence('email')
            ->notEmpty('An email address is required.');
    
        $validator
            ->requirePresence('password')
            ->notEmpty('A password is required.');
    
        $validator
            ->requirePresence('firstname')
            ->notEmpty('firstname')
            ->add('firstname', 'minlength',['rule' => ['minlength', 1]]);
    
        return $validator;
        }
    }
    

    Now set the 'validate' => 'register' param in your controller newEntity or patchEntity Funciton

    $user = $this->Users->patchEntity($user, $this->request->data,['validate' => 'register'])