Skip to content

Commit e2cc899

Browse files
authored
Merge pull request spatie#1110 from pemudakoding/main
Support non backed enum & php 8.1
2 parents fc57d9c + ec8bd33 commit e2cc899

File tree

5 files changed

+95
-1
lines changed

5 files changed

+95
-1
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Spatie\Activitylog\Actions;
4+
5+
class ResolveForPropertyValueAction
6+
{
7+
/**
8+
* Action that resolve property value of log
9+
* that cannot be handled by PHP as default
10+
*
11+
* @param mixed $value
12+
* @return mixed
13+
*/
14+
public static function execute(mixed $value): mixed
15+
{
16+
$instance = new static;
17+
18+
/**
19+
* Give a fallback value if value not a backed enum
20+
*/
21+
if ($instance->isValueAnEnum($value)) {
22+
return $value->value ?? $value->name;
23+
}
24+
25+
return $value;
26+
}
27+
28+
protected function isValueAnEnum($value): bool
29+
{
30+
if (! function_exists('enum_exists')){
31+
return false;
32+
}
33+
34+
$enumNamespace = is_object($value) ? get_class($value): $value;
35+
36+
return ! is_array($value) && enum_exists($enumNamespace);
37+
}
38+
}

src/ActivityLogger.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Illuminate\Support\Str;
1111
use Illuminate\Support\Traits\Conditionable;
1212
use Illuminate\Support\Traits\Macroable;
13+
use Spatie\Activitylog\Actions\ResolveForPropertyValueAction;
1314
use Spatie\Activitylog\Contracts\Activity as ActivityContract;
1415

1516
class ActivityLogger
@@ -102,13 +103,15 @@ public function setEvent(string $event): static
102103

103104
public function withProperties(mixed $properties): static
104105
{
105-
$this->getActivity()->properties = collect($properties);
106+
$this->getActivity()->properties = collect($properties)->map(fn ($value) => ResolveForPropertyValueAction::execute($value));
106107

107108
return $this;
108109
}
109110

110111
public function withProperty(string $key, mixed $value): static
111112
{
113+
$value = ResolveForPropertyValueAction::execute($value);
114+
112115
$this->getActivity()->properties = $this->getActivity()->properties->put($key, $value);
113116

114117
return $this;

src/Traits/LogsActivity.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,10 @@ public static function logChanges(Model $model): array
366366
if ($model->hasCast($attribute)) {
367367
$cast = $model->getCasts()[$attribute];
368368

369+
if (function_exists('enum_exists') && enum_exists($cast)) {
370+
$changes[$attribute] = $model->getStorableEnumValue($changes[$attribute]);
371+
}
372+
369373
if ($model->isCustomDateTimeCast($cast) || $model->isImmutableCustomDateTimeCast($cast)) {
370374
$changes[$attribute] = $model->asDateTime($changes[$attribute])->format(explode(':', $cast, 2)[1]);
371375
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace Spatie\Activitylog\Test;
4+
5+
use Illuminate\Support\Str;
6+
use Spatie\Activitylog\Test\Enum\NonBackedEnum;
7+
use Spatie\Activitylog\Test\Models\Activity;
8+
use Spatie\Activitylog\Test\Models\User;
9+
10+
afterEach(fn() => Activity::query()->latest()->first()->delete());
11+
12+
it('can store non-backed enum only a property', function () {
13+
$description = 'ROLE LOG';
14+
15+
activity()
16+
->performedOn(User::first())
17+
->withProperty('role', NonBackedEnum::User)->log($description);
18+
19+
$latestActivity = Activity::query()->latest()->first();
20+
21+
expect($latestActivity->description)->toEqual($description)
22+
->and($latestActivity->properties['role'])->toEqual('User');
23+
})
24+
->skip(version_compare(PHP_VERSION, '8.1', '<'), "PHP < 8.1 doesn't support enum");
25+
26+
it('can store non-backed enum with properties', function () {
27+
$description = 'ROLE LOG';
28+
29+
activity()
30+
->performedOn(User::first())
31+
->withProperties(['role' => NonBackedEnum::User])->log($description);
32+
33+
$latestActivity = Activity::query()->latest()->first();
34+
35+
expect($latestActivity->description)->toEqual($description)
36+
->and($latestActivity->properties['role'])->toEqual('User');
37+
})
38+
->skip(version_compare(PHP_VERSION, '8.1', '<'), "PHP < 8.1 doesn't support enum");
39+

tests/Enum/NonBackedEnum.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Spatie\Activitylog\Test\Enum;
4+
5+
enum NonBackedEnum
6+
{
7+
case Admin;
8+
9+
case User;
10+
}

0 commit comments

Comments
 (0)