Skip to content
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

Add custom validation message to international phone number form validation #6650

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
60d6ff8
Add custom validation message to international phone number form vali…
kuzmany Sep 27, 2018
519ec98
Merge remote-tracking branch 'upstream/staging' into enh-internationa…
kuzmany Oct 5, 2018
97f6109
Change validation error to shorter version
kuzmany Oct 5, 2018
2a58481
Move validation to validation tab
kuzmany Oct 5, 2018
a862024
Extend validation tab of form field
kuzmany Oct 8, 2018
1097807
Remove validation from FormFieldHelper.php (was moved to dispatcher)
kuzmany Oct 8, 2018
d36f93a
Add migrations
kuzmany Oct 8, 2018
23d4a90
Remove unnecessary mautic.form_validation_tab_on_build event
kuzmany Oct 9, 2018
b772534
Merge remote-tracking branch 'upstream/staging' into enh-internationa…
kuzmany Oct 9, 2018
a5eaf90
Revert placeholder to tel type
kuzmany Oct 9, 2018
85ad46d
Added migration from properties settings
kuzmany Oct 9, 2018
7a02de5
Fix to migrations
kuzmany Oct 9, 2018
80fd96f
Update messages.ini
npracht Nov 7, 2018
990d178
Merge remote-tracking branch 'upstream/staging' into enh-internationa…
kuzmany Nov 9, 2018
f3a0239
Fix translation
kuzmany Nov 9, 2018
5f264a8
Merge remote-tracking branch 'upstream/staging' into enh-internationa…
kuzmany Nov 19, 2018
2fff9f6
Merge remote-tracking branch 'upstream/staging' into enh-internationa…
kuzmany Nov 27, 2018
aa5f5c1
Show custom validation just for type
kuzmany Nov 27, 2018
d03dd3b
Fix phone validation
kuzmany Nov 27, 2018
af00d37
Fix typo
kuzmany Nov 27, 2018
745d7c9
Merge remote-tracking branch 'upstream/staging' into enh-internationa…
kuzmany Nov 29, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/bundles/FormBundle/Config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@
'mautic.helper.core_parameters',
],
],
'mautic.form.validation.subscriber' => [
'class' => \Mautic\FormBundle\EventListener\FormValidationSubscriber::class,
],
'mautic.form.pagebundle.subscriber' => [
'class' => PageSubscriber::class,
'arguments' => [
Expand Down Expand Up @@ -253,6 +256,9 @@
'mautic.form.type.field' => [
'class' => FieldType::class,
'alias' => 'formfield',
'arguments' => [
'translator',
],
'methodCalls' => [
'setFieldModel' => ['mautic.form.model.field'],
'setFormModel' => ['mautic.form.model.form'],
Expand Down Expand Up @@ -288,6 +294,12 @@
'translator',
],
],
'mautic.form.type.field_propertytel' => [
'class' => \Mautic\FormBundle\Form\Type\FormFieldTelType::class,
'arguments' => [
'translator',
],
],
'mautic.form.type.field_propertyfile' => [
'class' => FormFieldFileType::class,
'arguments' => [
Expand Down
6 changes: 6 additions & 0 deletions app/bundles/FormBundle/Controller/FieldController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

use Mautic\CoreBundle\Controller\FormController as CommonFormController;
use Mautic\FormBundle\Entity\Field;
use Mautic\FormBundle\Event\FormBuilderEvent;
use Mautic\FormBundle\FormEvents;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
Expand Down Expand Up @@ -397,6 +399,10 @@ private function getFieldForm($formId, array $formField)
);
$form->get('formId')->setData($formId);

$event = new FormBuilderEvent($this->get('translator'));
$this->dispatcher->dispatch(FormEvents::FORM_ON_BUILD, $event);
$event->addValidatorsToBuilder($form);

return $form;
}
}
35 changes: 35 additions & 0 deletions app/bundles/FormBundle/Entity/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ class Field
*/
private $properties = [];

/**
* @var array
*/
private $validation = [];

/**
* @var Form
*/
Expand Down Expand Up @@ -211,6 +216,10 @@ public static function loadMetadata(ORM\ClassMetadata $metadata)
->nullable()
->build();

$builder->createField('validation', 'json_array')
->nullable()
->build();

$builder->createManyToOne('form', 'Form')
->inversedBy('fields')
->addJoinColumn('form_id', 'id', false, false, 'CASCADE')
Expand Down Expand Up @@ -254,6 +263,7 @@ public static function loadApiMetadata(ApiMetadataDriver $metadata)
'helpMessage',
'order',
'properties',
'validation',
'labelAttributes',
'inputAttributes',
'containerAttributes',
Expand Down Expand Up @@ -479,6 +489,31 @@ public function getProperties()
return $this->properties;
}

