From 79026a20d67b2f589a81ddfe70c8f3901a0b23cf Mon Sep 17 00:00:00 2001 From: Jeremy Munsch Date: Fri, 18 Sep 2026 15:57:56 +0200 Subject: [PATCH] fix: Fixes #60 model user was not properly resolved on status chage --- app/Models/ActivityLog.php | 179 +++++++----------- app/Providers/RouteServiceProvider.php | 3 + .../Controllers/UpdateModelPublished.php | 11 +- 3 files changed, 73 insertions(+), 120 deletions(-) diff --git a/app/Models/ActivityLog.php b/app/Models/ActivityLog.php index 3a4e150..40b2977 100644 --- a/app/Models/ActivityLog.php +++ b/app/Models/ActivityLog.php @@ -1,18 +1,26 @@ |null $data List of changes (old and new values). + * @property Carbon $created_at The date on which the user was published. * * @property-read \App\Models\User $user User BelongsTo relation. * @property-read \App\Models\StaticPage $staticPage StaticPage BelongsTo relation. @@ -31,6 +39,7 @@ use Illuminate\Support\Str; class ActivityLog extends Model { use HasFactory; + use Notifiable; /** * Indicates if the model should be timestamped. @@ -59,7 +68,8 @@ class ActivityLog extends Model * @var array */ protected $casts = [ - 'is_anonymous' => 'boolean', + 'is_anonymous' => 'bool', + 'is_console' => 'bool', 'event' => ActivityLogsEventEnum::class, 'data' => 'json', 'created_at' => 'datetime', @@ -69,110 +79,49 @@ class ActivityLog extends Model /** * Add new activity to the activity logs list. - * - * @param \Illuminate\Database\Eloquent\Model $model - * @param \App\Enums\ActivityLogs\ActivityLogsEventEnum $eventEnum - * @return void */ public static function addActivity(Model $model, ActivityLogsEventEnum $eventEnum): void { $isAnonymous = true; - /** @var \Illuminate\Database\Eloquent\Model|null */ + /** @var Model|null */ $userModel = auth('backend')->user(); - if (is_object($userModel)) { - $userModel = $userModel->getKeyForSelectQuery(); + $user_id = optional($userModel)->id; + if ($userModel instanceof Model) { + $user_id = $userModel->getKeyForSelectQuery(); $isAnonymous = false; } $activity = new self(); - $activity->user_id = $userModel; + $activity->user_id = $user_id; $activity->is_console = app()->runningInConsole(); $activity->is_anonymous = $isAnonymous; - $activity->model_class = \get_class($model); + $activity->model_class = $model::class; $activity->model_id = $model->getKey(); $activity->event = $eventEnum; $activity->data = static::getChangedColumns($activity, $model, $eventEnum); - // @phpstan-ignore-next-line - $activity->created_at = now(); + $activity->setAttribute('created_at', now()); $activity->saveOrFail(); } /** * Get old, new columns that has changed. * - * @param self $activity - * @param \Illuminate\Database\Eloquent\Model $model - * @param \App\Enums\ActivityLogs\ActivityLogsEventEnum $eventEnum - * @return array + * @return array|null */ - public static function getChangedColumns(self $activity, Model $model, ActivityLogsEventEnum $eventEnum): array - { - $modelClassName = $activity->model_class; - /** Get type of each fields of the target model */ - /** @var \Illuminate\Database\Eloquent\Model|null $targetModel */ - $targetModel = $activity->model_class::where( - (new $modelClassName())->getRouteKeyName(), - $activity->model_id - )->first(); - - if (\is_null($targetModel)) { - return []; + public static function getChangedColumns( + self $activity, + Model $model, + ActivityLogsEventEnum $eventEnum + ): ?array { + if ($eventEnum !== ActivityLogsEventEnum::updated) { + return null; } - $targetModelTypes = collect($targetModel->toArray()) - ->map(fn ($value) => self::getValueType($value)) + + $casts = $model->getCasts(); + $changes = $model->getChanges(); + + return collect($changes) + ->map(fn($val, $key) => $casts[$key] ?? 'string') ->toArray(); - /** Return old, new and type of values changed */ - return match ($eventEnum) { - ActivityLogsEventEnum::created => array_intersect_key($targetModelTypes, $model->toArray()), - ActivityLogsEventEnum::duplicated => array_intersect_key($targetModelTypes, $model->toArray()), - ActivityLogsEventEnum::updated => array_intersect_key($targetModelTypes, $model->getChanges()), - default => [] - }; - } - - - /** - * Get a value type as a string - * ! Use this for display purpose only - * - * @param mixed $value - * @return string - * @throws \RuntimeException If type is unhlanded. - * @phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded - */ - private static function getValueType(mixed $value): string - { - // phpcs:enable - $type = \gettype($value); - switch ($type) { - // phpcs:ignore PSR2.ControlStructures.SwitchDeclaration.TerminatingComment - case 'string': - return match (true) { - Str::length(\strip_tags($value)) !== Str::length($value) => 'html', - Str::startsWith($value, 'storage/modelfiles') => 'file', - Str::isUuid($value) => 'uuid', - Str::isUlid($value) => 'ulid', - Str::isUrl($value) => 'url', - Str::isMatch('/^[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]$/', $value) => 'youtube_video_id', - \is_numeric($value) => 'numeric', - Str::isJson($value) and - (Str::startsWith($value, '[') or Str::startsWith($value, '{')) => 'json', - default => 'string' - }; - case 'NULL': - case 'object': - case 'array': - case 'integer': - case 'boolean': - return $type; - case 'double': - return is_float($value) ? 'float' : 'double'; - case 'resource (closed)': - case 'resource': - throw new \RuntimeException('Laravel model properties should not contain resources !'); - case 'unknown type': - default: - throw new \RuntimeException('Unhandled Type ' . \gettype($value)); - } //end switch } // * RELATIONS @@ -180,9 +129,9 @@ class ActivityLog extends Model /** * User BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\User> */ - public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function user(): BelongsTo { return $this->belongsTo(User::class); } @@ -190,9 +139,9 @@ class ActivityLog extends Model /** * StaticPage BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\StaticPage> */ - public function staticPage(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function staticPage(): BelongsTo { return $this->belongsTo(StaticPage::class); } @@ -200,9 +149,9 @@ class ActivityLog extends Model /** * Settings BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\Settings> */ - public function settings(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function settings(): BelongsTo { return $this->belongsTo(Settings::class); } @@ -210,9 +159,9 @@ class ActivityLog extends Model /** * Range BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\Range> */ - public function range(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function range(): BelongsTo { return $this->belongsTo(Range::class); } @@ -220,9 +169,9 @@ class ActivityLog extends Model /** * Product BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\Product> */ - public function product(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function product(): BelongsTo { return $this->belongsTo(Product::class); } @@ -230,9 +179,9 @@ class ActivityLog extends Model /** * Prize BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\Prize> */ - public function prize(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function prize(): BelongsTo { return $this->belongsTo(Prize::class); } @@ -240,9 +189,9 @@ class ActivityLog extends Model /** * Participation BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\Participation> */ - public function participation(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function participation(): BelongsTo { return $this->belongsTo(Participation::class); } @@ -250,9 +199,9 @@ class ActivityLog extends Model /** * InstantWin BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\InstantWin> */ - public function instantWin(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function instantWin(): BelongsTo { return $this->belongsTo(InstantWin::class); } @@ -260,9 +209,9 @@ class ActivityLog extends Model /** * FaqTheme BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\FaqTheme> */ - public function faqTheme(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function faqTheme(): BelongsTo { return $this->belongsTo(FaqTheme::class); } @@ -270,9 +219,9 @@ class ActivityLog extends Model /** * FaqQuestion BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\FaqQuestion> */ - public function faqQuestion(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function faqQuestion(): BelongsTo { return $this->belongsTo(FaqQuestion::class); } @@ -280,9 +229,9 @@ class ActivityLog extends Model /** * Customer BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\Customer> */ - public function customer(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function customer(): BelongsTo { return $this->belongsTo(Customer::class); } @@ -290,9 +239,9 @@ class ActivityLog extends Model /** * Code BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\Code> */ - public function code(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function code(): BelongsTo { return $this->belongsTo(Code::class); } @@ -300,9 +249,9 @@ class ActivityLog extends Model /** * BannedIp BelongsTo relation. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo<$this,\App\Models\BannedIp> */ - public function bannedIp(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function bannedIp(): BelongsTo { return $this->belongsTo(BannedIp::class); } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 438e4db..1cf114d 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\Models\User; use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; use Illuminate\Http\Request; @@ -40,6 +41,8 @@ class RouteServiceProvider extends ServiceProvider Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web-re7.php')); + + Route::model('user', User::class); }); } diff --git a/app/Traits/Controllers/UpdateModelPublished.php b/app/Traits/Controllers/UpdateModelPublished.php index 05691b1..50d08b8 100644 --- a/app/Traits/Controllers/UpdateModelPublished.php +++ b/app/Traits/Controllers/UpdateModelPublished.php @@ -1,8 +1,11 @@ update(['published' => !$model->getOriginal('published')]); + $model->update(['published' => ! $model->getOriginal('published')]); + return redirect()->back()->with('success', trans(__('crud.messages.publish_status_saved'))); } }