Skip to content

Commit

Permalink
Add weekdays value object
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian Kolb committed Jun 9, 2024
1 parent e10fb10 commit 78e5028
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/DependencyInjection/DoctrineTypeRegisterCompilerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use DigitalCraftsman\DateTimePrecision\Doctrine\MomentType;
use DigitalCraftsman\DateTimePrecision\Doctrine\MonthType;
use DigitalCraftsman\DateTimePrecision\Doctrine\TimeType;
use DigitalCraftsman\DateTimePrecision\Doctrine\WeekdaysType;
use DigitalCraftsman\DateTimePrecision\Doctrine\WeekdayType;
use DigitalCraftsman\DateTimePrecision\Doctrine\YearType;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
Expand All @@ -25,6 +26,7 @@ public function process(ContainerBuilder $container): void
$typeDefinitions['dtp_moment'] = ['class' => MomentType::class];
$typeDefinitions['dtp_time'] = ['class' => TimeType::class];
$typeDefinitions['dtp_weekday'] = ['class' => WeekdayType::class];
$typeDefinitions['dtp_weekdays'] = ['class' => WeekdaysType::class];
$typeDefinitions['dtp_date'] = ['class' => DateType::class];
$typeDefinitions['dtp_month'] = ['class' => MonthType::class];
$typeDefinitions['dtp_year'] = ['class' => YearType::class];
Expand Down
56 changes: 56 additions & 0 deletions src/Doctrine/WeekdaysType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace DigitalCraftsman\DateTimePrecision\Doctrine;

use DigitalCraftsman\DateTimePrecision\Weekdays;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\JsonType;

final class WeekdaysType extends JsonType
{
/** @codeCoverageIgnore */
public function getName(): string
{
return 'dtp_weekdays';
}

/** @param Weekdays|null $value */
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
{
if ($value === null) {
return null;
}

$array = $value->normalize();

return json_encode($array, JSON_THROW_ON_ERROR);
}

/** @param string|null $value */
public function convertToPHPValue($value, AbstractPlatform $platform): ?Weekdays
{
if ($value === null) {
return null;
}

$array = json_decode($value, true, 512, JSON_THROW_ON_ERROR);

return Weekdays::denormalize($array);
}

/** @codeCoverageIgnore */
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
$column['jsonb'] = true;

return $platform->getJsonTypeDeclarationSQL($column);
}

/** @codeCoverageIgnore */
public function requiresSQLCommentHint(AbstractPlatform $platform): bool
{
return true;
}
}
3 changes: 3 additions & 0 deletions src/Resources/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ services:
DigitalCraftsman\DateTimePrecision\Serializer\WeekdayNormalizer:
tags: [ { name: 'serializer.normalizer' } ]

DigitalCraftsman\DateTimePrecision\Serializer\WeekdaysNormalizer:
tags: [ { name: 'serializer.normalizer' } ]

DigitalCraftsman\DateTimePrecision\Serializer\DateNormalizer:
tags: [ { name: 'serializer.normalizer' } ]

Expand Down
49 changes: 49 additions & 0 deletions src/Serializer/WeekdaysNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace DigitalCraftsman\DateTimePrecision\Serializer;

use DigitalCraftsman\DateTimePrecision\Weekdays;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

final class WeekdaysNormalizer implements NormalizerInterface, DenormalizerInterface
{
public function supportsNormalization($data, $format = null, array $context = []): bool
{
return $data instanceof Weekdays;
}

/** @param class-string $type */
public function supportsDenormalization($data, $type, $format = null, array $context = []): bool
{
return $type === Weekdays::class;
}

/** @param Weekdays|null $object */
public function normalize($object, $format = null, array $context = []): ?array
{
return $object?->normalize();
}

/** @param ?array $data */
public function denormalize($data, $type, $format = null, array $context = []): ?Weekdays
{
return $data === null
? null
: Weekdays::denormalize($data);
}

/**
* @return array<class-string, bool>
*
* @codeCoverageIgnore
*/
public function getSupportedTypes(?string $format): array
{
return [
Weekdays::class => true,
];
}
}
54 changes: 54 additions & 0 deletions src/Weekdays.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace DigitalCraftsman\DateTimePrecision;

final readonly class Weekdays
{
// Construction

/** @param array<int, Weekday> $weekdays */
public function __construct(
/** @var array<int, Weekday> $weekdays */
public array $weekdays,
) {
// TODO: Validate for unique
}

// -- Array normalizable

/** @param array<int, string> $array */
public static function denormalize(array $array): self
{
$weekdays = [];
foreach ($array as $value) {
$weekdays[] = Weekday::from($value);
}

return new self($weekdays);
}

/** @return array<int, string> */
public function normalize(): array
{
$weekdayStrings = [];
foreach ($this->weekdays as $weekday) {
$weekdayStrings[] = $weekday->value;
}

return $weekdayStrings;
}

// Accessors

public function contains(Weekday $weekday): bool
{
return in_array($weekday, $this->weekdays, true);
}

public function notContains(Weekday $weekday): bool
{
return !in_array($weekday, $this->weekdays, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use DigitalCraftsman\DateTimePrecision\Doctrine\MomentType;
use DigitalCraftsman\DateTimePrecision\Doctrine\MonthType;
use DigitalCraftsman\DateTimePrecision\Doctrine\TimeType;
use DigitalCraftsman\DateTimePrecision\Doctrine\WeekdaysType;
use DigitalCraftsman\DateTimePrecision\Doctrine\WeekdayType;
use DigitalCraftsman\DateTimePrecision\Doctrine\YearType;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -46,6 +47,9 @@ public function process_works(): void
self::assertArrayHasKey('dtp_weekday', $updatedParameters);
self::assertSame(['class' => WeekdayType::class], $updatedParameters['dtp_weekday']);

self::assertArrayHasKey('dtp_weekdays', $updatedParameters);
self::assertSame(['class' => WeekdaysType::class], $updatedParameters['dtp_weekdays']);

self::assertArrayHasKey('dtp_date', $updatedParameters);
self::assertSame(['class' => DateType::class], $updatedParameters['dtp_date']);

Expand Down

0 comments on commit 78e5028

Please sign in to comment.