/**
* Set validation.
*
* @param array $validation
*
* @return Field
*/
public function setValidation($validation)
{
$this->isChanged('validation', $validation);
$this->validation = $validation;

return $this;
}

/**
* Get validation.
*
* @return array
*/
public function getValidation()
{
return $this->validation;
}

/**
* Set validationMessage.
*
Expand Down
23 changes: 23 additions & 0 deletions app/bundles/FormBundle/Event/FormBuilderEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Mautic\CoreBundle\Event\ComponentValidationTrait;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\Form\Form;

/**
* Class FormBuilderEvent.
Expand Down Expand Up @@ -211,6 +212,28 @@ public function addValidator($key, array $validator)
$this->validators[$key] = $validator;
}

/**
* @param Form $form
*/
public function addValidatorsToBuilder(Form $form)
{
if (!empty($this->validators)) {
$validationData = (isset($form->getData()['validation'])) ? $form->getData()['validation'] : [];
foreach ($this->validators as $validator) {
if (isset($validator['formType']) && isset($validator['fieldType']) && $validator['fieldType'] == $form->getData()['type']) {
$form->add(
'validation',
$validator['formType'],
[
'label' => false,
'data' => $validationData,
]
);
}
}
}
}

/**
* Returns validators organized by ['form' => [], 'fieldType' => [], ...
*
Expand Down
70 changes: 70 additions & 0 deletions app/bundles/FormBundle/EventListener/FormValidationSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

/*
* @copyright 2014 Mautic Contributors. All rights reserved
* @author Mautic
*
* @link http://mautic.org
*
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/

namespace Mautic\FormBundle\EventListener;

use libphonenumber\NumberParseException;
use libphonenumber\PhoneNumberUtil;
use Mautic\CoreBundle\EventListener\CommonSubscriber;
use Mautic\FormBundle\Event as Events;
use Mautic\FormBundle\FormEvents;

class FormValidationSubscriber extends CommonSubscriber
{
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
FormEvents::FORM_ON_BUILD => ['onFormBuilder', 0],
FormEvents::ON_FORM_VALIDATE => ['onFormValidate', 0],
];
}

/**
* Add a simple email form.
*
* @param Events\FormBuilderEvent $event
*/
public function onFormBuilder(Events\FormBuilderEvent $event)
{
$event->addValidator(
'phone.validation',
[
'eventName' => FormEvents::ON_FORM_VALIDATE,
'fieldType' => 'tel',
'formType' => \Mautic\FormBundle\Form\Type\FormFieldTelType::class,
]
);
}

/**
* @param Events\ValidationEvent $event
*/
public function onFormValidate(Events\ValidationEvent $event)
{
$field = $event->getField();
if ($field->getType() === 'tel' && !empty($field->getValidation()['international'])) {
$value = $event->getValue();
$phoneUtil = PhoneNumberUtil::getInstance();
try {
$phoneUtil->parse($value, PhoneNumberUtil::UNKNOWN_REGION);
} catch (NumberParseException $e) {
if (!empty($field->getValidation()['international_validationmsg'])) {
$event->failedValidation($field->getValidation()['international_validationmsg']);
} else {
$event->failedValidation($this->translator->trans('mautic.form.submission.phone.invalid'));
}
}
}
}
}
44 changes: 22 additions & 22 deletions app/bundles/FormBundle/Form/Type/FieldType.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Constraints as Assert;

/**
Expand All @@ -25,6 +26,21 @@ class FieldType extends AbstractType
{
use FormFieldTrait;

/**
* @var TranslatorInterface
*/
private $translator;

