Skip to content

Commit

Permalink
Fix DispatchAudit Serialization Problems (#893)
Browse files Browse the repository at this point in the history
* Fix DispatchAudit Serialization Problems

* Remove SerializesModels trait

* Tests for `Serialization of 'Closure' is not allowed`
  • Loading branch information
erikn69 authored May 21, 2024
1 parent e0cc534 commit 4afff44
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
85 changes: 85 additions & 0 deletions src/Events/DispatchAudit.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace OwenIt\Auditing\Events;

use OwenIt\Auditing\Contracts\Auditable;
use ReflectionClass;

class DispatchAudit
{
Expand All @@ -22,4 +23,88 @@ public function __construct(Auditable $model)
{
$this->model = $model;
}

/**
* Prepare the instance values for serialization.
*
* @return array
*/
public function __serialize()
{
$values = [
'class' => get_class($this->model),
'model_data' => [
'exists' => true,
'connection' => $this->model->getQueueableConnection()
]
];

$customProperties = array_merge([
'attributes',
'original',
'excludedAttributes',
'auditEvent',
'auditExclude',
'auditCustomOld',
'auditCustomNew',
'isCustomEvent',
'preloadedResolverData',
], $this->model->auditEventSerializedProperties ?? []);

$reflection = new ReflectionClass($this->model);

foreach ($customProperties as $key) {
try {
$values['model_data'][$key] = $this->getModelPropertyValue($reflection, $key);
} catch (\Throwable $e){
//
}
}

return $values;
}

/**
* Restore the model after serialization.
*
* @param array $values
* @return array
*/
public function __unserialize(array $values)
{
$this->model = new $values['class'];

$reflection = new ReflectionClass($this->model);
foreach ($values['model_data'] as $key => $value) {
$this->setModelPropertyValue($reflection, $key, $value);
}

return $values;
}

/**
* Set the property value for the given property.
*/
protected function setModelPropertyValue(ReflectionClass $reflection, string $name, $value)
{
$property = $reflection->getProperty($name);

$property->setAccessible(true);

$property->setValue($this->model, $value);
}

/**
* Get the property value for the given property.
*
* @return mixed
*/
protected function getModelPropertyValue(ReflectionClass $reflection, string $name)
{
$property = $reflection->getProperty($name);

$property->setAccessible(true);

return $property->getValue($this->model);
}
}
4 changes: 4 additions & 0 deletions tests/Models/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,16 @@ class Article extends Model implements Auditable
'reviewed',
];

public $customClosure;

public function __construct(array $attributes = [])
{
if (class_exists(\Illuminate\Database\Eloquent\Casts\AsArrayObject::class)) {
$this->casts['config'] = \Illuminate\Database\Eloquent\Casts\AsArrayObject::class;
}

$this->customClosure = function () {};

parent::__construct($attributes);
}

Expand Down

0 comments on commit 4afff44

Please sign in to comment.