14장 이벤트 시스템

14.1. 기본기 다지기

// 코드 14-1 app/Http/Controllers/ArticlesController.php

public function store(\App\Http\Requests\ArticlesRequest $request)
{
    $article = \App\User::find(1)->articles()->create($request->all());

    if (! $article) { ... }

    var_dump('이벤트를 던집니다.');
    event('article.created', [$article]);
    var_dump('이벤트를 던졌습니다.');

    // return redirect( ... );
}
// 코드 14-2 app/Http/routes.php

Event::listen('article.created', function ($article) {
    var_dump('이벤트를 받았습니다. 받은 데이터(상태)는 다음과 같습니다.');
    var_dump($article->toArray());
});

그림 14-1 이벤트 시스템 작동 원리

14.2. 이벤트 레지스트리

// 코드 14-3 app/Providers/EventServiceProvider.php

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [...];

    public function boot(DispatcherContract $events)
    {
        parent::boot($events);

        $events->listen('article.created', function ($article) {
            var_dump('이벤트를 받았습니다. 받은 데이터(상태)는 다음과 같습니다.');
            var_dump($article->toArray());
        });
    }
}

14.3. 이벤트 리스너 클래스

# 콘솔 14-1 이벤트 리스너 클래스 뼈대 코드 만들기 

$ php artisan make:listener ArticlesEventListener --event=article.created
// 코드 14-4 app/Http/Listeners/ArticlesEventListener.php

// use App\Events\article.created;

class ArticlesEventListener
{
    public function handle(\App\Article $article)
    {
        var_dump('이벤트를 받았습니다. 받은 데이터(상태)는 다음과 같습니다.');
        var_dump($article->toArray());
    }
}
// 코드 14-5 app/Providers/EventServiceProvider.php

public function boot(DispatcherContract $events)
{
    parent::boot($events);

    $events->listen(
        'article.created', 
        \App\Listeners\ArticlesEventListener::class
    );
}

14.4. 이벤트 클래스

# 콘솔 14-2 이벤트 클래스 뼈대 코드 만들기

$ php artisan make:event ArticleCreated
// 코드 14-6 app/Http/Events/ArticleCreated.php

class ArticleCreated extends Event
{
    use SerializesModels;

    public $article;

    public function __construct(\App\Article $article)
    {
        $this->article = $article;
    }
}
// 코드 14-7 app/Http/Controllers/ArticlesController.php

public function store(\App\Http\Requests\ArticlesRequest $request)
{
    // ...
    dump('이벤트를 던집니다.');
    event(new \App\Events\ArticleCreated($article));
    dump('이벤트를 던졌습니다.');
}
// 코드 14-8 app/Providers/EventServiceProvider.php

public function boot(DispatcherContract $events)
{
    parent::boot($events);

    $events->listen(
        \App\Events\ArticleCreated::class, 
        \App\Listeners\ArticlesEventListener::class
    );
}
// 코드 14-8 app/Http/Listeners/ArticlesEventListener.php

public function handle(\App\Events\ArticleCreated $event)
{
    dump('이벤트를 받았습니다. 받은 데이터(상태)는 다음과 같습니다.');
    dump($event->article->toArray());
}

14.5. 실용적인 이벤트 시스템

// 코드 14-9 app/Http/Controllers/ArticlesController.php

public function store(\App\Http\Requests\ArticlesRequest $request)
{
    $article = \App\User::find(1)->articles()->create($request->all());

    if (! $article) { ... }

    event(new \App\Events\ArticlesEvent($article));

    return redirect(route('articles.index'))->with('flash_message', '작성하신 글이 저장되었습니다.');
}
// 코드 14-10 app/Providers/EventServiceProvider.php

protected $listen = [
    \App\Events\ArticlesEvent::class => [
        \App\Listeners\ArticlesEventListener::class,
    ],
];
# 콘솔 14-3 이벤트 채널과 리스너 뼈대 코드 한번에 만들기

$ php artisan event:generate
// 코드 14-11 app/Events/ArticlesEvent.php

class ArticlesEvent extends Event
{
    use SerializesModels;

    public $article;

    public $action;

    public function __construct(\App\Article $article, $action = 'created')
    {
        $this->article = $article;
        $this->action = $action;
    }
}
// 코드 14-12 app/Http/Listeners/ArticlesEventListener.php

public function handle(\App\Events\ArticlesEvent $event)
{
    if ($event->action === 'created') {
        \Log::info(sprintf(
            '새로운 포럼 글이 등록되었습니다.: %s',
            $event->article->title
        ));
    }
}`
// 로그 14-1 storage/logs/laravel.log

[DATETIME] local.INFO: 새로운 포럼 글이 등록되었습니다.: 이벤트 시스템을 테스트합니다.

14.6. 라라벨 내장 이벤트 채널

14.6.1. 마이그레이션 및 모델

# 콘솔 14-4 last_login 열 추가 마이그레이션 뼈대 코드 만들기

$ php artisan make:migration add_last_login_column_on_users_table --table=users
// 코드 14-13 database/migrations/TIMESTAMP_add_last_login_column_on_users_table.php

class AddLastLoginColumnOnUsersTable extends Migration
{
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->timestamp('last_login')->nullable();
        });
    }

    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('last_login');
        });
    }
}
// 코드 14-14 app/User.php

class User extends Authenticatable
{
    protected $dates = ['last_login'];
}

14.6.2. 이벤트 리스너

// 코드 14-15 app/Providers/EventServiceProvider.php

protected $listen = [
    // ...
    \Illuminate\Auth\Events\Login::class => [
        \App\Listeners\UsersEventListener::class
    ],
];
# 콘솔 14-5 이벤트 채널 및 리스너 뼈대 코드 만들기

$ php artisan event:generate
// 코드 14-16 app/Listeners/UsersEventListener.php 

class UsersEventListener
{
    public function handle(Login $event)
    {
        $event->user->last_login = \Carbon\Carbon::now();

        return $event->user->save();
    }
}

14.6.3. 테스트

# 콘솔 14-6 이벤트 처리 결과 확인

$ php artisan tinker
>>> App\User::whereEmail('Braulio92@example.org')->first();
# => App\User {#652
#      id: 1,
#      name: "Ms. Karen Parker",
#      ...
#      last_login: "2016-03-11 08:38:57",
#    }

14.7. 마치며

$ git commit -m '이벤트 시스템'
$ git tag 1014-event

results matching ""

    No results matching ""