<?php
namespace App\Entity;
use App\Repository\WebsiteSettingRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=WebsiteSettingRepository::class)
* @ORM\Table(name="website_setting")
* @ORM\HasLifecycleCallbacks
*/
class WebsiteSetting
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private ?int $id = null;
/**
* Clé fonctionnelle IMMUTABLE (ex: site_maintenance, homepage_mode)
*
* @ORM\Column(name="setting_key", type="string", length=100, unique=true)
*/
private string $key;
/**
* Type logique de la valeur
* Valeurs autorisées :
* string | int | float | bool | json | text
*
* @ORM\Column(type="string", length=20)
*/
private string $type;
/** @ORM\Column(type="string", length=255, nullable=true) */
private ?string $valueString = null;
/** @ORM\Column(type="integer", nullable=true) */
private ?int $valueInt = null;
/** @ORM\Column(type="float", nullable=true) */
private ?float $valueFloat = null;
/** @ORM\Column(type="boolean", nullable=true) */
private ?bool $valueBool = null;
/** @ORM\Column(type="json", nullable=true) */
private ?array $valueJson = null;
/** @ORM\Column(type="text", nullable=true) */
private ?string $valueText = null;
/** @ORM\Column(type="string", length=255, nullable=true) */
private ?string $description = null;
/**
* @ORM\Column(type="datetime_immutable")
*/
private \DateTimeImmutable $updatedAt;
public function __construct()
{
$this->updatedAt = new \DateTimeImmutable();
}
/**
* Sectione fonctionnel (website, seo, social, system, etc.)
* @ORM\Column(type="string", length=50, nullable=true)
*/
private ?string $section = 'website';
/* ======================================================
* GETTERS / SETTERS DE BASE
* ====================================================== */
public function getId(): ?int
{
return $this->id;
}
public function getKey(): string
{
return $this->key;
}
/**
* À n'utiliser qu'à la création
* La clé NE DOIT PAS changer ensuite
*/
public function setKey(string $key): self
{
$this->key = $key;
return $this;
}
public function getType(): string
{
return $this->type;
}
/**
* Le type est figé après création
*/
public function setType(string $type): self
{
$allowed = ['string','int','float','bool','json','text'];
if (!in_array($type, $allowed, true)) {
throw new \InvalidArgumentException('Type de setting invalide');
}
$this->type = $type;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function getUpdatedAt(): \DateTimeImmutable
{
return $this->updatedAt;
}
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function updateTimestamp(): void
{
$this->updatedAt = new \DateTimeImmutable();
}
private function touch(): void
{
$this->updatedAt = new \DateTimeImmutable();
}
public function getSection(): string
{
return $this->section ?? 'website';
}
public function setSection(string $section): self
{
$this->section = $section;
return $this;
}
/* ======================================================
* ACCÈS VALEUR TYPÉE (API PUBLIQUE)
* ====================================================== */
/**
* Valeur lisible par le métier / Twig / services
*/
public function getTypedValue()
{
return match ($this->type) {
'string' => $this->valueString,
'int' => $this->valueInt,
'float' => $this->valueFloat,
'bool' => $this->valueBool,
'json' => $this->valueJson,
'text' => $this->valueText,
default => null,
};
}
/**
* Setter centralisé — nettoie les autres colonnes automatiquement
*/
public function setTypedValue($value): self
{
// Reset strict pour éviter toute incohérence
$this->valueString = null;
$this->valueInt = null;
$this->valueFloat = null;
$this->valueBool = null;
$this->valueJson = null;
$this->valueText = null;
switch ($this->type) {
case 'int':
$this->valueInt = $value !== null ? (int) $value : null;
break;
case 'float':
$this->valueFloat = $value !== null ? (float) $value : null;
break;
case 'bool':
$this->valueBool = (bool) $value;
break;
case 'json':
$this->valueJson = is_array($value) ? $value : [];
break;
case 'text':
$this->valueText = $value !== null ? (string) $value : null;
break;
default: // string
$this->valueString = $value !== null ? (string) $value : null;
}
$this->touch();
return $this;
}
/* ======================================================
* HELPERS OPTIONNELS
* ====================================================== */
public function isBoolean(): bool
{
return $this->type === 'bool';
}
public function isJson(): bool
{
return $this->type === 'json';
}
public function isNumeric(): bool
{
return in_array($this->type, ['int', 'float'], true);
}
public function getValue()
{
return $this->getTypedValue();
}
public function setValue($value): self
{
switch ($this->type) {
case 'string':
$this->valueString = $value !== null ? (string) $value : null;
break;
case 'int':
$this->valueInt = $value !== null ? (int) $value : null;
break;
case 'float':
$this->valueFloat = $value !== null ? (float) $value : null;
break;
case 'bool':
$this->valueBool = (bool) $value;
break;
case 'json':
$this->valueJson = $value !== null ? (array) $value : null;
break;
case 'text':
$this->valueText = $value !== null ? (string) $value : null;
break;
}
$this->updatedAt = new \DateTimeImmutable();
return $this;
}
}