/**
* FieldType constructor.
*
* @param TranslatorInterface $translator
*/
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -223,7 +239,11 @@ public function buildForm(FormBuilderInterface $builder, array $options)
[
'label' => 'mautic.form.field.form.validationmsg',
'label_attr' => ['class' => 'control-label'],
'attr' => ['class' => 'form-control'],
'attr' => [
'class' => 'form-control',
'tooltip' => $this->translator->trans('mautic.core.form.default').': '.$this->translator->trans('mautic.form.field.generic.required', [], 'validators'),
'data-show-on' => '{"formfield_isRequired_1": "checked"}',
],
'required' => false,
]
);
Expand Down Expand Up @@ -479,6 +499,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
case 'number':
case 'text':
case 'url':
case 'tel':
$builder->add(
'properties',
'formfield_placeholder',
Expand Down Expand Up @@ -521,27 +542,6 @@ public function buildForm(FormBuilderInterface $builder, array $options)
]
);
break;
case 'tel':
if (empty($propertiesData['international'])) {
$propertiesData['international'] = false;
}
$builder->add(
'properties',
FormFieldTelType::class,
[
'label' => false,
'data' => $propertiesData,
]
);
$builder->add(
'properties',
'formfield_placeholder',
[
'label' => false,
'data' => $propertiesData,
]
);
break;
}
}

Expand Down
35 changes: 34 additions & 1 deletion app/bundles/FormBundle/Form/Type/FormFieldTelType.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,57 @@

namespace Mautic\FormBundle\Form\Type;

use Mautic\CoreBundle\Form\Type\YesNoButtonGroupType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Translation\TranslatorInterface;

/**
* Class FormFieldTextType.
*/
class FormFieldTelType extends AbstractType
{
/**
* @var TranslatorInterface
*/
private $translator;

/**
* FormFieldTelType constructor.
*
* @param TranslatorInterface $translator
*/
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}

/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'international',
'yesno_button_group',
YesNoButtonGroupType::class,
[
'label' => 'mautic.form.field.type.tel.international',
'data' => isset($options['data']['international']) ? $options['data']['international'] : false,
]
);

$builder->add(
'international_validationmsg',
TextType::class,
[
'label' => 'mautic.form.field.form.validationmsg',
'label_attr' => ['class' => 'control-label'],
'attr' => [
'class' => 'form-control',
'tooltip' => $this->translator->trans('mautic.core.form.default').': '.$this->translator->trans('mautic.form.submission.phone.invalid', [], 'validators'),
'data-show-on' => '{"formfield_validation_international_1": "checked"}',
],
]
);
}
Expand Down
9 changes: 9 additions & 0 deletions app/bundles/FormBundle/FormEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ final class FormEvents
*/
const FORM_ON_BUILD = 'mautic.form_on_build';

/**
* The mautic.on_form_validate event is dispatched when a form is validated.
*
* The event listener receives a Mautic\FormBundle\Event\ValidationEvent instance.
*
* @var string
*/
const ON_FORM_VALIDATE = 'mautic.on_form_validate';

/**
* The mautic.form_on_submit event is dispatched when a new submission is fired.
*
Expand Down
3 changes: 0 additions & 3 deletions app/bundles/FormBundle/Helper/FormFieldHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ public function validateFieldValue($type, $value, $f = null)
continue;
}

if ($f !== null && $f->getType() === 'tel' && empty($f->getProperties()['international'])) {
continue;
}
if ($type == 'captcha') {
$captcha = $f->getProperties()['captcha'];
if (empty($captcha) && Blank::class !== $constraint) {
Expand Down
2 changes: 1 addition & 1 deletion app/bundles/FormBundle/Translations/en_US/messages.ini
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ mautic.form.field.type.pagebreak="Page break"
mautic.form.field.type.radiogrp="Radio group"
mautic.form.field.type.textarea="Textarea"
mautic.form.field.type.file="File"
mautic.form.field.type.tel.international="Validate as internationally-standardized format"
mautic.form.field.type.tel.international="Validate as international format"
mautic.form.field.file.public="Public accessible link to download"
mautic.form.field.file.allowed_extensions="Allowed file extensions"
mautic.form.field.file.allowed_size="Maximum size (MB)"
Expand Down
Loading