13

In the FOUserBundle, I would like to be able to change the validation settings for minimum length, maximum length and not blank on fields such as username and password.

I was able to put some validation via @Assert on my custom fields, but now I am wondering how I could change the username validation for the FOSUserBundle?

These fields are generated automatically, so I can't add them to my User entity... and by default, it allows characters like {^| etc... which don't look good.

Jon Winstanley
  • 23,010
  • 22
  • 73
  • 116
mwinter
  • 596
  • 2
  • 5
  • 14

3 Answers3

16

You can overwrite the default settings by creating a new validation file in your bundle. This is bundle inheritance. Just copy (not cut).

FOSUserBundle/Resources/config/validation/orm.xml to YourBundle/Resources/config/validation/orm.xml.

(couchdb.xml, mongodb.xml, propel.xml respectively)

and adjust it to your needs. Change the class name, then add your constraints:

<class name="Vendor\YourBundle\Model\User">

    <property name="username">
        <!-- minimum length for username -->
        <constraint name="MinLength">
            <option name="limit">3</option>
            <option name="message">Your name must have at least {{ limit }} characters.</option>
        </constraint>
        <!-- custom constraint -->
        <constraint name="Acme\DemoBundle\Validator\Constraints\ContainsAlphanumeric" />
    </property>

    <constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
        <option name="fields">usernameCanonical</option>
        <option name="errorPath">username</option>
        <option name="message">fos_user.username.already_used</option>
        <option name="groups">
            <value>Registration</value>
            <value>Profile</value>
        </option>
    </constraint>

    <constraint name="Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity">
        <option name="fields">emailCanonical</option>
        <option name="errorPath">email</option>
        <option name="message">fos_user.email.already_used</option>
        <option name="groups">
            <value>Registration</value>
            <value>Profile</value>
        </option>
    </constraint>
</class>

Read more about which constraints are available (and how to use them with xml configuration ) in the Validation Constraints Reference.

Gottlieb Notschnabel
  • 9,408
  • 18
  • 74
  • 116
Nicolai Fröhlich
  • 51,330
  • 11
  • 126
  • 130
  • Alright, thanks alot! I didn't even have to add the orm.xml file, after properly reading the Validation Constrains Reference, I found out I could just add a validation.yml to my UserBundle's config, and add it there :D – mwinter May 23 '13 at 12:32
  • Thats the second possible solution but in general you will be quicker using the xml file from FOSUserBundle with copy&paste as it already provides a skeleten :) – Nicolai Fröhlich May 23 '13 at 15:24
  • 1
    @M. Winterinho could you please add your solution as well? – Tzook Bar Noy Oct 03 '13 at 06:14
  • @nifr +1 Man of the year – mate64 Mar 22 '14 at 18:47
  • 2
    this doesn't seems to work, as field validation is defined in different file: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/config/validation.xml and if i try to overwrite this file, validations are duplicated rather than overwritten – gondo Dec 17 '14 at 16:44
  • @gondo - I was referring to `Resources/config/validation/orm.yml` here. You're talking about `/Resources/config/validation.yml`? Furthermore ensure that your bundle extends FOSUserBundle. – Nicolai Fröhlich Dec 18 '14 at 12:58
  • 1
    @nifr yes, as mentioned im talking abuot https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/config/validation.xml as this is the file where the properties validations are defined. the file you are mentioning, https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/config/validation/orm.xml is used for entity validation not for its property validations so technically in your proposed solution you are mixing these two incorrectly – gondo Dec 18 '14 at 15:38
6

The easiest thing for me was to overwrite the property in my custom entity and change the settings for the assertion:

<?php
namespace YourBundle\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class User extends \FOS\UserBundle\Model\User
{
    // ...

    /**
    * @Assert\Length(
    *     min=8,
    *     max=4096,
    *     minMessage="user.password.short",
    *     groups={"Profile", "ResetPassword", "Registration", "ChangePassword"}
    * )
    */
    protected $plainPassword;

    // ...
}

Don't forget the validation groups.

Heads up: user.password.short translation is in the validators Domain of your bundle in YourBundle\Resources\translations\.

Example:

# validators.en.yml
user:
    password:
        short: Password must be at least 8 characters long.

Don't know if this is version specific; I'm using symfony v2.8.3 and fosuser ~2.0@dev (a39d000).

gblock
  • 495
  • 3
  • 13
3

In YML you would do it like this:

# src/Acme/ProjectBundle/Resources/config/validation.yml
Acme\ProjectBundle\Entity\User:
    properties:
        email:
            - Length:
                min: 5
                minMessage: "Your email must have at least {{ limit }} characters."
                max: 255
                maxMessage: "Your email is too long."
            - NotBlank:
                message: "Please enter an email"
        username:
            - Length:
                min: 6
                minMessage: "Your username must have at least {{ limit }} characters."
                max: 255
                maxMessage: "Your username is too long."
            - NotBlank:
                message: "Please enter an username"
        plainPassword:
            - Length:
                min: 8
                minMessage: "Your password must have at least {{ limit }} characters."
                max: 255
                maxMessage: "Your password is too long."
            - NotBlank:
                message: "Please enter a password"

Acme\ProjectBundle\Form\Model\ChangePassword:
    properties:
        new:
            - Length:
                min: 8
                minMessage: "Your password must have at least {{ limit }} characters."
                max: 255
                maxMessage: "Your password is too long."
            - NotBlank:
                message: "Please enter a password"

Acme\ProjectBundle\Form\Model\ResetPassword:
    properties:
        new:
            - Length:
                min: 8
                minMessage: "Your password must have at least {{ limit }} characters."
                max: 255
                maxMessage: "Your password is too long."
            - NotBlank:
                message: "Please enter a password"
Jon Winstanley
  • 23,010
  • 22
  • 73
  • 116