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;
|
2024-04-15 14:41:23 +02:00
|
|
|
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-19 17:03:25 +02:00
|
|
|
use Illuminate\Support\Arr;
|
2024-09-26 12:18:18 +02:00
|
|
|
use Illuminate\Support\Facades\Cache;
|
2024-04-09 12:31:45 +02:00
|
|
|
|
|
|
|
|
/**
|
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.
|
2024-04-15 14:41:23 +02:00
|
|
|
* phpcs:ignore Generic.Files.LineLength.TooLong
|
2024-07-17 09:44:08 +02:00
|
|
|
* @property array<\App\Lib\Definitions\MenuNode>|array<string,array<string|null>>|array<string,int> $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 = [
|
2024-04-19 17:03:25 +02:00
|
|
|
'value'
|
2024-04-09 12:31:45 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The attributes that should be cast.
|
|
|
|
|
*
|
|
|
|
|
* @var array<string, string>
|
|
|
|
|
*/
|
|
|
|
|
protected $casts = [
|
2024-04-25 10:43:44 +02:00
|
|
|
'type' => SettingsType::class,
|
2024-04-09 12:31:45 +02:00
|
|
|
'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-08-30 15:14:57 +02:00
|
|
|
static::creating(fn() => throw new \ErrorException('Not allowed to create an instance of this'));
|
2024-04-15 14:41:23 +02:00
|
|
|
static::updated(function (self $model) {
|
|
|
|
|
if ($model->type === SettingsType::hotNews) {
|
2024-04-19 17:03:25 +02:00
|
|
|
FileStorageHelper::removeOldFiles(
|
|
|
|
|
Arr::wrap(Arr::get($model->getOriginal('value'), 'picture')),
|
|
|
|
|
Arr::wrap($model->value['picture'])
|
|
|
|
|
);
|
2024-04-15 14:41:23 +02:00
|
|
|
}
|
2024-04-18 12:05:10 +02:00
|
|
|
self::removeCached();
|
2024-09-26 12:18:18 +02:00
|
|
|
self::resetCache($model->type);
|
2024-04-15 14:41:23 +02:00
|
|
|
});
|
2024-08-30 15:14:57 +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
|
|
|
|
|
*/
|
2024-10-04 17:03:04 +02:00
|
|
|
public function getRouteKey(): mixed
|
2024-04-09 12:31:45 +02:00
|
|
|
{
|
|
|
|
|
/** @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
|
|
|
|
|
|
|
|
|
|
/**
|
2024-10-04 17:03:04 +02:00
|
|
|
* Mutator for 'value' attribute.
|
2024-04-09 12:31:45 +02:00
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Database\Eloquent\Casts\Attribute
|
|
|
|
|
*/
|
2024-10-04 17:03:04 +02:00
|
|
|
public function value(): \Illuminate\Database\Eloquent\Casts\Attribute
|
2024-04-09 12:31:45 +02:00
|
|
|
{
|
|
|
|
|
return Attribute::make(
|
2024-08-30 15:14:57 +02:00
|
|
|
get: fn($value): array => self::valueFromJson($this->type, $value),
|
2024-04-09 12:31:45 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// * METHODS
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the json layout for a setting type.
|
|
|
|
|
*
|
|
|
|
|
* @param \App\Enums\Settings\SettingsType $type
|
|
|
|
|
*
|
|
|
|
|
* ! Note complete this with pipes when adding another SettingsType.
|
2024-06-24 14:20:09 +02:00
|
|
|
* @return array<\App\Lib\Definitions\MenuNode>|array<string,array<string|null>>
|
2024-04-09 12:31:45 +02:00
|
|
|
* @throws \ErrorException If $type is unhandled.
|
|
|
|
|
*/
|
|
|
|
|
public static function getJsonLayout(SettingsType $type): array
|
|
|
|
|
{
|
|
|
|
|
return match ($type) {
|
2024-08-30 15:14:57 +02:00
|
|
|
SettingsType::mainMenu => collect(MenuNodeType::all())
|
|
|
|
|
->filter(fn(MenuNodeType $menuNodeType) => $menuNodeType !== MenuNodeType::link)
|
2024-10-09 16:22:17 +02:00
|
|
|
->map(fn(MenuNodeType $nodeType, int $key) => MenuNode::make(
|
|
|
|
|
$key + 1,
|
2024-04-09 12:31:45 +02:00
|
|
|
$nodeType->value(),
|
2024-04-25 10:43:44 +02:00
|
|
|
true,
|
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(),
|
2024-08-30 15:14:57 +02:00
|
|
|
SettingsType::hotNews => [
|
2024-05-22 12:02:14 +02:00
|
|
|
'text' => 'le texte',
|
2024-05-15 12:40:31 +02:00
|
|
|
'picture' => null,
|
2024-04-15 14:41:23 +02:00
|
|
|
'picture_alt' => 'le texte alt de l\'image',
|
2024-05-15 12:40:31 +02:00
|
|
|
'picture_title' => 'le titre de l\'image',
|
|
|
|
|
],
|
2024-08-30 15:14:57 +02:00
|
|
|
SettingsType::offersCount => [
|
2024-07-17 09:44:08 +02:00
|
|
|
'count' => 0,
|
|
|
|
|
],
|
2024-10-09 17:29:03 +02:00
|
|
|
SettingsType::breederMap => [
|
2024-08-30 15:14:57 +02:00
|
|
|
'title' => 'titre',
|
|
|
|
|
'main_text' => 'texte principal',
|
|
|
|
|
'picto_text' => 'texte du pictogramme',
|
|
|
|
|
],
|
|
|
|
|
// @phpstan-ignore-next-line
|
2024-04-09 12:31:45 +02:00
|
|
|
default => throw new \ErrorException("No instruction to seed setting type '{$type->label()}'")
|
2024-04-25 10:43:44 +02:00
|
|
|
}; //end match
|
2024-04-09 12:31:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2024-10-04 17:03:04 +02:00
|
|
|
* Unserialize setting value.
|
2024-04-09 12:31:45 +02:00
|
|
|
*
|
|
|
|
|
* @param \App\Enums\Settings\SettingsType $type
|
|
|
|
|
* @param string $json
|
|
|
|
|
* ! Note complete this with pipes when adding another SettingsType.
|
2024-06-24 14:20:09 +02:00
|
|
|
* @return array<\App\Lib\Definitions\MenuNode>|array<string,array<string|null>>
|
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) {
|
2024-08-30 15:14:57 +02:00
|
|
|
SettingsType::mainMenu => collect(json_decode($json, true))
|
|
|
|
|
->map(fn(array $jsonLayout) => MenuNode::make(...$jsonLayout))->all(),
|
2024-10-09 17:29:03 +02:00
|
|
|
SettingsType::hotNews => json_decode($json, true),
|
|
|
|
|
SettingsType::offersCount => json_decode($json, true),
|
|
|
|
|
SettingsType::breederMap => json_decode($json, true),
|
2024-08-30 15:14:57 +02:00
|
|
|
// @phpstan-ignore-next-line
|
2024-04-09 12:31:45 +02:00
|
|
|
default => throw new \ErrorException("No instruction to unserialize setting type '{$type->label()}'")
|
|
|
|
|
};
|
|
|
|
|
}
|
2024-09-26 12:18:18 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reset all cache elements related to this model.
|
2024-09-27 10:26:15 +02:00
|
|
|
*
|
|
|
|
|
* @param \App\Enums\Settings\SettingsType $type
|
2024-09-26 12:18:18 +02:00
|
|
|
* @return void
|
|
|
|
|
*/
|
2024-10-04 17:03:04 +02:00
|
|
|
private static function resetCache(SettingsType $type): void
|
2024-09-26 12:18:18 +02:00
|
|
|
{
|
2024-10-01 15:02:24 +02:00
|
|
|
Cache::forget(sprintf('%sGeneralSetting', $type->name));
|
2024-09-26 12:18:18 +02:00
|
|
|
self::getCachedGeneralSetting($type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get cached general setting associated to a given type.
|
2024-09-27 10:26:15 +02:00
|
|
|
*
|
2024-09-26 12:18:18 +02:00
|
|
|
* @param \App\Enums\Settings\SettingsType $type
|
2024-10-04 17:03:04 +02:00
|
|
|
* @return mixed
|
2024-09-26 12:18:18 +02:00
|
|
|
*/
|
2024-10-04 17:03:04 +02:00
|
|
|
public static function getCachedGeneralSetting(SettingsType $type): mixed
|
2024-09-26 12:18:18 +02:00
|
|
|
{
|
|
|
|
|
return Cache::rememberForever(
|
|
|
|
|
sprintf('%sGeneralSetting', $type->name),
|
|
|
|
|
fn() => self::query()->where('type', $type)->first()
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-04-09 12:31:45 +02:00
|
|
|
}
|