Encodera

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

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

Оглавление

Поведения

Поведение — готовый кусок логики, который подключают к классу таблицы одной строкой. Оно срабатывает само при сохранении или поиске. Так общий код — метки времени, создание адреса из заголовка — пишут один раз и используют в любых таблицах.

Подключение

Поведения подключают в методе 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.

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

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