記錄非常重要,凡走過必留痕跡,不然哪天網站被惡搞都不知道是誰惡搞,所以一定要作紀錄,Laravel-activitylog 這個套件就可以幫你做好一些紀錄,已經非常夠用,當然你也可以自己做一個更詳細的。

詳細請參考官網說明 https://spatie.be/docs/laravel-activitylog/v3/introduction

安裝

#安裝
composer require spatie/laravel-activitylog
#產生 migration
php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="migrations"
#產生 config
php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="config"

設定

編輯 config/activitylog.php

<?php

return [

    /*
     * If set to false, no activities will be saved to the database.
     */
    //啟用
    'enabled' => env('ACTIVITY_LOGGER_ENABLED', true),

    /*
     * When the clean-command is executed, all recording activities older than
     * the number of days specified here will be deleted.
     */
    //刪除多少天以前的紀錄
    'delete_records_older_than_days' => 365,

    /*
     * If no log name is passed to the activity() helper
     * we use this default log name.
     */
    //log_name欄位預設名稱
    'default_log_name' => 'default',

    /*
     * You can specify an auth driver here that gets user models.
     * If this is null we'll use the default Laravel auth driver.
     */
    //使用哪一個Auth Driver
    'default_auth_driver' => null,

    /*
     * If set to true, the subject returns soft deleted models.
     */
    //啟用軟刪除Model
    'subject_returns_soft_deleted_models' => false,

    /*
     * This model will be used to log activity.
     * It should be implements the Spatie\Activitylog\Contracts\Activity interface
     * and extend Illuminate\Database\Eloquent\Model.
     */
    'activity_model' => \Spatie\Activitylog\Models\Activity::class,

    /*
     * This is the name of the table that will be created by the migration and
     * used by the Activity model shipped with this package.
     */
    //資料表名稱
    'table_name' => 'activity_log',

    /*
     * This is the database connection that will be used by the migration and
     * the Activity model shipped with this package. In case it's not set
     * Laravel database.default will be used instead.
     */
    //連接資料庫,若需要連接不同的資料庫需在 .env 中指定
    'database_connection' => env('ACTIVITY_LOGGER_DB_CONNECTION'),
];

安裝及設定完後請執行 php artisan migrate 將資料表建立起來。

Laravel 5.5+ 不需要在 config\app.php 中加入 providers


    'providers' => [
        //Spatie\Activitylog 紀錄器
        Spatie\Activitylog\ActivitylogServiceProvider::class,
    ],

一般使用(直接在Controller使用)

例如: 後台管理登入登出紀錄

            //登入成功紀錄
            $adminuser = AdminEloquent::find(Auth::guard('admin')->id());
            activity()->causedBy($adminuser)->log('登入成功');

例如: 修改資料

        $adminuser = AdminEloquent::find(Auth::guard('admin')->id());
        activity()
        ->causedBy($adminuser)
        ->performedOn($post)
        ->withProperties($request)
        ->log('編輯');

說明:

        //啟用記錄開始
        //log_name欄位字串
        activity('log_name')
        //紀錄哪個用戶,放在 causer_type 與 causer_id 欄位
        ->causedBy($adminuser)
        //紀錄被修改的資料表, 放在 subject_type 與 subject_id 欄位
        ->performedOn($post)
        //紀錄被修改的相關資料,放在 properties 欄位
        ->withProperties($request)
        //儲存並將字串寫入 description 欄位
        ->log('編輯');

        //description 欄位裡面可以直接放入被修改的欄位資料或者其他資料
        // ->log('編輯,標題 :subject.title, 管理者 :causer.name');

使用在 Model 中

例如: 文章的 Model,這樣只要資料表有異動就會幫你做紀錄。

//直接使用記錄功能
use Spatie\Activitylog\Traits\LogsActivity;
class Post extends Model
{
    use LogsActivity;

    //可讓使用者新增編輯的欄位名稱
  	protected $fillable = [
        'title', 'type', 'content', 'user_id', 'approved',
        'onlinedate', 'offlinedate', 'isshow', 'istop', 'sort'
	];


    //要記錄的欄位
    //protected static $logAttributes = ['title','content'];
    //忽略紀錄有異動的欄位
    //protected static $ignoreChangedAttributes = ['isshow','istop','sort'];

    //要記錄的欄位 ['*'] 全部
    protected static $logAttributes = ['*'];

    //若使用 $logAttributes = ['*'] 時可使用來忽略某些欄位異動不啟用紀錄
    // protected static $logAttributesToIgnore = [ 'type'];

    //只記錄有改變的欄位
    protected static $logOnlyDirty = true;

    //無異動資料則不增加空資料,若沒設定 $logOnlyDirty = true 時使用
    //protected static $submitEmptyLogs = false;

    //log_name 欄位資料
    protected static $logName = '會員文章';

    //如果資料表欄位中有相關連其他資料表,可以使用該資料表中的欄位資料
    //protected $fillable = ['name', 'text', 'user_id'];
    //protected static $logAttributes = ['name', 'text', 'user.name'];

    //此為舊版做法
    //將此模型命名在 activity 資料表的 log_name 欄位, 等同 protected static $logName = '會員文章';
    //public function getLogNameToUse(string $eventName = ''): string
    //{
    //    return '會員文章';
    //}

紀錄額外的資料

例如: IP 資料

//建立特定IP欄位
->tap(function(Activity $activity) { $activity->ip = request()->ip();})

或者編輯 providers\AppServiceProvider.php 在 boot 啟動時就抓取IP並一起紀錄

        //第一種方式 (舊版做法)
        //只要有作紀錄動作,都將IP寫入 properties 欄位
        Activity::saving(function (Activity $activity) {
            $activity->properties = $activity->properties->put('ip', request()->ip());
        });

        //第二種方式 (新版作法)
        //只要有作紀錄動作,將IP寫入特定的紀錄IP欄位
        Activity::saving(function(Activity $activity) { $activity->ip = $activity->ip = request()->ip();});

取出資料

//將最後一筆紀錄取出
$lastActivity = Activity::all()->last();

//最後一筆紀錄有異動的資料
$lastActivity = Activity::all()->last()->change();

//將最後一筆的properties取出
$lastActivity = Activity::all()->last()->properties;

//將最後一筆的description取出
$lastActivity = Activity::all()->last()->description;

//取出特定與log_name相同的資料
$lastActivity = Activity::where('log_name' , 'other-log')->get();

// properties 欄位的資料格式
[
   'attributes' => [
        'name' => 'updated name',
        'text' => 'Lorum',
    ],
    'old' => [
        'name' => 'original name',
        'text' => 'Lorum',
    ],
    //如果有紀錄其他資料在properties的話,例如:IP
    'ip' => ['xxx.xxx.xxx.xxx'],
];

//舊版作法將ip資料放在properties欄位,若要在前端顯示ip則使用下面方法取出ip資料
{{ $lastActivity['ip'] }}

//新版使用額外的欄位作法
{{ $lastActivity->ip }}
最後修改日期: 2020 年 10 月 4 日