Skip to content

Commit

Permalink
refactor: Deprecating Doctrine FlexDateType, Adding StringFlexDateDat…
Browse files Browse the repository at this point in the history
…aTransformer, Validations withing FlexDateType, Adding FlexDate Validator
  • Loading branch information
philipsorst committed May 3, 2024
1 parent 292719c commit 4d195d5
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 9 deletions.
3 changes: 3 additions & 0 deletions src/Doctrine/Type/FlexDateType.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
use Dontdrinkandroot\Common\FlexDate;
use Override;

/**
* @deprecated Objects are compared by reference so updates are not tracked, https://github.com/doctrine/orm/issues/5542
*/
class FlexDateType extends StringType
{
final public const NAME = 'ddr_flexdate';

Check failure on line 16 in src/Doctrine/Type/FlexDateType.php

View workflow job for this annotation

GitHub Actions / phpunit-and-psalm / Psalm

MissingClassConstType

src/Doctrine/Type/FlexDateType.php:16:24: MissingClassConstType: Class constant "Dontdrinkandroot\BridgeBundle\Doctrine\Type\FlexDateType::NAME" should have a declared type. (see https://psalm.dev/359)
Expand Down
35 changes: 35 additions & 0 deletions src/Form/DataTransformer/StringFlexDateDataTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Dontdrinkandroot\BridgeBundle\Form\DataTransformer;

use Dontdrinkandroot\Common\FlexDate;
use Dontdrinkandroot\Common\StringUtils;
use Override;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

/**
* @implements DataTransformerInterface<string, FlexDate>
*/
class StringFlexDateDataTransformer implements DataTransformerInterface
{
#[Override]
public function transform(mixed $value): FlexDate
{
if (StringUtils::isEmpty($value)) {
return new FlexDate();
}

return FlexDate::fromString($value);
}

#[Override]
public function reverseTransform(mixed $value): ?string
{
if (null === $value || $value->isEmpty()) {
return null;
}

return (string)$value;
}
}
37 changes: 34 additions & 3 deletions src/Form/Type/FlexDateType.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints as Assert;

class FlexDateType extends AbstractType
{
Expand All @@ -23,6 +24,17 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'label' => false,
'required' => false,
'attr' => ['class' => 'year', 'placeholder' => 'year', 'min' => 0],
'constraints' => [
new Assert\Range(['min' => 0]),
new Assert\Length(['min' => 4, 'max' => 4]),
new Assert\Expression(
[
'expression' => 'value == null && this.getParent().getViewData().getMonth() != null',
'message' => 'ddr.flexdate.yearnotset',
'negate' => false
]
),
]
]
)
->add(
Expand All @@ -34,7 +46,17 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'choices' => $this->getMonthChoices(),
'placeholder' => 'month',
'attr' => ['class' => 'month'],
'choice_translation_domain' => false
'choice_translation_domain' => false,
'constraints' => [
new Assert\Range(['min' => 1, 'max' => 12]),
new Assert\Expression(
[
'expression' => 'value == null && this.getParent().getViewData().getDay() != null',
'message' => 'ddr.flexdate.monthnotset',
'negate' => false
]
),
]
]
)
->add(
Expand All @@ -46,15 +68,24 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'choices' => $this->getDayChoices(),
'placeholder' => 'day',
'attr' => ['class' => 'day'],
'choice_translation_domain' => false
'choice_translation_domain' => false,
'constraints' => [
new Assert\Range(['min' => 1, 'max' => 31]),
new Assert\Expression(
[
'expression' => 'value != null && !this.getParent().getViewData().isValidDate()',
'message' => 'ddr.flexdate.dateinvalid',
'negate' => false
]
),
]
]
);
}

#[Override]
public function configureOptions(OptionsResolver $resolver): void
{
parent::configureOptions($resolver);
$resolver->setDefault('translation_domain', 'FlexDate');
$resolver->setDefault('data_class', FlexDate::class);
$resolver->setDefault('attr', ['class' => 'flexdate']);
Expand Down
11 changes: 11 additions & 0 deletions src/Validator/FlexDate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Dontdrinkandroot\BridgeBundle\Validator;

use Attribute;
use Symfony\Component\Validator\Constraint;

#[Attribute]
class FlexDate extends Constraint
{
}
36 changes: 36 additions & 0 deletions src/Validator/FlexDateValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Dontdrinkandroot\BridgeBundle\Validator;

use Override;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedValueException;

class FlexDateValidator extends ConstraintValidator
{
public const string PATTERN = '/^\d{4}(-\d{2}(-\d{2})?)?$/';

#[Override]
public function validate(mixed $value, Constraint $constraint): void
{
if (null === $value || '' === $value) {
return;
}

if (!is_string($value)) {
throw new UnexpectedValueException($value, 'string');
}

if (!preg_match(self::PATTERN, $value)) {
$this->context->buildViolation('ddr.flexdate.formatinvalid')
->addViolation();
return;
}

if (!\Dontdrinkandroot\Common\FlexDate::fromString($value)->isValidDate()) {
$this->context->buildViolation('ddr.flexdate.dateinvalid')
->addViolation();
}
}
}
5 changes: 2 additions & 3 deletions src/Validator/Security/PasswordValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

namespace Dontdrinkandroot\BridgeBundle\Validator\Security;

use Override;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class PasswordValidator extends ConstraintValidator
{
/**
* {@inheritdoc}
*/
#[Override]
public function validate(mixed $value, Constraint $constraint): void
{
if (!is_string($value) || '' === $value) {
Expand Down
6 changes: 3 additions & 3 deletions translations/FlexDate.en.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
year: Jahr
month: Monat
day: Tag
year: Year
month: Month
day: Day
1 change: 1 addition & 0 deletions translations/validators.de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ ddr:
yearnotset: Das Jahr ist nicht gesetzt.
monthnotset: Der Monat ist nicht gesetzt.
dateinvalid: Das angegebene Datum existiert nicht.
formatinvalid: Das Datum hat ein ungültiges Format.
repeated_field_mismatch: 'Die Felder stimmen nicht überein.'
1 change: 1 addition & 0 deletions translations/validators.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ ddr:
yearnotset: The year is not set.
monthnotset: The month is not set.
dateinvalid: The date does not exist.
formatinvalid: The date has an invalid format.
repeated_field_mismatch: 'The fields do not match.'

0 comments on commit 4d195d5

Please sign in to comment.