-
Notifications
You must be signed in to change notification settings - Fork 2
YCRO-300 add backend validation for info collector forms #56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Netgen\Bundle\SiteBundle\InfoCollection\Form\Extension; | ||
|
|
||
| use Ibexa\Contracts\ContentForms\Data\Content\FieldData; | ||
| use Netgen\Bundle\InformationCollectionBundle\Ibexa\ContentForms\InformationCollectionFieldType; | ||
| use Netgen\Bundle\InformationCollectionBundle\Ibexa\ContentForms\InformationCollectionType; | ||
| use Netgen\Bundle\SiteBundle\InfoCollection\Validator\Constraints\CustomEmail; | ||
| use Symfony\Component\Form\AbstractTypeExtension; | ||
| use Symfony\Component\Form\FormBuilderInterface; | ||
| use Symfony\Component\OptionsResolver\OptionsResolver; | ||
|
|
||
| final class EmailFormExtension extends AbstractTypeExtension | ||
| { | ||
| public static function getExtendedTypes(): iterable | ||
| { | ||
| return [InformationCollectionType::class]; | ||
| } | ||
|
|
||
| public function configureOptions(OptionsResolver $resolver): void | ||
| { | ||
| $resolver->setDefault('translation_domain', 'validators'); | ||
| } | ||
|
|
||
| public function buildForm(FormBuilderInterface $builder, array $options): void | ||
| { | ||
| foreach ($builder->getData()->getCollectedFields() as $identifier => $fieldData) { | ||
| /** @var FieldData $fieldData */ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this |
||
| if ($fieldData->fieldDefinition->fieldTypeIdentifier === 'ezemail') { | ||
| $emailOptions = $builder->get($identifier)->getOptions(); | ||
|
|
||
| $customEmailExists = false; | ||
| foreach ($emailOptions['constraints'] as $constraint) { | ||
| if ($constraint instanceof CustomEmail) { | ||
| $customEmailExists = true; | ||
|
|
||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (!$customEmailExists) { | ||
| $emailOptions['constraints'][] = new CustomEmail(); | ||
| } | ||
|
|
||
| $builder->add($identifier, InformationCollectionFieldType::class, $emailOptions); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Netgen\Bundle\SiteBundle\InfoCollection\Form\Extension; | ||
|
|
||
| use Ibexa\Contracts\ContentForms\Data\Content\FieldData; | ||
| use Netgen\Bundle\InformationCollectionBundle\Ibexa\ContentForms\InformationCollectionFieldType; | ||
| use Netgen\Bundle\InformationCollectionBundle\Ibexa\ContentForms\InformationCollectionType; | ||
| use Netgen\Bundle\SiteBundle\InfoCollection\Validator\Constraints\RequiredField; | ||
| use Symfony\Component\Form\AbstractTypeExtension; | ||
| use Symfony\Component\Form\FormBuilderInterface; | ||
| use Symfony\Component\OptionsResolver\OptionsResolver; | ||
|
|
||
| final class RequiredFieldFormExtension extends AbstractTypeExtension | ||
| { | ||
| public static function getExtendedTypes(): iterable | ||
| { | ||
| return [InformationCollectionType::class]; | ||
| } | ||
|
|
||
| public function configureOptions(OptionsResolver $resolver): void | ||
| { | ||
| $resolver->setDefaults([ | ||
| 'translation_domain' => 'validators', | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need this here, we're not translating anything here, besides |
||
| 'attr' => [ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need this? Isn't this something for template to control and not the form extension? |
||
| 'class' => 'embed-form js-form-embed', | ||
| ], | ||
| ]); | ||
| } | ||
|
|
||
| public function buildForm(FormBuilderInterface $builder, array $options): void | ||
| { | ||
| foreach ($builder->getData()->getCollectedFields() as $identifier => $fieldData) { | ||
| /** @var FieldData $fieldData */ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this @var? If yes, please use FQCN in the typehint. |
||
| if ($fieldData->fieldDefinition->isRequired === true) { | ||
| $fieldOptions = $builder->get($identifier)->getOptions(); | ||
|
|
||
| $hasRequiredFieldConstraint = false; | ||
|
|
||
| foreach ($fieldOptions['constraints'] as $constraint) { | ||
| if ($constraint instanceof RequiredField) { | ||
| $hasRequiredFieldConstraint = true; | ||
|
|
||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (!$hasRequiredFieldConstraint) { | ||
| $fieldOptions['constraints'][] = new RequiredField(); | ||
| $builder->add($identifier, InformationCollectionFieldType::class, $fieldOptions); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Netgen\Bundle\SiteBundle\InfoCollection\Validator\Constraints; | ||
|
|
||
| use Symfony\Component\Validator\Constraint; | ||
|
|
||
| final class CustomEmail extends Constraint | ||
| { | ||
| public string $message = 'email_is_not_valid'; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Netgen\Bundle\SiteBundle\InfoCollection\Validator\Constraints; | ||
|
|
||
| use Symfony\Component\Validator\Constraint; | ||
| use Symfony\Component\Validator\ConstraintValidator; | ||
| use Symfony\Component\Validator\Exception\UnexpectedTypeException; | ||
|
|
||
| use function filter_var; | ||
|
|
||
| use const FILTER_VALIDATE_EMAIL; | ||
|
|
||
| final class CustomEmailValidator extends ConstraintValidator | ||
| { | ||
| public function validate(mixed $value, Constraint $constraint): void | ||
| { | ||
| if (!$constraint instanceof CustomEmail) { | ||
| throw new UnexpectedTypeException($constraint, CustomEmail::class); | ||
| } | ||
|
|
||
| $emailValue = $value->value->email; | ||
|
|
||
| if (filter_var($emailValue, FILTER_VALIDATE_EMAIL) === false) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of |
||
| $this->context->buildViolation($constraint->message) | ||
| ->atPath($value->fieldDefinition->identifier) | ||
| ->addViolation(); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Netgen\Bundle\SiteBundle\InfoCollection\Validator\Constraints; | ||
|
|
||
| use Symfony\Component\Validator\Constraint; | ||
|
|
||
| final class RequiredField extends Constraint | ||
| { | ||
| public string $message = 'this_value_should_not_be_blank'; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Netgen\Bundle\SiteBundle\InfoCollection\Validator\Constraints; | ||
|
|
||
| use Ibexa\Contracts\ContentForms\Data\Content\FieldData; | ||
| use Symfony\Component\Validator\Constraint; | ||
| use Symfony\Component\Validator\ConstraintValidator; | ||
|
|
||
| use function array_filter; | ||
| use function property_exists; | ||
|
|
||
| final class RequiredFieldValidator extends ConstraintValidator | ||
| { | ||
| public function validate(mixed $value, Constraint $constraint): void | ||
| { | ||
| /** @var FieldData $value */ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should check if |
||
| if ( | ||
| $value->value === null | ||
| || array_filter( | ||
| $value->value->attributes(), | ||
| static fn ($attr) => $value->value->attribute($attr) === null || $value->value->attribute($attr) === '' || $value->value->attribute($attr) === false, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The closure is missing property and return typehints. |
||
| ) !== [] | ||
| ) { | ||
| if (!property_exists($constraint, 'message')) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to check for existence of |
||
| return; | ||
| } | ||
| $this->context->buildViolation($constraint->message) | ||
| ->atPath($value->fieldDefinition->identifier) | ||
| ->addViolation(); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| this_value_should_not_be_blank: 'This value should not be blank.' | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add prefixes to these message identifiers:
This way we allow adding more messages in the future. |
||
| email_is_not_valid: 'Email is not valid.' | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing EOF at the end of file. |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this
configureOptionsmethod, we're not translating anything here, besidesvalidatorsdomain is default anyways.