From 23cfb2d52c4715f1041e9d30a12de78329668204 Mon Sep 17 00:00:00 2001 From: zachweix Date: Thu, 21 Nov 2019 09:18:11 -0500 Subject: [PATCH 01/15] use newer conventions use larger integers for ID's and in down function change to dropIfExists, to prevent a potential failure --- .../2013_04_09_062329_create_revisions_table.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/migrations/2013_04_09_062329_create_revisions_table.php b/src/migrations/2013_04_09_062329_create_revisions_table.php index fdd5b1e8..8d3d2d2a 100644 --- a/src/migrations/2013_04_09_062329_create_revisions_table.php +++ b/src/migrations/2013_04_09_062329_create_revisions_table.php @@ -12,10 +12,10 @@ class CreateRevisionsTable extends Migration public function up() { Schema::create('revisions', function ($table) { - $table->increments('id'); + $table->bigIncrements('id'); $table->string('revisionable_type'); - $table->integer('revisionable_id'); - $table->integer('user_id')->nullable(); + $table->unsignedBigInteger('revisionable_id'); + $table->unsignedBigInteger('user_id')->nullable(); $table->string('key'); $table->text('old_value')->nullable(); $table->text('new_value')->nullable(); @@ -32,6 +32,6 @@ public function up() */ public function down() { - Schema::drop('revisions'); + Schema::dropIfExists('revisions'); } } From b3c462e340fa45b05540a2004a0ba853dfa1e8cc Mon Sep 17 00:00:00 2001 From: Sergey Zhidkov Date: Fri, 25 Oct 2019 17:50:33 +0300 Subject: [PATCH 02/15] Added storing Force Delete --- readme.md | 8 +++++ .../Revisionable/Revisionable.php | 32 +++++++++++++++++++ .../Revisionable/RevisionableTrait.php | 32 +++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/readme.md b/readme.md index 46ba578d..3ac95380 100644 --- a/readme.md +++ b/readme.md @@ -162,6 +162,14 @@ To better format the output for `deleted_at` entries, you can use the `isEmpty` +### Storing Force Delete +By default the Force Delete of a model is not stored as a revision. + +If you want to store the Force Delete as a revision you can override this behavior by setting `revisionForceDeleteEnabled ` to `true` by adding the following to your model: +```php +protected $revisionForceDeleteEnabled = true; +``` + ### Storing Creations By default the creation of a new model is not stored as a revision. Only subsequent changes to a model is stored. diff --git a/src/Venturecraft/Revisionable/Revisionable.php b/src/Venturecraft/Revisionable/Revisionable.php index 04e5986e..21b60328 100644 --- a/src/Venturecraft/Revisionable/Revisionable.php +++ b/src/Venturecraft/Revisionable/Revisionable.php @@ -72,6 +72,7 @@ public static function boot() static::deleted(function ($model) { $model->preSave(); $model->postDelete(); + $model->postForceDelete(); }); } /** @@ -224,6 +225,37 @@ public function postDelete() } } + /** + * If forcedeletes are enabled, set the value created_at of model to null + * + * @return void|bool + */ + public function postForceDelete() + { + if (empty($this->revisionForceDeleteEnabled)) { + return false; + } + + if ((!isset($this->revisionEnabled) || $this->revisionEnabled) + && (($this->isSoftDelete() && $this->isForceDeleting()) || !$this->isSoftDelete())) { + + $revisions[] = array( + 'revisionable_type' => $this->getMorphClass(), + 'revisionable_id' => $this->getKey(), + 'key' => self::CREATED_AT, + 'old_value' => $this->{self::CREATED_AT}, + 'new_value' => null, + 'user_id' => $this->getSystemUserId(), + 'created_at' => new \DateTime(), + 'updated_at' => new \DateTime(), + ); + + $revision = Revisionable::newModel(); + \DB::table($revision->getTable())->insert($revisions); + \Event::dispatch('revisionable.deleted', array('model' => $this, 'revisions' => $revisions)); + } + } + /** * Attempt to find the user id of the currently logged in user * Supports Cartalyst Sentry/Sentinel based authentication, as well as stock Auth diff --git a/src/Venturecraft/Revisionable/RevisionableTrait.php b/src/Venturecraft/Revisionable/RevisionableTrait.php index 4f6fe2b6..b4163d32 100644 --- a/src/Venturecraft/Revisionable/RevisionableTrait.php +++ b/src/Venturecraft/Revisionable/RevisionableTrait.php @@ -84,6 +84,7 @@ public static function bootRevisionableTrait() static::deleted(function ($model) { $model->preSave(); $model->postDelete(); + $model->postForceDelete(); }); } @@ -281,6 +282,37 @@ public function postDelete() } } + /** + * If forcedeletes are enabled, set the value created_at of model to null + * + * @return void|bool + */ + public function postForceDelete() + { + if (empty($this->revisionForceDeleteEnabled)) { + return false; + } + + if ((!isset($this->revisionEnabled) || $this->revisionEnabled) + && (($this->isSoftDelete() && $this->isForceDeleting()) || !$this->isSoftDelete())) { + + $revisions[] = array( + 'revisionable_type' => $this->getMorphClass(), + 'revisionable_id' => $this->getKey(), + 'key' => self::CREATED_AT, + 'old_value' => $this->{self::CREATED_AT}, + 'new_value' => null, + 'user_id' => $this->getSystemUserId(), + 'created_at' => new \DateTime(), + 'updated_at' => new \DateTime(), + ); + + $revision = Revisionable::newModel(); + \DB::table($revision->getTable())->insert($revisions); + \Event::dispatch('revisionable.deleted', array('model' => $this, 'revisions' => $revisions)); + } + } + /** * Attempt to find the user id of the currently logged in user * Supports Cartalyst Sentry/Sentinel based authentication, as well as stock Auth From 2f29a96e75e97f35833c6ce327d95bc2bf76f5af Mon Sep 17 00:00:00 2001 From: Sergey Zhidkov Date: Fri, 25 Oct 2019 17:59:22 +0300 Subject: [PATCH 03/15] Storing Force Delete in README --- readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.md b/readme.md index 3ac95380..8063e4fb 100644 --- a/readme.md +++ b/readme.md @@ -170,6 +170,10 @@ If you want to store the Force Delete as a revision you can override this behavi protected $revisionForceDeleteEnabled = true; ``` +In which case, the `created_at` field will be stored as a key with the `oldValue()` value equal to the model creation date and the `newValue()` value equal to null. + +**Attention!** Turn on this setting carefully! Since the model saved in the revision, now does not exist, so you will not be able to get its object or its relations. + ### Storing Creations By default the creation of a new model is not stored as a revision. Only subsequent changes to a model is stored. From 2fb4324c66ae4c9504be8ab29ac615582fe36f8b Mon Sep 17 00:00:00 2001 From: Sergey Zhidkov Date: Fri, 25 Oct 2019 18:08:34 +0300 Subject: [PATCH 04/15] Storing Force Delete in README --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 8063e4fb..b1986928 100644 --- a/readme.md +++ b/readme.md @@ -170,7 +170,7 @@ If you want to store the Force Delete as a revision you can override this behavi protected $revisionForceDeleteEnabled = true; ``` -In which case, the `created_at` field will be stored as a key with the `oldValue()` value equal to the model creation date and the `newValue()` value equal to null. +In which case, the `created_at` field will be stored as a key with the `oldValue()` value equal to the model creation date and the `newValue()` value equal to `null`. **Attention!** Turn on this setting carefully! Since the model saved in the revision, now does not exist, so you will not be able to get its object or its relations. From 4fe0bcf6ab997b7336ea60e89bd34763bf62a40c Mon Sep 17 00:00:00 2001 From: Paul Stanisci Date: Mon, 31 Aug 2020 17:15:25 -0400 Subject: [PATCH 05/15] checks value is object before using json_decode() in preSave() --- src/Venturecraft/Revisionable/RevisionableTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Venturecraft/Revisionable/RevisionableTrait.php b/src/Venturecraft/Revisionable/RevisionableTrait.php index b4163d32..f1fcd1b9 100644 --- a/src/Venturecraft/Revisionable/RevisionableTrait.php +++ b/src/Venturecraft/Revisionable/RevisionableTrait.php @@ -126,7 +126,7 @@ public function preSave() // we can only safely compare basic items, // so for now we drop any object based items, like DateTime foreach ($this->updatedData as $key => $val) { - if (isset($this->casts[$key]) && in_array($this->casts[$key], ['object', 'array']) && isset($this->originalData[$key])) { + if (gettype($val) == 'object' && isset($this->casts[$key]) && in_array($this->casts[$key], ['object', 'array']) && isset($this->originalData[$key])) { // Sorts the keys of a JSON object due Normalization performed by MySQL // So it doesn't set false flag if it is changed only order of key or whitespace after comma From 49e2db2373d0c9cd8ae3394b46c344dc422cde5f Mon Sep 17 00:00:00 2001 From: Paul Stanisci Date: Wed, 9 Sep 2020 15:22:41 -0400 Subject: [PATCH 06/15] Cast values are now correctly checked for either array or object --- src/Venturecraft/Revisionable/RevisionableTrait.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Venturecraft/Revisionable/RevisionableTrait.php b/src/Venturecraft/Revisionable/RevisionableTrait.php index f1fcd1b9..4f0ff400 100644 --- a/src/Venturecraft/Revisionable/RevisionableTrait.php +++ b/src/Venturecraft/Revisionable/RevisionableTrait.php @@ -126,7 +126,8 @@ public function preSave() // we can only safely compare basic items, // so for now we drop any object based items, like DateTime foreach ($this->updatedData as $key => $val) { - if (gettype($val) == 'object' && isset($this->casts[$key]) && in_array($this->casts[$key], ['object', 'array']) && isset($this->originalData[$key])) { + $castCheck = ['object', 'array']; + if (isset($this->casts[$key]) && in_array(gettype($val), $castCheck) && in_array($this->casts[$key], $castCheck) && isset($this->originalData[$key])) { // Sorts the keys of a JSON object due Normalization performed by MySQL // So it doesn't set false flag if it is changed only order of key or whitespace after comma From 2c68e7a22ed10c4d27aad743c639d8c67b26d6cf Mon Sep 17 00:00:00 2001 From: Paul Stanisci Date: Wed, 9 Sep 2020 15:26:26 -0400 Subject: [PATCH 07/15] fixed indentation to match original format --- src/Venturecraft/Revisionable/RevisionableTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Venturecraft/Revisionable/RevisionableTrait.php b/src/Venturecraft/Revisionable/RevisionableTrait.php index 4f0ff400..d57d180a 100644 --- a/src/Venturecraft/Revisionable/RevisionableTrait.php +++ b/src/Venturecraft/Revisionable/RevisionableTrait.php @@ -126,7 +126,7 @@ public function preSave() // we can only safely compare basic items, // so for now we drop any object based items, like DateTime foreach ($this->updatedData as $key => $val) { - $castCheck = ['object', 'array']; + $castCheck = ['object', 'array']; if (isset($this->casts[$key]) && in_array(gettype($val), $castCheck) && in_array($this->casts[$key], $castCheck) && isset($this->originalData[$key])) { // Sorts the keys of a JSON object due Normalization performed by MySQL // So it doesn't set false flag if it is changed only order of key or whitespace after comma From e8a89ce3c6d622a36e99fc87e9aaa70e7396260e Mon Sep 17 00:00:00 2001 From: Lance Pioch Date: Tue, 2 Mar 2021 18:34:38 -0500 Subject: [PATCH 08/15] Revert #112 and follow #113 --- src/Venturecraft/Revisionable/Revisionable.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Venturecraft/Revisionable/Revisionable.php b/src/Venturecraft/Revisionable/Revisionable.php index 21b60328..5134af12 100644 --- a/src/Venturecraft/Revisionable/Revisionable.php +++ b/src/Venturecraft/Revisionable/Revisionable.php @@ -81,7 +81,12 @@ public static function boot() */ public static function newModel() { - $model = \Config::get('revisionable.model', 'Venturecraft\Revisionable\Revision'); + $model = app('config')->get('revisionable.model'); + + if (! $model) { + $model = 'Venturecraft\Revisionable\Revision'; + } + return new $model; } From 7dd938dd3b4abe0ff1bbd7aaf8245f3d66dce205 Mon Sep 17 00:00:00 2001 From: Reinier Date: Mon, 29 Mar 2021 11:48:22 +0200 Subject: [PATCH 09/15] Update RevisionableTrait.php --- src/Venturecraft/Revisionable/RevisionableTrait.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Venturecraft/Revisionable/RevisionableTrait.php b/src/Venturecraft/Revisionable/RevisionableTrait.php index d57d180a..0def63f2 100644 --- a/src/Venturecraft/Revisionable/RevisionableTrait.php +++ b/src/Venturecraft/Revisionable/RevisionableTrait.php @@ -326,6 +326,8 @@ public function getSystemUserId() || class_exists($class = '\Cartalyst\Sentinel\Laravel\Facades\Sentinel') ) { return ($class::check()) ? $class::getUser()->id : null; + } elseif (function_exists('backpack_auth') && backpack_auth()->check()) { + return backpack_user()->id; } elseif (\Auth::check()) { return \Auth::user()->getAuthIdentifier(); } From 24ef304dfe7fe64362cc815faab0fc80030d0c59 Mon Sep 17 00:00:00 2001 From: Cristian Tabacitu Date: Wed, 19 Jan 2022 20:02:41 +0200 Subject: [PATCH 10/15] support Laravel 9 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 8ec2fa76..4aff9eee 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,8 @@ }, "require": { "php": ">=5.4.0", - "illuminate/support": "~4.0|~5.0|~5.1|^6.0|^7.0|^8.0", - "laravel/framework": "~5.4|^6.0|^7.0|^8.0" + "illuminate/support": "~4.0|~5.0|~5.1|^6.0|^7.0|^8.0|^9.0", + "laravel/framework": "~5.4|^6.0|^7.0|^8.0|^9.0" }, "autoload": { "classmap": [ From e40e8240a78a6f48ff9de2bc7a917c34b30931e1 Mon Sep 17 00:00:00 2001 From: AHMAD BWIDANI Date: Sun, 6 Nov 2022 11:10:16 +0300 Subject: [PATCH 11/15] Update readme.md remove misleading space (not being trimmed in model) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index b1986928..1bb43d9a 100644 --- a/readme.md +++ b/readme.md @@ -283,7 +283,7 @@ Analogous to "boolean", only any text or numeric values can act as a source valu Look at this as an associative array in which the key is separated from the value by a dot. Array elements are separated by a vertical line. ``` -options: search.On the search|network.In networks +options:search.On the search|network.In networks ``` ### DateTime From 0533f5fa967dbb656b098dac123046fff5ecc69f Mon Sep 17 00:00:00 2001 From: Shift Date: Thu, 2 Feb 2023 06:29:08 +0000 Subject: [PATCH 12/15] Bump dependencies for Laravel 10 --- composer.json | 97 +++++++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/composer.json b/composer.json index 4aff9eee..8e0ada31 100644 --- a/composer.json +++ b/composer.json @@ -1,45 +1,52 @@ -{ - "name": "venturecraft/revisionable", - "license": "MIT", - "description": "Keep a revision history for your models without thinking, created as a package for use with Laravel", - "keywords": ["model", "laravel", "ardent", "revision", "audit", "history"], - "homepage": "http://github.com/venturecraft/revisionable", - "authors": [ - { - "name": "Chris Duell", - "email": "me@chrisduell.com" - } - ], - "support": { - "issues": "https://github.com/VentureCraft/revisionable/issues", - "source": "https://github.com/VentureCraft/revisionable" - }, - "require": { - "php": ">=5.4.0", - "illuminate/support": "~4.0|~5.0|~5.1|^6.0|^7.0|^8.0|^9.0", - "laravel/framework": "~5.4|^6.0|^7.0|^8.0|^9.0" - }, - "autoload": { - "classmap": [ - "src/migrations" - ], - "psr-0": { - "Venturecraft\\Revisionable": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Venturecraft\\Revisionable\\Tests\\": "tests/" - } - }, - "require-dev": { - "orchestra/testbench": "~3.0" - }, - "extra": { - "laravel": { - "providers": [ - "Venturecraft\\Revisionable\\RevisionableServiceProvider" - ] - } - } -} +{ + "name": "venturecraft/revisionable", + "license": "MIT", + "description": "Keep a revision history for your models without thinking, created as a package for use with Laravel", + "keywords": [ + "model", + "laravel", + "ardent", + "revision", + "audit", + "history" + ], + "homepage": "http://github.com/venturecraft/revisionable", + "authors": [ + { + "name": "Chris Duell", + "email": "me@chrisduell.com" + } + ], + "support": { + "issues": "https://github.com/VentureCraft/revisionable/issues", + "source": "https://github.com/VentureCraft/revisionable" + }, + "require": { + "php": ">=5.4.0", + "illuminate/support": "~4.0|~5.0|~5.1|^6.0|^7.0|^8.0|^9.0|^10.0", + "laravel/framework": "~5.4|^6.0|^7.0|^8.0|^9.0|^10.0" + }, + "autoload": { + "classmap": [ + "src/migrations" + ], + "psr-0": { + "Venturecraft\\Revisionable": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Venturecraft\\Revisionable\\Tests\\": "tests/" + } + }, + "require-dev": { + "orchestra/testbench": "~3.0|^8.0" + }, + "extra": { + "laravel": { + "providers": [ + "Venturecraft\\Revisionable\\RevisionableServiceProvider" + ] + } + } +} From 40b122b7ad2eb42316e1e0a6674d96a6f8295f2d Mon Sep 17 00:00:00 2001 From: CedricFrossard <113982099+CedricFrossard@users.noreply.github.com> Date: Wed, 8 Mar 2023 15:31:23 +0100 Subject: [PATCH 13/15] Update readme.md doc: userResponsible returns false and not null. --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 1bb43d9a..0e85c25b 100644 --- a/readme.md +++ b/readme.md @@ -344,7 +344,7 @@ If you have enabled revisions of creations as well you can display it like this: ### userResponsible() -Returns the User that was responsible for making the revision. A user model is returned, or null if there was no user recorded. +Returns the User that was responsible for making the revision. A user model is returned, or false if there was no user recorded. The user model that is loaded depends on what you have set in your `config/auth.php` file for the `model` variable. From 42d37d544f95ea008078207bed9383c79cf7578d Mon Sep 17 00:00:00 2001 From: Shift Date: Tue, 27 Feb 2024 01:34:43 +0000 Subject: [PATCH 14/15] Bump dependencies for Laravel 11 --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 8e0ada31..440a4a52 100644 --- a/composer.json +++ b/composer.json @@ -23,8 +23,8 @@ }, "require": { "php": ">=5.4.0", - "illuminate/support": "~4.0|~5.0|~5.1|^6.0|^7.0|^8.0|^9.0|^10.0", - "laravel/framework": "~5.4|^6.0|^7.0|^8.0|^9.0|^10.0" + "illuminate/support": "~4.0|~5.0|~5.1|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0", + "laravel/framework": "~5.4|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0" }, "autoload": { "classmap": [ @@ -40,7 +40,7 @@ } }, "require-dev": { - "orchestra/testbench": "~3.0|^8.0" + "orchestra/testbench": "~3.0|^8.0|^9.0" }, "extra": { "laravel": { From 466b3ea9d067e1f04a1e09658c2a8ff1347b252b Mon Sep 17 00:00:00 2001 From: syscore24 Date: Thu, 1 Aug 2024 16:57:27 +0530 Subject: [PATCH 15/15] Replaced DB query with eloquent so query uses model's $connection --- src/Venturecraft/Revisionable/Revisionable.php | 12 ++++++++---- src/Venturecraft/Revisionable/RevisionableTrait.php | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Venturecraft/Revisionable/Revisionable.php b/src/Venturecraft/Revisionable/Revisionable.php index 5134af12..21f7f4e4 100644 --- a/src/Venturecraft/Revisionable/Revisionable.php +++ b/src/Venturecraft/Revisionable/Revisionable.php @@ -170,7 +170,8 @@ public function postSave() if (count($revisions) > 0) { $revision = static::newModel(); - \DB::table($revision->getTable())->insert($revisions); + // \DB::table($revision->getTable())->insert($revisions); + $revision->insert($revisions); } } } @@ -203,7 +204,8 @@ public function postCreate() ); $revision = static::newModel(); - \DB::table($revision->getTable())->insert($revisions); + // \DB::table($revision->getTable())->insert($revisions); + $revision->insert($revisions); } } @@ -226,7 +228,8 @@ public function postDelete() 'updated_at' => new \DateTime(), ); $revision = static::newModel(); - \DB::table($revision->getTable())->insert($revisions); + // \DB::table($revision->getTable())->insert($revisions); + $revision->insert($revisions); } } @@ -256,7 +259,8 @@ public function postForceDelete() ); $revision = Revisionable::newModel(); - \DB::table($revision->getTable())->insert($revisions); + // \DB::table($revision->getTable())->insert($revisions); + $revision->insert($revisions); \Event::dispatch('revisionable.deleted', array('model' => $this, 'revisions' => $revisions)); } } diff --git a/src/Venturecraft/Revisionable/RevisionableTrait.php b/src/Venturecraft/Revisionable/RevisionableTrait.php index 0def63f2..a56fde57 100644 --- a/src/Venturecraft/Revisionable/RevisionableTrait.php +++ b/src/Venturecraft/Revisionable/RevisionableTrait.php @@ -210,7 +210,8 @@ public function postSave() } } $revision = Revisionable::newModel(); - \DB::table($revision->getTable())->insert($revisions); + // \DB::table($revision->getTable())->insert($revisions); + $revision->insert($revisions); \Event::dispatch('revisionable.saved', array('model' => $this, 'revisions' => $revisions)); } } @@ -248,7 +249,8 @@ public function postCreate() $revisions = array_merge($revisions[0], $this->getAdditionalFields()); $revision = Revisionable::newModel(); - \DB::table($revision->getTable())->insert($revisions); + // \DB::table($revision->getTable())->insert($revisions); + $revision->insert($revisions); \Event::dispatch('revisionable.created', array('model' => $this, 'revisions' => $revisions)); } @@ -278,7 +280,8 @@ public function postDelete() $revisions = array_merge($revisions[0], $this->getAdditionalFields()); $revision = Revisionable::newModel(); - \DB::table($revision->getTable())->insert($revisions); + // \DB::table($revision->getTable())->insert($revisions); + $revision->insert($revisions); \Event::dispatch('revisionable.deleted', array('model' => $this, 'revisions' => $revisions)); } } @@ -309,7 +312,8 @@ public function postForceDelete() ); $revision = Revisionable::newModel(); - \DB::table($revision->getTable())->insert($revisions); + // \DB::table($revision->getTable())->insert($revisions); + $revision->insert($revisions); \Event::dispatch('revisionable.deleted', array('model' => $this, 'revisions' => $revisions)); } }