Laravel 5,日志模型创建,更新,删除事件

时间:2015-06-27 10:48:46

标签: php laravel-5 laravel-5.1

我正在开发Laravel 5应用程序。其中我想记录模型创建,更新和删除事件与所有新的或更改(如果模型正在更新)模型字段。我想要简单的可重用解决方案,而无需编写太多代码。

3 个答案:

答案 0 :(得分:8)

当然,您可以创建如下所示的特征,并在要记录的所有模型中使用它。

<?php

namespace App\Traits;

use App\Activity;
use Illuminate\Database\Eloquent\Model;

/**
 * Class ModelEventLogger
 * @package App\Traits
 *
 *  Automatically Log Add, Update, Delete events of Model.
 */
trait ModelEventLogger {

    /**
     * Automatically boot with Model, and register Events handler.
     */
    protected static function bootModelEventLogger()
    {
        foreach (static::getRecordActivityEvents() as $eventName) {
            static::$eventName(function (Model $model) use ($eventName) {
                try {
                    $reflect = new \ReflectionClass($model);
                    return Activity::create([
                        'user_id'     => \Auth::user()->id,
                        'contentId'   => $model->id,
                        'contentType' => get_class($model),
                        'action'      => static::getActionName($eventName),
                        'description' => ucfirst($eventName) . " a " . $reflect->getShortName(),
                        'details'     => json_encode($model->getDirty())
                    ]);
                } catch (\Exception $e) {
                    return true;
                }
            });
        }
    }

    /**
     * Set the default events to be recorded if the $recordEvents
     * property does not exist on the model.
     *
     * @return array
     */
    protected static function getRecordActivityEvents()
    {
        if (isset(static::$recordEvents)) {
            return static::$recordEvents;
        }

        return [
            'created',
            'updated',
            'deleted',
        ];
    }

    /**
     * Return Suitable action name for Supplied Event
     *
     * @param $event
     * @return string
     */
    protected static function getActionName($event)
    {
        switch (strtolower($event)) {
            case 'created':
                return 'create';
                break;
            case 'updated':
                return 'update';
                break;
            case 'deleted':
                return 'delete';
                break;
            default:
                return 'unknown';
        }
    }
} 

现在,您可以在要为其投放事件的任何模型中使用此特征。在你的案例模型中。

<?php namespace App;

use App\Traits\ModelEventLogger;
use Illuminate\Database\Eloquent\Model;

class Test extends Model {

    use ModelEventLogger;

    //Just in case you want specific events to be fired for Article model
    //uncomment following line of code

   // protected static $recordEvents = ['created'];

}

当然,您必须使用相关列创建“活动”模型和相关表。 我希望这会有所帮助。

答案 1 :(得分:1)

我做了一点修改希望它有所帮助。 (这只是跟踪模型的修改)

的迁移

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateLogActions extends Migration
{
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::create('log_actions', function (Blueprint $table) {
      $table->increments('id');
      $table->integer('loggable_id');
      $table->string('loggable_type');
      $table->string('action');
      $table->integer('user_id')->unsigned()->index();
      $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
      $table->timestamp('dt_action');
    });
  }

  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::drop('log_actions');
  }
}

模型

<?php

namespace App\Wdog\Entities;

use Illuminate\Database\Eloquent\Model;
use Prettus\Repository\Contracts\Transformable;
use Prettus\Repository\Traits\TransformableTrait;

class LogAction extends Model implements Transformable
{
  use TransformableTrait;

  protected $fillable = [
    'loggable_type',
    'loggable_id',
    'user_id',
    'action',
    'dt_action'

  ];

  public $timestamps = false;

  protected $dates = [
    'dt_action'
  ];

  public function user()
  {
    return $this->belongsTo('App\User');
  }

  public function loggable()
  {
    return $this->morphTo();
  }
}

性状

最后只添加一个特质

<?php   

namespace App\Wdog\Traits;

use App\Wdog\Entities\LogAction;
use Auth;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;


trait ModelEventLogger
{

  public static function bootModelEventLogger()
  {

    $user_id = Auth::user()->id;
    foreach (static::getRecordActivityEvents() as $eventName) {


      static::$eventName(function (Model $model) use ($user_id, $eventName) {

        $log = new LogAction([
          'user_id'   => $user_id,
          'dt_action' => Carbon::now(),
          'action'     => $eventName
        ]);          

        $model->logs()->save($log);


      });
    }    
  }    

  protected static function getRecordActivityEvents()
  {
    if (isset(static::$recordEvents)) {
      return static::$recordEvents;
    }

    return [
      'created',
      'updated',
      'deleted',
    ];
  }


  protected static function logs()
  {


    return $this->morphMany('\App\Wdog\Entities\LogAction', 'loggable')->orderBy('dt_action', 'desc');




  }


}

然后只使用模型中的特征

class User extends Model implements Transformable
{
  use ModelEventLogger;
...

答案 2 :(得分:0)

虽然线程很旧,但具体引用了OP对simple reusable solution without writing too much of a code的请求,Spatie's activity logger轻而易举!他们完整文档中的This specific part显示了OP的任务多么简单和容易!