2017 © Pedro Pelรกez
 

library history

Eloquent model history tracking for Laravel

image

panoscape/history

Eloquent model history tracking for Laravel

  • Thursday, July 19, 2018
  • by seancheung
  • Repository
  • 2 Watchers
  • 7 Stars
  • 61 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 1 Forks
  • 1 Open issues
  • 5 Versions
  • 39 % Grown

The README.md

Test Status Coverage Status Total Downloads Latest Stable Version License , (*1)

History

Eloquent model history tracking for Laravel, (*2)

Installation

Composer

Laravel 6.x and above, (*3)

composer require panoscape/history

Laravel 5.6.x, (*4)

composer require "panoscape/history:^1.0"

Service provider and alias

Only required for Laravel 5.6.x, (*5)

config/app.php, (*6)

'providers' => [
    ...
    Panoscape\History\HistoryServiceProvider::class,
];
'aliases' => [
    ...
    'App\History' => Panoscape\History\History::class,
];

Migration

php artisan vendor:publish --provider="Panoscape\History\HistoryServiceProvider" --tag=migrations

Config

php artisan vendor:publish --provider="Panoscape\History\HistoryServiceProvider" --tag=config

Localization

php artisan vendor:publish --provider="Panoscape\History\HistoryServiceProvider" --tag=translations

Usage

Add HasOperations trait to user model that performs operations., (*7)

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Panoscape\History\HasOperations;

class User extends Authenticatable
{
    use Notifiable, SoftDeletes, HasOperations;
}

Add HasHistories trait to the model that will be tracked., (*8)

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Panoscape\History\HasHistories;

class Article extends Model
{
    use HasHistories;

    public function getModelLabel()
    {
        return $this->display_name;
    }
}

Remember that you'll need to implement the abstract getModelLabel method from the trait. This provides the model instance's display name in histories (as Who in Who did what)., (*9)

Get histories of a model

$model->histories();
//or dynamic property
$model->histories;

Get operations of a user

$user->operations();
//or dynamic property
$user->operations;

Additional query conditions

Both histories and operations return Eloquent relationships which also serve as query builders. You can add further constraints by chaining conditions:, (*10)

// get the lastest 10 records
$model->histories()->orderBy('performed_at', 'desc')->take(10)

// filter by user id
$model->histories()->where('user_id', 10010)

History

//get the associated model
$history->model();

//get the associated user
//the user is the authenticated user when the action is being performed
//it might be null if the history is performed unauthenticatedly
$history->user();
//check user existence
$history->hasUser();

//get the message
$history->message;

//get the meta(only available when it's an updating operation)
//the meta will be an array with the properties changing information
$history->meta;

//get the timestamp the action was performed at
$history->performed_at;

Example message, (*11)

Created Project my_project
   โ”‚       โ”‚         โ”‚
   โ”‚       โ”‚         โ””โ”€โ”€โ”€โ”€โ”€ instance name(returned from `getModelLabel`)
   โ”‚       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ model name(class name or localized name)
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ event name(default or localized name)

Example meta, (*12)

[
    ['key' => 'name', 'old' => 'myName', 'new' => 'myNewName'],
    ['key' => 'age', 'old' => 10, 'new' => 100],
    ...
]

Custom history

Besides the built in created/updating/deleting/restoring events, you may track custom history record by firing an ModelChanged event., (*13)

use Panoscape\History\Events\ModelChanged;

...
//fire a model changed event
event(new ModelChanged($user, 'User roles updated', $user->roles()->pluck('id')->toArray()));

The ModelChanged constructor accepts two/three/four arguments. The first is the associated model instance; the second is the message; the third is optional, which is the meta(array); the fourth is also optional, being the translation key of the event(see Localization)., (*14)

Localization

You may localize the model's type name., (*15)

To do that, add the language line to the models array in the published language file, with the key being the class's base name in snake case., (*16)

Example language config, (*17)

/*
|--------------------------------------------------------------------------
| Tracker Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used across application for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/

'created' => 'ๅˆ›ๅปบ:model:label',

'updating' => 'actualizar :model :label',

'deleting' => ':model :label lรถschen',

'restored' => ':model:labelใ‚’ๅพฉๅ…ƒ',

//you may add your own model name language line here
'models' => [
    'project' => '้กน็›ฎ',
    'component_template' => '็ป„ไปถๆจกๆฟ',
    // 'model_base_name_in_snake_case' => 'translation',
]

This will translate your model history into, (*18)

ๅˆ›ๅปบ้กน็›ฎproject_001

You can also translate custom history messages from ModelChanged events, (*19)

/*
|--------------------------------------------------------------------------
| Tracker Language Lines
|--------------------------------------------------------------------------
*/
'switched_role' => ':model switched role',
// if you specified the translation key, the message argument will be ignored, simply just pass `null`
event(new ModelChanged($user, null, $user->roles()->pluck('id')->toArray()), 'switched_role');

