Поведения
Поведение — готовый кусок логики, который подключают к классу таблицы одной строкой. Оно срабатывает само при сохранении или поиске. Так общий код — метки времени, создание адреса из заголовка — пишут один раз и используют в любых таблицах.
Подключение
Поведения подключают в методе initialize() класса таблицы:
// src/Model/Table/ArticlesTable.php
public function initialize(array $config): void
{
parent::initialize($config);
$this->addBehavior('Timestamp');
}Timestamp при создании записи заполняет столбец created, а при каждом сохранении — modified. Сохраните статью через форму и посмотрите в базу: обе даты проставлены, хотя в коде о них нет ни слова.
Встроенные поведения
| Поведение | Что делает |
|---|---|
Timestamp | Заполняет created и modified |
CounterCache | Хранит число связанных записей в столбце родителя |
Translate | Переводы полей на разные языки |
Tree | Вложенные категории |
Настройки поведения
Вторым аргументом передают настройки:
// src/Model/Table/CommentsTable.php
$this->belongsTo('Articles');
$this->addBehavior('CounterCache', [
'Articles' => ['comment_count'],
]);Теперь при добавлении и удалении комментария в столбце comment_count таблицы articles обновляется их число. Столбец нужно заранее создать миграцией.
Своё поведение
Свои поведения лежат в папке src/Model/Behavior. Создадим поведение, которое делает из заголовка адрес статьи — слаг:
bin/cake bake behavior Sluggable// src/Model/Behavior/SluggableBehavior.php
namespace App\Model\Behavior;
use ArrayObject;
use Cake\Datasource\EntityInterface;
use Cake\Event\EventInterface;
use Cake\ORM\Behavior;
use Cake\Utility\Text;
class SluggableBehavior extends Behavior
{
public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options): void
{
if ($entity->isNew() && !$entity->slug) {
$entity->slug = Text::slug(mb_strtolower($entity->title));
}
}
}Метод beforeSave() вызывается перед каждым сохранением. Для новой записи без слага он превращает заголовок «Hello World» в hello-world.
Использование
Добавьте таблице столбец slug миграцией и подключите поведение:
// src/Model/Table/ArticlesTable.php
$this->addBehavior('Sluggable');Создайте статью через форму — столбец slug заполнится сам. То же поведение можно подключить к любой таблице, где есть столбцы title и slug.
События таблицы
Поведение может реагировать на несколько событий:
| Метод | Когда вызывается |
|---|---|
beforeMarshal() | До переноса данных формы в запись |
beforeSave() | Перед сохранением |
afterSave() | После сохранения |
beforeDelete() | Перед удалением |
beforeFind() | Перед выполнением запроса |
Такие же методы можно написать и прямо в классе таблицы, если логика нужна только ей.
Частая ошибка
Timestamp ищет столбцы с именами created и modified. Если назвать их created_at и updated_at, как в других фреймворках, поведение молча ничего не заполнит. Называйте столбцы по соглашениям CakePHP.