66 lines
2.0 KiB
PHP
66 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Domains\Logging\Models\Concerns;
|
|
|
|
use App\Domains\Logging\Enums\ValueChangeActorType;
|
|
use App\Domains\Logging\Models\ValueChange;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use LogicException;
|
|
|
|
trait LogsValueChanges
|
|
{
|
|
abstract protected function valueChangeTenantCode(): string;
|
|
|
|
public static function bootLogsValueChanges(): void
|
|
{
|
|
static::updated(function (Model $model): void {
|
|
$changedAttributes = array_values(array_intersect(
|
|
$model->getLoggedAttributes(),
|
|
array_keys($model->getChanges()),
|
|
));
|
|
|
|
if ($changedAttributes === []) {
|
|
return;
|
|
}
|
|
|
|
$userId = Auth::id();
|
|
$actorType = $userId === null
|
|
? ValueChangeActorType::System
|
|
: ValueChangeActorType::User;
|
|
|
|
foreach ($changedAttributes as $attribute) {
|
|
$model->valueChanges()->create([
|
|
'tenant_code' => $model->valueChangeTenantCode(),
|
|
'attribute' => $attribute,
|
|
'old_value' => $model->getRawOriginal($attribute),
|
|
'new_value' => $model->getAttributes()[$attribute] ?? null,
|
|
'changed_at' => now(),
|
|
'actor_type' => $actorType,
|
|
'user_id' => $userId,
|
|
]);
|
|
}
|
|
});
|
|
}
|
|
|
|
/** @return array<int, string> */
|
|
public function getLoggedAttributes(): array
|
|
{
|
|
if (! property_exists($this, 'loggedAttributes')) {
|
|
throw new LogicException(sprintf(
|
|
'The [%s] model must define a $loggedAttributes property.',
|
|
static::class,
|
|
));
|
|
}
|
|
|
|
return array_values(array_unique($this->loggedAttributes));
|
|
}
|
|
|
|
/** @return MorphMany<ValueChange, $this> */
|
|
public function valueChanges(): MorphMany
|
|
{
|
|
return $this->morphMany(ValueChange::class, 'trackable');
|
|
}
|
|
}
|