Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assert\Regex and TypeGuessing

I have following entity field:

/**    
* @Assert\Regex(
*   pattern = "/^d+\.(jpg|png|gif)$/",
*   htmlPattern = "/^d+\.(jpg|png|gif)$/"
* )
**/

protected $src;

The form is created by something like this:

$builder
   ->add('src', TextareaType::class, array( //neither is TextType::class working
      'attr' => array('class' => 'mysrc'),
)); //pattern will not be rendered

The problem is, as soon as I provide the field type class TextareaType::class the regex pattern isn't rendered as constraint to the form. Or in other words: The regex pattern is only rendered, if the field type is guessed:

$builder
   ->add('src', null, array(    
      'attr' => array('class' => 'mysrc'),
)); //pattern will be rendered

Any workaround? I want to have the regex patterns in one place, i.e. in my entity, not in a controller or a form.

like image 542
musicman Avatar asked Nov 23 '25 21:11

musicman


2 Answers

Yepp, this is how it should work. Not only the field type is guessed, but some options too and if the type is not guessed the options neither.

BTW the textarea element does not support the pattern attribute, but if you want to you can add one: 'attr' => array('pattern' => '/jsregex/'), you should use a different pattern for the client side than the server side anyway. If you want to give the pattern in one place use a constant.

like image 150
1ed Avatar answered Nov 26 '25 14:11

1ed


Maybe this one could help you:

FormType

use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Validator\Constraints\Regex;
use YourBundle\Entity\YourEntity;

public function __construct(ValidatorInterface $validator)
{
    $this->validator = $validator;
}

public function getRegexPattern($property)
{
    $pattern = null;
    $metadata = $this->validator->getMetadataFor(new YourEntity());
    $propertyMetadata = $metadata->getPropertyMetadata($property);
    $constraints = $propertyMetadata[0]->constraints;

    foreach($constraints as $constraint) {
        if ($constraint instanceof Regex) {
            $pattern = $constraint->pattern;
        }
    }

    return $pattern;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('src', TextType::class, array(
        'attr' => array(
            'class' => 'mysrc',
            'pattern' => $this->getRegexPattern('src')
        ),
    )); 
}

services.yml (Needed to inject validator in type)

services:
    app.form.type.your_entity_type:
        class: YourBundle\Form\YourEntityType
        arguments:
            validator: "@validator"
        tags:
            - { name: form.type }

Rendered

<input type="text" pattern="/^d+\.(jpg|png|gif)$/" class="src"/>

Like this, even if the TextType in manually set, you get the html validation through pattern retrieved from the constraints of the property.

like image 42
chalasr Avatar answered Nov 26 '25 14:11

chalasr