From 9f5607ad44ef636f6ad9d82fc4ff3aa1406ce586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petra=20Mi=C5=A1eta?= Date: Mon, 1 Sep 2025 16:49:47 +0200 Subject: [PATCH 1/2] YCRO-300 add backend validation for info collector forms --- .../Form/Extension/EmailFormExtension.php | 49 ++++++++++++++++ .../Extension/RequiredFieldFormExtension.php | 56 +++++++++++++++++++ .../Validator/Constraints/CustomEmail.php | 10 ++++ .../Constraints/CustomEmailValidator.php | 27 +++++++++ .../Validator/Constraints/RequiredField.php | 12 ++++ .../Constraints/RequiredFieldValidator.php | 34 +++++++++++ bundle/Resources/config/info_collection.yaml | 10 ++++ .../Resources/translations/validators.en.yaml | 2 + 8 files changed, 200 insertions(+) create mode 100644 bundle/InfoCollection/Form/Extension/EmailFormExtension.php create mode 100644 bundle/InfoCollection/Form/Extension/RequiredFieldFormExtension.php create mode 100644 bundle/InfoCollection/Validator/Constraints/CustomEmail.php create mode 100644 bundle/InfoCollection/Validator/Constraints/CustomEmailValidator.php create mode 100644 bundle/InfoCollection/Validator/Constraints/RequiredField.php create mode 100644 bundle/InfoCollection/Validator/Constraints/RequiredFieldValidator.php create mode 100644 bundle/Resources/translations/validators.en.yaml diff --git a/bundle/InfoCollection/Form/Extension/EmailFormExtension.php b/bundle/InfoCollection/Form/Extension/EmailFormExtension.php new file mode 100644 index 00000000..3cb198e5 --- /dev/null +++ b/bundle/InfoCollection/Form/Extension/EmailFormExtension.php @@ -0,0 +1,49 @@ +setDefault('translation_domain', 'validators'); + } + + public function buildForm(FormBuilderInterface $builder, array $options): void + { + foreach ($builder->getData()->getCollectedFields() as $identifier => $fieldData) { + /** @var FieldData $fieldData */ + 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); + } + } + } +} diff --git a/bundle/InfoCollection/Form/Extension/RequiredFieldFormExtension.php b/bundle/InfoCollection/Form/Extension/RequiredFieldFormExtension.php new file mode 100644 index 00000000..a9a751d7 --- /dev/null +++ b/bundle/InfoCollection/Form/Extension/RequiredFieldFormExtension.php @@ -0,0 +1,56 @@ +setDefaults([ + 'translation_domain' => 'validators', + 'attr' => [ + 'class' => 'embed-form js-form-embed', + ], + ]); + } + + public function buildForm(FormBuilderInterface $builder, array $options): void + { + foreach ($builder->getData()->getCollectedFields() as $identifier => $fieldData) { + /** @var FieldData $fieldData */ + 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); + } + } + } + } +} diff --git a/bundle/InfoCollection/Validator/Constraints/CustomEmail.php b/bundle/InfoCollection/Validator/Constraints/CustomEmail.php new file mode 100644 index 00000000..81307752 --- /dev/null +++ b/bundle/InfoCollection/Validator/Constraints/CustomEmail.php @@ -0,0 +1,10 @@ +value->email; + + if (filter_var($emailValue, FILTER_VALIDATE_EMAIL) === false) { + $this->context->buildViolation($constraint->message) + ->atPath($value->fieldDefinition->identifier) + ->addViolation(); + } + } +} \ No newline at end of file diff --git a/bundle/InfoCollection/Validator/Constraints/RequiredField.php b/bundle/InfoCollection/Validator/Constraints/RequiredField.php new file mode 100644 index 00000000..b2a2e8eb --- /dev/null +++ b/bundle/InfoCollection/Validator/Constraints/RequiredField.php @@ -0,0 +1,12 @@ +value === null + || array_filter( + $value->value->attributes(), + static fn ($attr) => $value->value->attribute($attr) === null || $value->value->attribute($attr) === '' || $value->value->attribute($attr) === false, + ) !== [] + ) { + if (!property_exists($constraint, 'message')) { + return; + } + $this->context->buildViolation($constraint->message) + ->atPath($value->fieldDefinition->identifier) + ->addViolation(); + } + } +} diff --git a/bundle/Resources/config/info_collection.yaml b/bundle/Resources/config/info_collection.yaml index c80cf59a..02566be3 100644 --- a/bundle/Resources/config/info_collection.yaml +++ b/bundle/Resources/config/info_collection.yaml @@ -23,6 +23,16 @@ services: tags: - { name: netgen_information_collection.action } + ngsite.info_collection.form.extension.required_field: + class: Netgen\Bundle\SiteBundle\InfoCollection\Form\Extension\RequiredFieldFormExtension + tags: + - { name: form.type_extension, extended_type: Netgen\Bundle\InformationCollectionBundle\Ibexa\ContentForms\InformationCollectionType, priority: -100 } + + ngsite.info_collection.form.extension.email_form_extenison: + class: Netgen\Bundle\SiteBundle\InfoCollection\Form\Extension\EmailFormExtension + tags: + - { name: form.type_extension, extended_type: Netgen\Bundle\InformationCollectionBundle\Ibexa\ContentForms\InformationCollectionType, priority: -100 } + ngsite.info_collection.form.extension.honeypot_extension: class: Netgen\Bundle\SiteBundle\InfoCollection\Form\Extension\HoneypotExtension tags: diff --git a/bundle/Resources/translations/validators.en.yaml b/bundle/Resources/translations/validators.en.yaml new file mode 100644 index 00000000..fdf83cd2 --- /dev/null +++ b/bundle/Resources/translations/validators.en.yaml @@ -0,0 +1,2 @@ +this_value_should_not_be_blank: 'This value should not be blank.' +email_is_not_valid: 'Email is not valid.' \ No newline at end of file From 1ff5bee27bba6e7831d9bf106efc0687618021b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petra=20Mi=C5=A1eta?= Date: Mon, 1 Sep 2025 17:01:43 +0200 Subject: [PATCH 2/2] YCRO-300 run cs fixer --- bundle/InfoCollection/Form/Extension/EmailFormExtension.php | 4 +++- .../Form/Extension/RequiredFieldFormExtension.php | 2 +- bundle/InfoCollection/Validator/Constraints/CustomEmail.php | 4 +++- .../Validator/Constraints/CustomEmailValidator.php | 6 +++++- .../InfoCollection/Validator/Constraints/RequiredField.php | 2 +- .../Validator/Constraints/RequiredFieldValidator.php | 2 +- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/bundle/InfoCollection/Form/Extension/EmailFormExtension.php b/bundle/InfoCollection/Form/Extension/EmailFormExtension.php index 3cb198e5..4ccb48ed 100644 --- a/bundle/InfoCollection/Form/Extension/EmailFormExtension.php +++ b/bundle/InfoCollection/Form/Extension/EmailFormExtension.php @@ -1,11 +1,13 @@ addViolation(); } } -} \ No newline at end of file +} diff --git a/bundle/InfoCollection/Validator/Constraints/RequiredField.php b/bundle/InfoCollection/Validator/Constraints/RequiredField.php index b2a2e8eb..2148ff02 100644 --- a/bundle/InfoCollection/Validator/Constraints/RequiredField.php +++ b/bundle/InfoCollection/Validator/Constraints/RequiredField.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Netgen\Bundle\SiteBundle\InfoCollection\Validator\Constraints; +namespace Netgen\Bundle\SiteBundle\InfoCollection\Validator\Constraints; use Symfony\Component\Validator\Constraint; diff --git a/bundle/InfoCollection/Validator/Constraints/RequiredFieldValidator.php b/bundle/InfoCollection/Validator/Constraints/RequiredFieldValidator.php index 543bccf1..671d3988 100644 --- a/bundle/InfoCollection/Validator/Constraints/RequiredFieldValidator.php +++ b/bundle/InfoCollection/Validator/Constraints/RequiredFieldValidator.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Netgen\Bundle\SiteBundle\InfoCollection\Validator\Constraints; +namespace Netgen\Bundle\SiteBundle\InfoCollection\Validator\Constraints; use Ibexa\Contracts\ContentForms\Data\Content\FieldData; use Symfony\Component\Validator\Constraint;