【Laravel】使用 Event 實作登入後記錄用戶資訊 LoginEvent

筆記一下 Login 後記錄用戶資訊的實作,這次使用 Laravel 的 Event

…migrations  & ..model

Schema::create('login_logs', function (Blueprint $table) {
    $table->id();
    $table->string('subject_type')->index('subject_type')->comment('用戶類型: Admin、User');
    $table->unsignedInteger('subject_id')->index('subject_id')->comment('用戶ID');
    $table->string('ip')->nullable()->comment('登入IP');
    $table->string('login_type')->nullable()->comment('登入方式: direct、FB、Google');
    $table->timestamp('login_at')->useCurrent()->comment('登入時間');
});

 

app/Providers/EventServiceProvider.php

LoginEvent::class => [
    LoginLogProcessed::class,
],

 

app/Events/LoginEvent.php

<?php

namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class LoginEvent
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * @var Admin|User
     */
    public $user = '';

    /**
     * @var String
     */
    public $userType = '';

    /**
     * @var String
     */
    public $loginType = '';

    /**
     * @var String
     */
    public $ip = '';

    /**
     * @param Admin|User $user
     * @param String $loginType
     * @param String $ip
     */
    public function __construct($user, String $loginType, String $ip)
    {
        $this->user = $user;
        $this->userType = get_class($user);
        $this->loginType = $loginType;
        $this->ip = $ip;
    }
}

 

app/Listeners/LoginLogProcessed.php

<?php

namespace App\Listeners;

use App\Services\LoginLogService;
use App\Events\LoginEvent;
use Illuminate\Contracts\Queue\ShouldQueue;

class LoginLogProcessed implements ShouldQueue
{
    /**
     * The name of the queue the job should be sent to.
     *
     * @var string|null
     */
    public $queue = 'login.listeners';

    /**
     * LoginLogService variable
     *
     * @var App\Services\LoginLogService
     */
    protected $loginLogService;

    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct(
        LoginLogService $loginLogService
    ) {
        $this->loginLogService = $loginLogService;
    }

    /**
     * Handle the event.
     *
     * @param  LoginEvent  $event
     * @return void
     */
    public function handle(LoginEvent $event)
    {
        $this->loginLogService->create([
            'subject_type' => $event->userType,
            'subject_id' => $event->user->id,
            'ip' => $event->ip,
            'login_type' => $event->loginType,
            'login_at' => now()
        ]);
    }
}

 

app/Services/LoginLogService.php

<?php

namespace App\Services;

use App\Repositories\LoginLogRepository;
use Ihero\Generator\Exceptions\RuntimeException;

class LoginLogService
{
    /**
     * LoginLogRepository variable
     *
     * @var App\Repositories\LoginLogRepository
     */
    protected $loginLogRepository;

    /**
     * __construct
     *
     * @param LoginLogRepository $loginLogRepository
     */
    public function __construct(LoginLogRepository $loginLogRepository)
    {
        $this->loginLogRepository = $loginLogRepository;
    }

    /**
     *
     * @param Array $input
     * @return void
     */
    public function create(Array $input)
    {
        $this->loginLogRepository->create($input);
    }
}

 

app/Repositories/LoginLogRepository.php

<?php

namespace App\Repositories;

use App\Models\LoginLog as Model;
use Ihero\Generator\Repositories\Repository;

class LoginLogRepository extends Repository
{
    /**
     * The table model.
     *
     * @var Model $model
     */
    protected $model;

    /**
     * __construct
     *
     * @param Model $model
     */
    public function __construct(Model $model)
    {
        $this->model = new \ReflectionClass($model);
    }
}

 

運用

event(new LoginEvent($user, 'direct', request()->ip()));
php artisan queue:work --queue=login.listeners --timeout=3600 --memory=1024 --daemon