CakePHP 4 How To Create Custom Validation Rule

Reading Time: 9 minutes
2,640 Views

Inside this article we will see CakePHP 4 How To Create Custom Validation Rule. This tutorial will help you to understand about implementing custom validation rules in CakePHP forms. We will see the classified information about Validator and it’s method to create custom form validation rule.

In any application where we have forms to take user data we add form validations. So in this case we will create a simple form with few form input fields like name, email, mobile_no. We will see the concept of custom form validation rule of about name field for value length.

Learn More –

Let’s get started.

CakePHP 4 Installation

To create a CakePHP project, run this command into your shell or terminal. Make sure composer should be installed in your system.

$ composer create-project --prefer-dist cakephp/app:~4.0 mycakephp

Above command will creates a project with the name called mycakephp.

Create Database

To create a database, either we can create via Manual tool of PhpMyadmin or by means of a mysql command.

CREATE DATABASE mydatabase;

Successfully, we have created a database.

Database Connection

Open app_local.php file from /config folder. Search for Datasources. Go to default array of it.

You can add your connection details here to connect with your database. It will be like this –

//...

'Datasources' => [
        'default' => [
            'host' => 'localhost',
            /*
             * CakePHP will use the default DB port based on the driver selected
             * MySQL on MAMP uses port 8889, MAMP users will want to uncomment
             * the following line and set the port accordingly
             */
            //'port' => 'non_standard_port_number',

            'username' => 'root',
            'password' => 'sample@123',

            'database' => 'mydatabase',
            /*
             * If not using the default 'public' schema with the PostgreSQL driver
             * set it here.
             */
            //'schema' => 'myapp',

            /*
             * You can use a DSN string to set the entire configuration
             */
            'url' => env('DATABASE_URL', null),
        ],
  
     //...

//...

You can pass host, username, password and database.

Successfully, you are now connected with the database.

How To Use Validator

There are few steps which needs to be taken care before using validator in CakePHP.

  • Load Validator
  • Create an instance
  • Create custom validation rule using add() method
  • Get validation errors

Load Validator

use Cake\Validation\Validator;

Create an Instance

$validator = new Validator();

Create custom validation

Syntax

$validator->add(fieldName, ruleName, [ "rule" => function(){} ]);

Example

$validator->add("name", "_length", [
    "rule" => function($value, $context){
        if(empty($value)){
            return "Name field required";
        }

        if(strlen($value) < 5){
            return "Name must be greater than 4 characters";
        }

        if(strlen($value) > 20){
            return "Name must be less than 20 characters";
        }

        return true;
    }
]);

Checking for Errors

$errors = $validator->errors($formData);

Let’s see all these in action.

Create Migrations

Open project into terminal run this migration command.

$ bin/cake bake migration CreateEmployees

Above command will create a file 20220317154654_CreateEmployees.php inside /config/Migrations folder.

Open 20220317154654_CreateEmployees.php and write this following into it. It will create employees table into database.

<?php
declare(strict_types=1);

use Migrations\AbstractMigration;

class CreateEmployees extends AbstractMigration
{
    public function change()
    {
        $table = $this->table('employees');

        $table->addColumn("name", "string", [
            "limit" => 50,
            "null" => false
        ]);

        $table->addColumn("email", "string", [
            "limit" => 50,
            "null" => false
        ]);

        $table->addColumn("mobile_no", "string", [
            "limit" => 20,
            "null" => false
        ]);

        $table->create();
    }
}

Run Migration

Run migration to create a database table.

$ bin/cake migrations migrate

Table: employees

Create Model & Entity

Open project into terminal run this bake console command.

$ bin/cake bake model Employees --no-validation --no-rules

It will create a Model file with Entity class as well.

Open EmployeesTable.php from /src/Model/Table folder and write this following code into it.

<?php
declare(strict_types=1);

namespace App\Model\Table;

use Cake\ORM\Table;

class EmployeesTable extends Table
{
    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('employees');
        $this->setPrimaryKey('id');
    }
}

Open Employee.php from /src/Model/Entity folder and write this following code into it.

<?php
declare(strict_types=1);

namespace App\Model\Entity;

use Cake\ORM\Entity;

class Employee extends Entity
{
    protected $_accessible = [
        'name' => true,
        'email' => true,
        'mobile_no' => true,
    ];
}

