-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
207 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# History for Laravel Models | ||
|
||
Easily add keeping track of model modifications. | ||
|
||
## Installation | ||
|
||
1. Add `"tochka-developers/model-history":"^0.1"` to the `require` section | ||
of your `composer.json` | ||
|
||
2. Publish package assets: | ||
```shell | ||
php artisan vendor:publish | ||
``` | ||
3. You may now edit the config file `model-history.php` to specify | ||
the name of the table to store history records. Please do it _before_ | ||
running the migrations. Default name is `history` which is quite reasonable. | ||
|
||
4. Use `\Tochka\ModelHistory\HasHistory` trait in your model. | ||
|
||
## History structure | ||
|
||
History records for all tracked models are stored in the same table | ||
specified in the config file (`history` is the default name). | ||
Each record contains the following data: | ||
- `changed_at` - time of modification; | ||
- `entity_name` - name of the table containing tracked model records; | ||
- `entity_id` - ID of the row in the tracked table the history entry relates to; | ||
- `action` - type of modification. The possible values are `create`, `update`, | ||
`delete` and `restore`. | ||
- `new_data` - a JSON containing _new_ values. Therefore each history record is | ||
essentially a diff to the previous version of the model. | ||
|
||
## Warning | ||
|
||
The history table always grows and is NEVER CLEANED UP by this package. | ||
Please consider the possibility of the history table becoming the largest | ||
in your database and occupying more space than all other tables | ||
ultimately exhausting all available disk space. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"name": "tochka-developers/model-history", | ||
"description": "Simple history for Laravel models", | ||
"type": "package", | ||
"require": { | ||
"php": "^7.4", | ||
"ext-json": "*", | ||
"ext-pdo": "*", | ||
"laravel/framework": "^5.8 || ^6.0 || ^7.0 || ^8.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"Tochka\\ModelHistory\\": "src/" | ||
} | ||
}, | ||
"extra": { | ||
"laravel": { | ||
"providers": [ | ||
"Tochka\\ModelHistory\\ModelHistoryServiceProvider" | ||
] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?php | ||
|
||
return [ | ||
// The table where the history records are kept | ||
'table_name' => 'history', | ||
]; |
41 changes: 41 additions & 0 deletions
41
database/migrations/2021_04_28_111111_create_history_table.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Support\Facades\Schema; | ||
use Tochka\ModelHistory\HistoryObserver; | ||
|
||
/** | ||
* Create table for history records | ||
*/ | ||
class CreateHistoryTable extends Migration | ||
{ | ||
/** | ||
* Run the migrations. | ||
* | ||
* @return void | ||
*/ | ||
public function up() | ||
{ | ||
Schema::create(HistoryObserver::getTableName(), function (Blueprint $table) { | ||
$table->increments('id'); | ||
$table->string('entity_name'); | ||
$table->integer('entity_id'); | ||
$table->string('action'); | ||
$table->text('new_data')->nullable(); | ||
$table->timestamp('changed_at'); | ||
|
||
$table->index(['entity_name', 'entity_id']); | ||
}); | ||
} | ||
|
||
/** | ||
* Reverse the migrations. | ||
* | ||
* @return void | ||
*/ | ||
public function down() | ||
{ | ||
Schema::dropIfExists(HistoryObserver::getTableName()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
namespace Tochka\ModelHistory; | ||
|
||
/** | ||
* Use this in your model to enable saving history entries | ||
* @codeCoverageIgnore | ||
*/ | ||
trait HasHistory | ||
{ | ||
public static function bootHasHistory(): void | ||
{ | ||
static::observe(HistoryObserver::class); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<?php | ||
|
||
namespace Tochka\ModelHistory; | ||
|
||
use Illuminate\Database\Eloquent\Model; | ||
use Illuminate\Support\Facades\DB; | ||
use Illuminate\Support\Facades\Log; | ||
|
||
/** | ||
* This listens for model events and produces a history record for each action on the model in question. | ||
*/ | ||
class HistoryObserver | ||
{ | ||
public const ACTION_CREATE = 'create'; | ||
public const ACTION_UPDATE = 'update'; | ||
public const ACTION_DELETE = 'delete'; | ||
public const ACTION_RESTORE = 'restore'; | ||
|
||
public function created(Model $model): void | ||
{ | ||
self::saveData($model, self::ACTION_CREATE); | ||
} | ||
|
||
public function updated(Model $model): void | ||
{ | ||
self::saveData($model, self::ACTION_UPDATE); | ||
} | ||
|
||
public function deleted(Model $model): void | ||
{ | ||
self::saveData($model, self::ACTION_DELETE); | ||
} | ||
|
||
public function restored(Model $model): void | ||
{ | ||
self::saveData($model, self::ACTION_RESTORE); | ||
} | ||
|
||
public static function saveData(Model $model, string $action): void | ||
{ | ||
$entity_name = $model->getTable(); | ||
$entity_id = $model->{$model->getKeyName()}; | ||
try { | ||
$query = DB::table(self::getTableName()); | ||
|
||
$query->insert([ | ||
'entity_name' => $entity_name, | ||
'entity_id' => $entity_id, | ||
'action' => $action, | ||
'new_data' => \json_encode($model->getDirty()), | ||
'changed_at' => \date('Y-m-d H:i:s'), | ||
]); | ||
} catch (\Throwable $t) { | ||
Log::error('Unable to save history entry', ['entity_name' => $entity_name, 'entity_id' => $entity_id, 'message' => $t->getMessage()]); | ||
} | ||
} | ||
|
||
public static function getTableName(): string | ||
{ | ||
return config('model-history.table_name', 'history'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
namespace Tochka\ModelHistory; | ||
|
||
use Illuminate\Support\ServiceProvider; | ||
|
||
/** | ||
* Integration | ||
*/ | ||
class ModelHistoryServiceProvider extends ServiceProvider | ||
{ | ||
public function boot(): void | ||
{ | ||
$this->publishes([ | ||
__DIR__ . '/../config/model-history.php' => config_path('model-history.php'), | ||
], 'config'); | ||
|
||
$this->publishes([ | ||
__DIR__ . '/../database/migrations/' => database_path('migrations'), | ||
], 'migrations'); | ||
} | ||
} |