Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Проверка данных

Данные формы нельзя сохранять не глядя: заголовок может оказаться пустым, а почта — набором букв. CakePHP проверяет данные в два этапа. Валидация смотрит на формат присланных значений. Правила приложения проверяют то, для чего нужна база: не занято ли значение, существует ли связанная запись.

Где лежат правила

Оба набора находятся в классе таблицы — src/Model/Table/ArticlesTable.php. Команда bake model создаёт их заготовки по столбцам таблицы, дальше их правят вручную.

Валидация

// src/Model/Table/ArticlesTable.php
use Cake\Validation\Validator;
 
public function validationDefault(Validator $validator): Validator
{
    $validator
        ->notEmptyString('title', 'Введите заголовок.');
 
    return $validator;
}

Правило одно: заголовок не должен быть пустым. Второй аргумент — сообщение об ошибке.

Когда она срабатывает

Валидация выполняется внутри patchEntity() и newEntity():

$article = $this->Articles->newEntity(['title' => '']);
 
debug($article->getErrors());

debug() покажет массив с ключом title и текстом «Введите заголовок.». Ошибки хранятся в самой записи, а save() такую запись не сохранит и вернёт false.

Несколько правил

$validator
    ->requirePresence('title', 'create')
    ->notEmptyString('title', 'Введите заголовок.')
    ->minLength('title', 5, 'Заголовок должен быть не короче 5 символов.')
    ->maxLength('title', 255);
 
$validator
    ->notEmptyString('body', 'Введите текст.')
    ->boolean('published');

Правила одного поля записывают цепочкой. requirePresence('title', 'create') требует, чтобы при создании записи поле вообще было в данных.

Частые правила

МетодЧто проверяет
notEmptyString('field')Значение не пустое
allowEmptyString('field')Значение может быть пустым
minLength(), maxLength()Длина строки
email('field')Адрес почты
integer('field'), decimal('field')Число
inList('field', ['a', 'b'])Одно из значений
date('field')Дата
sameAs('password_confirm', 'password')Совпадение с другим полем

Правила приложения

use Cake\ORM\RulesChecker;
 
public function buildRules(RulesChecker $rules): RulesChecker
{
    $rules->add($rules->isUnique(['title'], 'Статья с таким заголовком уже есть.'));
 
    return $rules;
}

isUnique() заглядывает в базу и не даёт сохранить вторую статью с тем же заголовком. Правила приложения выполняются позже валидации — при вызове save(). Ещё одно готовое правило — existsIn(['article_id'], 'Articles'): связанная запись должна существовать.

Своё правило

$validator->add('title', 'noShouting', [
    'rule' => fn (string $value) => $value !== mb_strtoupper($value),
    'message' => 'Не пишите заголовок одними заглавными буквами.',
]);

Функция получает значение поля и возвращает true, если оно подходит. noShouting — произвольное имя правила.

Частая ошибка

Валидация проверяет только данные, пришедшие через patchEntity() или newEntity(). Значение, заданное в коде, — $article->title = '' — пройдёт мимо неё. Правила, от которых зависит целостность данных, — уникальность, существование связанной записи — пишите в buildRules(): они проверяют запись при каждом сохранении.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.