Полный цикл в digital

Наблюдатели за событиями Eloquent

Наблюдатели предоставляют механизм, который позволяет контролировать каждый процесс, происходящий с базой данных. Список событий, которые можно использовать при работе с базой данных, можно посмотреть в трейте HasEvents.

booting, booted, creating, created, updating, updated, deleting, deleted, saving, saved, restoring, restored. На каждую операцию с моделью предусмотрено 2 события. Например, при создании объекта модели сработает 2 события — creating и created. Первое срабатывает перед операцией добавления, второе после. Этот принцип распространяется на каждую операцию. Причём, если при обработке первого события вернуть false, то операция отменяется.

vendor/laravel/framework/src/illuminate/database/eloquent/concerns/HasEvents.php<?php
namespace Illuminate\Database\Eloquent\Concerns;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Events\NullDispatcher;
use Illuminate\Support\Arr;
use InvalidArgumentException;
trait HasEvents {
    public function getObservableEvents() {
        return array_merge(
            [
                'retrieved', 'creating', 'created', 'updating', 'updated',
                'saving', 'saved', 'restoring', 'restored', 'replicating',
                'deleting', 'deleted', 'forceDeleted',
            ],
            $this->observables
        );
    }
}

Создадим нового поставщика услуг:

php artisan make:provider EloquentEventServiceProvider
App/Providers/EloquentEventServiceProvider.php<?php
namespace App\Providers;

use App\Models\Page;
use Illuminate\Support\ServiceProvider;

class EloquentEventServiceProvider extends ServiceProvider {
    // Регистрируйте услуги @return void
    public function register() {
        // ...
    }
    // Сервисы начальной загрузки @return void
    public function boot() {
        Page::creating(function ($page) {
            $page->name = $page->name . ' (создана ' . auth()->user()->name . ')';
        });
    }
}

Добавим нового поставщика услуг в config/app.php:

config/app.phpreturn [
    'providers' => [
        App\Providers\EloquentEventServiceProvider::class,
    ]
]

Теперь перед добавлением новой страницы в базу данных к ее названию добавляется имя автора, который ее создал.

Наблюдать за множеством событий

Если нужно наблюдать за множеством событий для разных моделей (Page, Post, Category), то неудобно, что все они будут в методе boot() сервис-провайдера EloquentEventServiceProvider. Давайте создадим отдельную директорию app/Observers и разместим в ней файл класса PageObserver.php:

app/Observers/PageObserver.php<?php
namespace App\Observers;
use App\Models\Page;
class PageObserver {
    // Срабатывает перед записью новой страницы
    public function creating(Page $page) {
        $page->name = 'Перед созданием, ' . $page->name;
    }
    // Срабатывает при извлечении из базы данных
    public function retrieved(Page $page) {
        $page->name = 'При извлечении, ' . $page->name;
    }
    // Срабатывает перед удалением страницы из БД
    public function deleting(Page $page) {
        return false;
    }
}

В сервис-провайдере уже не будем обрабатывать события, а только укажем класс, который будет это делать. Другими словами — зарегистрируем наблюдателя за событиями модели Page:

App/Providers/EloquentEventServiceProvider.phpnamespace App\Providers;
use App\Models\Page;
use App\Observers\PageObserver;
use Illuminate\Support\ServiceProvider;
class EloquentEventServiceProvider extends ServiceProvider {
    /**
        * Register services.
        *
        * @return void
        */
    public function register() {
        // ...
    }
    /**
        * Bootstrap services.
        *
        * @return void
        */
    public function boot() {
        Page::observe(PageObserver::class);
    }
}

Поскольку метод deleting() возвращает false — страницу теперь вообще нельзя удалить.

Наблюдатели работают с предопределенными событиями, которые происходят только в Eloquent Models (создание записи, обновление записи, удаление и т.д.). События создает сам разработчик, они не определены заранее и могут использоваться где угодно, а не только в моделях. Поэтому мы разместили класс PageObserver в отдельной директории app/Observers, а не в директории app/Listeners.

Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг