ldc-legaulois/app/Models/GeneralSetting.php

184 lines
5.7 KiB
PHP
Raw Normal View History

2024-04-09 12:31:45 +02:00
<?php
namespace App\Models;
use App\Enums\Settings\MenuNodeType;
use App\Enums\Settings\SettingsType;
use App\Lib\Definitions\MenuNode;
use App\Lib\Helpers\FileStorageHelper;
2024-04-09 12:31:45 +02:00
use App\Lib\Link;
2024-04-18 12:05:10 +02:00
use App\Traits\Models\IsCachedAsCollection;
2024-04-09 12:31:45 +02:00
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
/**
2024-04-12 10:18:11 +02:00
* @property-read \App\Enums\Settings\SettingsType $type Enum SettingsType.
2024-04-09 12:31:45 +02:00
* ! Note complete this with pipes when adding another SettingsType.
* phpcs:ignore Generic.Files.LineLength.TooLong
* @property array<\App\Lib\Definitions\MenuNode>|array<'text'|'picture'|'picture_alt'|'picture_title',string> $value The actual setting value.
2024-04-09 12:31:45 +02:00
* @package App\Models
*/
class GeneralSetting extends Model
{
2024-04-18 12:05:10 +02:00
use IsCachedAsCollection;
2024-04-09 12:31:45 +02:00
/**
* The primary key for the model.
*
* @var string
*/
protected $primaryKey = 'type';
/**
* The "type" of the primary key ID.
*
* @var string
*/
protected $keyType = SettingsType::class;
/**
* Indicates if the IDs are auto-incrementing.
*
* @var boolean
*/
public $incrementing = false;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'value',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'type' => SettingsType::class,
'value' => 'json'
];
/**
* Perform any actions required after the model boots.
*
* @return void
2024-04-12 10:18:11 +02:00
* @throws \ErrorException Not allowed to create an instance of this.
2024-04-09 12:31:45 +02:00
*/
protected static function booted(): void
{
2024-04-12 10:18:11 +02:00
static::creating(fn () => throw new \ErrorException('Not allowed to create an instance of this'));
static::updating(function (self $model) {
if ($model->type === SettingsType::hotNews) {
2024-04-19 10:08:36 +02:00
// @phpstan-ignore-next-line
$model->value = FileStorageHelper::storeFile($model, $model->value['picture'], true);
}
});
static::updated(function (self $model) {
if ($model->type === SettingsType::hotNews) {
FileStorageHelper::removeOldFile($model, $model->value['picture']);
}
2024-04-18 12:05:10 +02:00
self::removeCached();
});
2024-04-12 10:18:11 +02:00
static::deleting(fn () => throw new \ErrorException('Not allowed to create an instance of this'));
2024-04-09 12:31:45 +02:00
}
// * ROUTABLE
/**
* Get the value of the model's route key.
*
* @return mixed
*/
public function getRouteKey()
{
/** @var \App\Enums\StaticPageType */
$enum = $this->getAttribute($this->getRouteKeyName());
return $enum->value();
}
/**
* Get the route key for the model.
*
* ! Type is the routable parameter
*
* @return string
*/
public function getRouteKeyName(): string
{
return 'type';
}
// * GETTERS
/**
* Mutator for 'value' attribute
*
* @return \Illuminate\Database\Eloquent\Casts\Attribute
*/
public function value(): Attribute
{
return Attribute::make(
get: fn ($value): array => self::valueFromJson($this->type, $value),
);
}
// * METHODS
/**
* Get the json layout for a setting type.
*
* @param \App\Enums\Settings\SettingsType $type
*
* ! Note complete this with pipes when adding another SettingsType.
* @return array<\App\Lib\Definitions\MenuNode>|array<'text'|'picture'|'picture_alt'|'picture_title',string>
2024-04-09 12:31:45 +02:00
* @throws \ErrorException If $type is unhandled.
*/
public static function getJsonLayout(SettingsType $type): array
{
return match ($type) {
SettingsType::mainMenu => collect(MenuNodeType::all())
->filter(fn (MenuNodeType $menuNodeType) => $menuNodeType !== MenuNodeType::link)
->map(fn (MenuNodeType $nodeType) => MenuNode::make(
$nodeType->value(),
2024-04-11 09:37:38 +02:00
$nodeType->label(),
2024-04-09 12:31:45 +02:00
!empty($nodeType->routeName()) ?
// phpcs:ignore Generic.Files.LineLength.TooLong
(new Link(routeName: $nodeType->routeName()))->toArray() : (new Link(url: 'https://example.net'))->toArray()
))->all(),
SettingsType::hotNews => [
'picture' => asset('/app/srcs/resources/assets/images/home/hot_news/100x100.png'),
'picture_alt' => 'le texte alt de l\'image',
'picture_title' => 'le title de l\'image',
'text' => 'le texte',
],
2024-04-09 12:31:45 +02:00
// @phpstan-ignore-next-line
default => throw new \ErrorException("No instruction to seed setting type '{$type->label()}'")
};
}
/**
* Unserialize setting value
*
* @param \App\Enums\Settings\SettingsType $type
* @param string $json
* ! Note complete this with pipes when adding another SettingsType.
* @return array<\App\Lib\Definitions\MenuNode>|array<'text'|'picture'|'picture_alt'|'picture_title',string>
2024-04-09 12:31:45 +02:00
* @throws \ErrorException If $type is unhandled.
*/
public static function valueFromJson(SettingsType $type, string $json): array
{
return match ($type) {
SettingsType::mainMenu => collect(json_decode($json, true))
->map(fn (array $jsonLayout) => MenuNode::make(...$jsonLayout))->all(),
SettingsType::hotNews => json_decode($json, true),
2024-04-09 12:31:45 +02:00
// @phpstan-ignore-next-line
default => throw new \ErrorException("No instruction to unserialize setting type '{$type->label()}'")
};
}
}