4

I'm building an application on Symfony 3.2

On one part of the application I'm providing an interface my users to change their passwords. For this task, I have a simple form which bound to my ChangePasword entity as follows.

Form class:

namespace MasterBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ChangePasswordType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('oldPassword', PasswordType::class)
            ->add('newPassword', PasswordType::class);
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(
            array(
                'data_class' => 'MasterBundle\Entity\ChangePassword'
            )
        );
    }

    public function getBlockPrefix()
    {
        return 'change_password';
    }
} 

And the model:

<?php

namespace MasterBundle\Entity;

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;

class ChangePassword
{

    /**
     * @UserPassword(message="Your current password is not correct.")
     */
    private $oldPassword;

    /**
     * @Assert\NotBlank(message="New password can not be blank.")
     * @Assert\Regex(pattern="/^(?=.*[a-z])(?=.*\\d).{6,}$/i", message="New password is required to be minimum 6 chars in length and to include at least one letter and one number.")
     */
    private $newPassword;

// other setter and getter stuff.
}

Now, the problem is the regex validator doesn't work. It doesnt match with anything.

However, if I modify the model as below; it works flawlessly:

<?php

namespace MasterBundle\Entity;

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
use Symfony\Component\Validator\Mapping\ClassMetadata;

class ChangePassword
{

    private $oldPassword;

    private $newPassword;

public static function loadValidatorMetadata(ClassMetadata $metadata)
{
    $metadata->addPropertyConstraint('oldPassword', new Userpassword(array(
        'message' => 'Your current password is not correct.',
    )));

    $metadata->addPropertyConstraint('newPassword', new Assert\NotBlank(array(
        'message' => 'New password can not be blank.',
    )));

    $metadata->addPropertyConstraint('newPassword', new Assert\Regex(array(
        'pattern' => '/^(?=.*[a-z])(?=.*\\d).{6,}$/i',
        'message' => 'New password is required to be minimum 6 chars in length and to include at least one letter and one number.'
    )));
}

// other setter and getter stuff.
}

Do you have any idea about the root of this problem? Any idea about further debugging the case, would be appreciated.

Lashae
  • 1,372
  • 1
  • 20
  • 36
  • check the `config.yml` files and verify you have the line `validation: { enable_annotations: true }` under the framework key. – Matteo May 23 '17 at 07:53
  • 1
    @Matteo Yes it is enabled, moreover `Assert\NotBlank` annotation works as expected ;-) – Lashae May 23 '17 at 13:12

1 Answers1

2

It seems that for this specific regular expression, the one in the annotation should not escape \d bit, however in the PHP implementation (ie using loadValidatorMetadata) we need to escape it.

If I edit the model which implemented the constraint in annotation as follows, it works:

/**
 * @Assert\NotBlank(message="New password can not be blank.")
 * @Assert\Regex(pattern="/^(?=.*[a-z])(?=.*\d).{6,}$/i", message="New password is required to be minimum 6 chars in length and to include at least one letter and one number.")
 */
private $newPassword;

Just edit /^(?=.*[a-z])(?=.*\\d).{6,}$/i to /^(?=.*[a-z])(?=.*\d).{6,}$/i

This seems to inconsistent. I think the annotation, yaml, xml and PHP implementations need to be identical whereas possible, the documentation should emphasize all of the inconsistencies.

Therefore I raised an issue on Symfony repo.

Lashae
  • 1,372
  • 1
  • 20
  • 36