diff --git a/src/Mpociot/Versionable/Jobs/VersionableJob.php b/src/Mpociot/Versionable/Jobs/VersionableJob.php new file mode 100644 index 0000000..3b27bdc --- /dev/null +++ b/src/Mpociot/Versionable/Jobs/VersionableJob.php @@ -0,0 +1,60 @@ +attributes = $this->model->getAttributes(); + $this->originalAttributes = $this->model->getOriginal(); + $this->id = $this->model->id; + $this->modelClass = get_class($this->model); + } + + /** + * @throws ReflectionException + */ + public function handle() + { + $resourceReflection = new ReflectionClass($this->modelClass); + $staticResource = $resourceReflection->newInstanceWithoutConstructor(); + $model = $staticResource->find($this->id); + + foreach ($this->originalAttributes as $key => $value) { + $model->setAttribute($key, $value); + } + + $model->syncOriginal(); + + foreach ($this->attributes as $key => $value) { + $model->setAttribute($key, $value); + } + + $model->versionableDirtyData = $model->getDirty(); + $model->updating = $model->exists; + $model->reason = $this->reason; + + Version::createVersionForModel($model); + } +} diff --git a/src/Mpociot/Versionable/Version.php b/src/Mpociot/Versionable/Version.php index add5cba..f05aff9 100644 --- a/src/Mpociot/Versionable/Version.php +++ b/src/Mpociot/Versionable/Version.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Config; use Illuminate\Database\Eloquent\Model as Eloquent; use Illuminate\Database\Eloquent\Model; +use Mpociot\Versionable\Jobs\VersionableJob; /** * Class Version @@ -105,4 +106,31 @@ public function diff(Version $againstVersion = null) return $diffArray; } + public static function createVersionForModel(Model $model) + { + if ( + ( $model->versioningEnabled === true && $model->updating && $model->isValidForVersioning() ) || + ( $model->versioningEnabled === true && !$model->updating && !is_null($model->versionableDirtyData) && count($model->versionableDirtyData)) + ) { + // Save a new version + $class = $model->getVersionClass(); + $version = new $class(); + $version->versionable_id = $model->getKey(); + $version->versionable_type = method_exists($model, 'getMorphClass') ? $model->getMorphClass() : get_class($model); + $version->user_id = $model->getAuthUserId(); + + $versionedHiddenFields = $model->versionedHiddenFields ?? []; + $model->makeVisible($versionedHiddenFields); + $version->model_data = serialize($model->attributesToArray()); + $model->makeHidden($versionedHiddenFields); + + if (!empty( $model->reason )) { + $version->reason = $model->reason; + } + + $version->save(); + + $model->purgeOldVersions(); + } + } } diff --git a/src/Mpociot/Versionable/VersionableTrait.php b/src/Mpociot/Versionable/VersionableTrait.php index f9ff17e..32be169 100644 --- a/src/Mpociot/Versionable/VersionableTrait.php +++ b/src/Mpociot/Versionable/VersionableTrait.php @@ -1,8 +1,11 @@ versionClass; @@ -40,19 +42,19 @@ protected function getVersionClass() * * @var array */ - private $versionableDirtyData; + public $versionableDirtyData; /** * Optional reason, why this version was created * @var string */ - private $reason; + public $reason; /** * Flag that determines if the model allows versioning at all * @var bool */ - protected $versioningEnabled = true; + public $versioningEnabled = true; /** * @return $this @@ -160,47 +162,25 @@ protected function versionablePreSave() */ protected function versionablePostSave() { - /** - * We'll save new versions on updating and first creation - */ - if ( - ( $this->versioningEnabled === true && $this->updating && $this->isValidForVersioning() ) || - ( $this->versioningEnabled === true && !$this->updating && !is_null($this->versionableDirtyData) && count($this->versionableDirtyData)) - ) { - // Save a new version - $class = $this->getVersionClass(); - $version = new $class(); - $version->versionable_id = $this->getKey(); - $version->versionable_type = method_exists($this, 'getMorphClass') ? $this->getMorphClass() : get_class($this); - $version->user_id = $this->getAuthUserId(); - - $versionedHiddenFields = $this->versionedHiddenFields ?? []; - $this->makeVisible($versionedHiddenFields); - $version->model_data = serialize($this->attributesToArray()); - $this->makeHidden($versionedHiddenFields); - - if (!empty( $this->reason )) { - $version->reason = $this->reason; - } - - $version->save(); - - $this->purgeOldVersions(); + if (config('versionable.use_queue', false)) { + VersionableJob::dispatch($this, $this?->reason); + } else { + Version::createVersionForModel($this); } } /** * Delete old versions of this model when they reach a specific count. - * + * * @return void */ - private function purgeOldVersions() + public function purgeOldVersions() { $keep = isset($this->keepOldVersions) ? $this->keepOldVersions : 0; - + if ((int)$keep > 0) { $count = $this->versions()->count(); - + if ($count > $keep) { $this->getLatestVersions() ->take($count) @@ -218,7 +198,7 @@ private function purgeOldVersions() * * @return bool */ - private function isValidForVersioning() + public function isValidForVersioning() { $dontVersionFields = isset( $this->dontVersionFields ) ? $this->dontVersionFields : []; $removeableKeys = array_merge($dontVersionFields, [$this->getUpdatedAtColumn()]); @@ -245,6 +225,4 @@ protected function getLatestVersions() { return $this->versions()->orderByDesc('version_id'); } - - } diff --git a/src/config/config.php b/src/config/config.php index 637864c..f8c453e 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -7,6 +7,12 @@ * Feel free to change this, if you need specific version * model logic. */ - 'version_model' => \Mpociot\Versionable\Version::class + 'version_model' => \Mpociot\Versionable\Version::class, -]; \ No newline at end of file + + /* + * Here you can configure the versioning logic + * to be handled within a separate job. + */ + 'use_queue' => env('VERSIONING_USE_QUEUE', false) +];