Skip to content

Commit

Permalink
fix(setting) Update setting system (wip)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrAnyx committed Dec 19, 2024
1 parent bcd61da commit 232d20b
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 78 deletions.
9 changes: 5 additions & 4 deletions src/Controller/TestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@

use App\Attribute\RelativeToEntity;
use App\Entity\Topic;
use App\Enum\SettingName;
use App\Entity\User;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;

#[Route('/api/_internal', name: 'api_', format: 'json')]
#[RelativeToEntity(Topic::class)]
class TestController extends AbstractRestController
{
#[Route('/test', name: 'test')]
public function index(
#[CurrentUser]
User $user,
): JsonResponse {
dd($this->getUserSetting(SettingName::COLOR_THEME));

return $this->json(null);
return $this->json($user, context: ['groups' => ['read:user:user']]);
}
}
2 changes: 1 addition & 1 deletion src/Controller/User/UserBehaviorController.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ classname: SettingDTO::class,
);

try {
$defaultSetting = SettingTemplate::getSetting($setting->name);
$defaultSetting = SettingTemplate::getSettingEntry($setting->name);
$defaultSetting->setValue($setting->value);
} catch (\Exception $e) {
throw new BadRequestHttpException($e->getMessage(), $e);
Expand Down
22 changes: 4 additions & 18 deletions src/Entity/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
use Symfony\Component\Validator\Validation;

#[ORM\Entity(repositoryClass: SettingRepository::class)]
class Setting
Expand All @@ -36,8 +35,8 @@ class Setting
public function __construct(SettingEntry $settingEntry, User $user)
{
$this
->setName($settingEntry->getName(true))
->setValue($settingEntry->getSerializedValue())
->setName($settingEntry->name)
->setValue($settingEntry->serialize())
->setUser($user);
}

Expand All @@ -60,22 +59,9 @@ public function setName(SettingName $name): static

public function getValue(): mixed
{
$templateSetting = SettingTemplate::getSetting($this->name);
$templateSetting = SettingTemplate::getSettingEntry($this->name);

try {
$storedValue = $templateSetting->serializer->deserialize($this->value);

$validator = Validation::createValidator();
$errors = $validator->validate($storedValue, $templateSetting->constraints);

if (\count($errors) > 0) {
throw new \InvalidArgumentException($errors[0]->getMessage());
}

return $storedValue;
} catch (\Exception) {
return $templateSetting->getValue();
}
return $templateSetting->deserialize($this->value);
}

public function setValue(string $value): static
Expand Down
4 changes: 2 additions & 2 deletions src/Entity/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,14 @@ public function updateSetting(SettingEntry $setting): static
$existingSetting = null;

foreach ($this->settings as $existing) {
if ($existing->getName() === $setting->getName(true)) {
if ($existing->getName() === $setting->name) {
$existingSetting = $existing;
break;
}
}

if ($existingSetting !== null) {
$existingSetting->setValue($setting->getSerializedValue());
$existingSetting->setValue($setting->serialize());
} else {
$newSetting = new Setting($setting, $this);
$this->settings->add($newSetting);
Expand Down
81 changes: 37 additions & 44 deletions src/Setting/SettingEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,78 +6,71 @@

use App\Enum\SettingName;
use App\Serializer\SerializerInterface;
use App\Service\ObjectInitializer;
use App\Trait\UseValidationTrait;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Validation;

class SettingEntry
{
public readonly SerializerInterface $serializer;
use UseValidationTrait;

/**
* @var Constraint[]
*/
public readonly array $constraints;

public readonly SettingName $name;

public mixed $value;
private mixed $value;

/**
* @param Constraint[] $constraints
*/
public function __construct(SettingName $name, mixed $defaultValue, string $serializer, array $serializerConstructorArgs = [], array $constraints = [])
{
$this->name = $name;
$this->value = $defaultValue;

if (!is_a($serializer, SerializerInterface::class, true)) {
throw new \InvalidArgumentException(\sprintf('Serializer %s must implement %s', $serializer, SerializerInterface::class));
}

$this->serializer = ObjectInitializer::initialize($serializer, $serializerConstructorArgs);
$this->constraints = $constraints;

$this->canSerialize();
}

/**
* @param bool $asEnum If true, returns the name as a SettingName enum; otherwise, returns the name as a string
*
* @return string|SettingName The name of the setting, either as a string or as a SettingName enum, depending on the value of $asEnum
*/
public function getName(bool $asEnum = false): string|SettingName
{
return $asEnum ? $this->name : $this->name->value;
public function __construct(
public readonly SettingName $name,
mixed $value,
public readonly SerializerInterface $serializer,
/** @var Constraint[] */
public readonly array $constraints = [],
) {
$this->setValue($value);
}

public function getValue(): mixed
{
return $this->value;
}

public function setValue(mixed $value): static
public function setValue(mixed $value): self
{
$this->validateMixedValue($value);

$this->value = $value;
$this->canSerialize();

return $this;
}

public function getSerializedValue(): string
public function serialize(): string
{
$this->validateMixedValue($this->value);

return $this->serializer->serialize($this->value);
}

private function canSerialize(): void
public function deserialize(string $rawValue): mixed
{
$this->serializer->canSerialize($this->value);

$validator = Validation::createValidator();
$errors = $validator->validate($this->value, $this->constraints);
try {
$this->validateStringValue($rawValue);

if (\count($errors) > 0) {
throw new \InvalidArgumentException($errors[0]->getMessage());
return $this->serializer->deserialize($rawValue);
} catch (\Exception) {
return $this->value;
}
}

private function validateMixedValue(mixed $value): void
{
$this->serializer->canSerialize($value);
$this->validate($value, $this->constraints);
}

private function validateStringValue(mixed $rawValue): void
{
$this->serializer->canDeserialize($rawValue);
$value = $this->serializer->deserialize($rawValue);

$this->validate($value, $this->constraints);
}
}
18 changes: 9 additions & 9 deletions src/Setting/SettingTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ class SettingTemplate
public static function getTemplate(): array
{
return [
new SettingEntry(SettingName::ITEMS_PER_PAGE, 50, IntegerSerializer::class, [], [
new SettingEntry(SettingName::ITEMS_PER_PAGE, 50, new IntegerSerializer(), [
new Assert\Range(min: 1, max: 1000),
]),
new SettingEntry(SettingName::FLASHCARD_PER_SESSION, 20, IntegerSerializer::class, [], [
new SettingEntry(SettingName::FLASHCARD_PER_SESSION, 20, new IntegerSerializer(), [
new Assert\Range(min: 1, max: 50),
]),
new SettingEntry(SettingName::COLOR_THEME, 'system', StringSerializer::class, [], [
new SettingEntry(SettingName::COLOR_THEME, 'system', new StringSerializer(), [
new Assert\Choice(['light', 'dark', 'system']),
]),
new SettingEntry(SettingName::PRIMARY_COLOR, 'sky', StringSerializer::class, [], [
new SettingEntry(SettingName::PRIMARY_COLOR, 'sky', new StringSerializer(), [
new Assert\Choice(['red', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose']),
]),
new SettingEntry(SettingName::GRAY_COLOR, 'cool', StringSerializer::class, [], [
new SettingEntry(SettingName::GRAY_COLOR, 'cool', new StringSerializer(), [
new Assert\Choice(['slate', 'cool', 'zinc', 'neutral', 'stone']),
]),
new SettingEntry(SettingName::SHOW_SESSION_INTRODUCTION, true, BooleanSerializer::class),
new SettingEntry(SettingName::SHOW_SESSION_INTRODUCTION, true, new BooleanSerializer()),
];
}

Expand All @@ -45,18 +45,18 @@ public static function getAssociativeTemplate(): array
$template = [];

foreach (self::getTemplate() as $setting) {
$template[$setting->getName()] = $setting->getValue();
$template[$setting->name->value] = $setting->getValue();
}

return $template;
}

public static function getSetting(SettingName $name): SettingEntry
public static function getSettingEntry(SettingName $name): SettingEntry
{
$settings = self::getTemplate();

foreach ($settings as $setting) {
if ($setting->getName(true) === $name) {
if ($setting->name === $name) {
return $setting;
}
}
Expand Down

0 comments on commit 232d20b

Please sign in to comment.