Filters

You may set whitelist and blacklist in config file. Please follow the description guide in the published config file., (*20)

/*
|--------------------------------------------------------------
| Events whitelist
|--------------------------------------------------------------
|
| Events in this array will be recorded.
| Available events are: created, updating, deleting, restored
|
*/
'events_whitelist' => [
    'created', 'updating', 'deleting', 'restored',
],

/*
|--------------------------------------------------------------
| Attributes blacklist
|--------------------------------------------------------------
| 
| Please add the whole class names. Example: \App\User:class
| For each model, attributes in its respect array will NOT be recorded into meta when performing update operation.
|
*/
'attributes_blacklist' => [
    // \App\User::class => [
    //     'password'
    // ],
],

/*
|--------------------------------------------------------------
| User type blacklist
|--------------------------------------------------------------
|
| Operations performed by user types in this array will NOT be recorded.
| Please add the whole class names. Example: \App\Admin:class
| Use 'nobody' to bypass unauthenticated operations
|
*/
'user_blacklist' => [
    // \App\Admin:class,
    // 'nobody'
],
/*
|--------------------------------------------------------------
| Enviroments blacklist
|--------------------------------------------------------------
|
| When application's environment is in the list, tracker will be disabled
|
*/
'env_blacklist' => [
    // 'test'
],

Auth guards

If your users are using non-default auth guards, you might see all $history->hasUser() become false even though the history sources were generated by authenticated users., (*21)

To fix this, you'll need to enable custom auth guards scanning in config file:, (*22)

/*
|--------------------------------------------------------------
| Enable auth guards scanning
|--------------------------------------------------------------
|
| You only need to enable this if your users are using non-default auth guards.
| In that case, all tracked user operations will be anonymous.
|
| - Set to `true` to use a full scan mode: all auth guards will be checked. However this does not ensure guard priority.
| - Set to an array to scan only specific auth guards(in the given order). e.g. `['web', 'api', 'admin']`
|
*/
'auth_guards' => null

Custom meta

You can define your own method for meta data. By default for updating event meta consists of modified keys and for other events meta is null., (*23)

Just redefine the method getModelMeta for the trait., (*24)

Example:, (*25)

class Article extends Model
{
    // if you want to use default trait method, you need to redeclare it with a new name
    use HasHistories {
        getModelMeta as protected traitGetModelMeta;
    };

    ...

    public function getModelMeta($event)
    {
        // using defaults for updating
        if($event == 'updating') return $this->traitGetModelMeta($event);
        // passing full model to meta
        // ['key1' => 'value1', 'key2' => 'value2', ...]
        else return $this;
    }
}

Known issues

  1. When updating a model, if its model label(attributes returned from getModelLabel) has been modified, the history message will use its new attributes, which might not be what you expect.
class Article extends Model
{
    use HasHistories;

    public function getModelLabel()
    {
        return $this->title;
    }
}
// original title is 'my title'
// modify title
$article->title = 'new title';
$article->save();
// the updating history message
// expect: Updating Article my title
// actual: Updating Article new title

A workaround, (*26)

public function getModelLabel()
{
    return $this->getOriginal('title', $this->title);
}

The Versions

19/07 2018

dev-develop

dev-develop https://github.com/seancheung/history

Eloquent model history tracking for Laravel

  Sources   Download

MIT

The Requires

 

by Sean Cheung

laravel log eloquent model tracking history

19/07 2018

dev-master

9999999-dev https://github.com/seancheung/history

Eloquent model history tracking for Laravel

  Sources   Download

MIT

The Requires

 

by Sean Cheung

laravel log eloquent model tracking history

19/07 2018

v1.0.2

1.0.2.0 https://github.com/seancheung/history

Eloquent model history tracking for Laravel

  Sources   Download

MIT

The Requires

 

by Sean Cheung

laravel log eloquent model tracking history

06/01 2018

1.0.1

1.0.1.0 https://github.com/seancheung/history

Eloquent model history tracking for Laravel

  Sources   Download

MIT

The Requires

 

by Sean Cheung

laravel log eloquent model tracking history

22/11 2016

1.0.0

1.0.0.0 https://github.com/panoscape/history

Eloquent model history tracking for Laravel

  Sources   Download

MIT

The Requires

 

by Sean Cheung

laravel log eloquent model tracking history