Create Controller

Again, back to terminal and this bake console command to create controller class.

$ bin/cake bake controller Employees --no-actions

It will create a controller class EmployeesController.php inside /src/Controller folder. Open and write this following code into it.

<?php

declare(strict_types=1);

namespace App\Controller;

use Cake\Validation\Validator;

class EmployeesController extends AppController
{
    public function initialize(): void
    {
        parent::initialize();

        $this->loadModel("Employees");
    }

    public function addEmployee()
    {
        $employeeEntity = $this->Employees->newEmptyEntity();

        if ($this->request->is("post")) {

            $validator = new Validator();

            $formData = $this->request->getData();

            $validator->add("name", "_length", [
                "rule" => function($value, $context){
                    if(empty($value)){
                        return "Name field required";
                    }

                    if(strlen($value) < 5){
                        return "Name must be greater than 4 characters";
                    }

                    if(strlen($value) > 20){
                        return "Name must be less than 20 characters";
                    }

                    return true;
                }
            ]);

            $errors = $validator->errors($formData);

            if (!empty($errors)) {
                // errors
                $this->set(compact("errors"));
            } else {
                // form submission
                print_r($formData);
                // You can save your data here..
            }
        }

        $this->set(compact("employeeEntity"));
    }
}

Create Template File

Create a folder with controller name i.e Employees inside /templates folder. Create a file add_employee.php into /templates/Employees folder.

In this template file we will create Add employee form. Also we are handling validation error and displaying error message into it for name field.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>CakePHP 4 Server Side Validation Using Validator</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

    <style>
        span.error {
            color: red;
        }
    </style>
</head>

<body>

    <div class="container">
        <h4>CakePHP 4 Server Side Validation Using Validator</h4>
        <div class="panel panel-primary">
            <div class="panel-heading">Employee Form</div>
            <div class="panel-body">
                <?= $this->Form->create($employeeEntity, ["class" => "form-horizontal"]) ?>
                <div class="form-group">
                    <label class="control-label col-sm-2" for="name">Name:</label>
                    <div class="col-sm-10">
                        <input type="name" class="form-control" id="name" name="name" placeholder="Enter name">
                        <span class="error"><?php echo isset($errors['name']['_length']) ? $errors['name']['_length'] : ""; ?></span>
                    </div>
                </div>
                <div class="form-group">
                    <label class="control-label col-sm-2" for="email">Email:</label>
                    <div class="col-sm-10">
                        <input type="email" class="form-control" id="email" name="email" placeholder="Enter email">
                    </div>
                </div>
                <div class="form-group">
                    <label class="control-label col-sm-2" for="mobile_no">Mobile:</label>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" id="mobile_no" name="mobile_no" placeholder="Enter number">
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <button type="submit" class="btn btn-success">Submit</button>
                    </div>
                </div>
                <?= $this->Form->end() ?>
            </div>
        </div>
    </div>

</body>

</html>

Accessing error message –

<?php echo isset($errors['name']['_length']) ? $errors['name']['_length'] : ""; ?>

name is the field name and _length is the rule name.

Disable CSRF Token

When we submit a cakephp form, it needs a CSRF token should be submitted with form submission request.

We are not interested to send CSRF token with form data. To disable it, Open Application.php from /src folder.

Remove these lines of code from middleware() method.

->add(new CsrfProtectionMiddleware([
    'httponly' => true,
]))

Create Route

Open routes.php file from /config folder. Add this route into it.

//...

$routes->connect(
    '/add-employee',
    ['controller' => 'Employees', 'action' => 'addEmployee']
);

//...

Application Testing

To execute start development server.

$ bin/cake server

URL: http://localhost:8765/add-employee

When we submit form without passing any value to it.

Pass value more than 20 characters into name field.

We hope this article helped you to learn CakePHP 4 How To Create Custom Validation Rule in a very detailed way.

Online Web Tutor invites you to try Skillshike! Learn CakePHP, Laravel, CodeIgniter, Node Js, MySQL, Authentication, RESTful Web Services, etc into a depth level. Master the Coding Skills to Become an Expert in PHP Web Development. So, Search your favourite course and enroll now.

If you liked this article, then please subscribe to our YouTube Channel for PHP & it’s framework, WordPress, Node Js video tutorials. You can also find us on Twitter and Facebook.