diff --git a/guides/validation.rst b/guides/validation.rst deleted file mode 100644 index 72689fbe5c9..00000000000 --- a/guides/validation.rst +++ /dev/null @@ -1,498 +0,0 @@ -.. index:: - single: Forms; Validators - single: Validators - -Validation -========== - -The Basics ----------- - -The Symfony2 Validator component is based on the `JSR303 Bean Validation -specification`_. What? A Java specification in PHP? You heard right, but it's -not as bad as it sounds. Let's look at how we use it in PHP. - -The Validator is designed to validate objects against different constraints. -These constraints can be put on the class itself, on properties and on methods -prefixed with "get" or "is". Let's look at a sample configuration:: - - class Author - { - /** - * @validation:NotBlank - * @validation:MinLength(4) - */ - public $firstName; - - /** - * @validation:Email(message="Ok, seriously now. Your email address please") - */ - public function getEmail() - { - return 'foobar'; - } - } - -This snippet shows a very simple ``Author`` class with a property and a getter. -Each constraint has a name, most of them also have a couple of options. Here we -configured the constraints with annotations, but Symfony2 also offers many -other configuration drivers. - -Because the annotation driver depends on the Doctrine library, it is not -enabled by default. You can enable it in your ``config.yml``: - -.. code-block:: yaml - - # hello/config/config.yml - app.config: - validation: - enabled: true - annotations: true - -Now let's try to validate an object:: - - $author = new Author(); - $author->firstName = 'B.'; - - print $this['validator']->validate($author); - -You should see the following output: - -.. code-block:: yaml - - Author.firstName: - This value is too short. It should have 4 characters or more - Author.email: - Ok, seriously now. Your email address please - -The ``validate()`` method returns a ``ConstraintViolationList`` object that can -simply be printed or processed in your code. That was easy! - -.. index:: - single: Validators; Constraints - -The Constraints ---------------- - -Symfony2 bundles many different constraints. The following list will show you -which ones are available and how you can use and configure them. Some -constraints have a default option. If you only set this option, you can leave -away the option name:: - - /** @validation:Min(limit=3) */ - -is identical to:: - - /** @validation:Min(3) */ - -AssertFalse -~~~~~~~~~~~ - -Validates that a value is ``false``. Very useful for testing return values of -methods:: - - /** @validation:AssertFalse */ - public function isInjured(); - -Options: - -* ``message``: The error message if validation fails - -AssertTrue -~~~~~~~~~~ - -Works like ``AssertFalse``. - -NotBlank -~~~~~~~~ - -Validates that a value is not empty:: - - /** @validation:NotBlank */ - private $firstName; - -Options: - -* ``message``: The error message if validation fails - -Blank -~~~~~ - -Works like ``NotBlank``. - -NotNull -~~~~~~~ - -Validates that a value is not ``NULL``:: - - /** @validation:NotNull */ - private $firstName; - -Options: - -* ``message``: The error message if validation fails - -Null -~~~~ - -Works like ``NotNull``. - -AssertType -~~~~~~~~~~ - -Validates that a value has a specific data type:: - - /** @validation:AssertType("integer") */ - private $age; - -Options: - -* ``type`` (default): The type -* ``message``: The error message if validation fails - -Choice -~~~~~~ - -Validates that a value is one or more of a list of choices:: - - /** @validation:Choice({"male", "female"}) */ - private $gender; - -Options: - -* ``choices`` (default): The available choices -* ``callback``: Can be used instead of ``choices``. A static callback method - returning the choices. If you set this to a string, the method is expected - to be in the validated class. -* ``multiple``: Whether multiple choices are allowed. Default: ``false`` -* ``min``: The minimum amount of selected choices -* ``max``: The maximum amount of selected choices -* ``message``: The error message if validation fails -* ``minMessage``: The error message if ``min`` validation fails -* ``maxMessage``: The error message if ``max`` validation fails - -Valid -~~~~~ - -Validates that an object is valid. Can be put on properties or getters to -validate related objects:: - - /** @validation:Valid */ - private $address; - -Options: - -* ``class``: The expected class of the object (optional) -* ``message``: The error message if the class doesn't match - -Collection -~~~~~~~~~~ - -Validates array entries against different constraints:: - - /** - * @validation:Collection( - * fields = { - * "firstName" = @validation:NotNull, - * "lastName" = { @validation:NotBlank, @validation:MinLength(4) } - * }, - * allowMissingFields = true - * ) - */ - private $options = array(); - -Options: - -* ``fields`` (default): An associative array of array keys and one or more - constraints -* ``allowMissingFields``: Whether some of the keys may not be present in the - array. Default: ``false`` -* ``allowExtraFields``: Whether the array may contain keys not present in the - ``fields`` option. Default: ``false`` -* ``missingFieldsMessage``: The error message if the ``allowMissingFields`` - validation fails -* ``extraFieldsMessage``: The error message if the ``allowExtraFields`` - validation fails - -Date -~~~~ - -Validates that a value is a valid date string with format ``YYYY-MM-DD``:: - - /** @validation:Date */ - private $birthday; - -Options: - -* ``message``: The error message if the validation fails - -DateTime -~~~~~~~~ - -Validates that a value is a valid datetime string with format ``YYYY-MM-DD -HH:MM:SS``:: - - /** @validation:DateTime */ - private $createdAt; - -Options: - -* ``message``: The error message if the validation fails - -Time -~~~~ - -Validates that a value is a valid time string with format ``HH:MM:SS``:: - - /** @validation:Time */ - private $start; - -Options: - -* ``message``: The error message if the validation fails - -Email -~~~~~ - -Validates that a value is a valid email address:: - - /** @validation:Email */ - private $email; - -Options: - -* ``message``: The error message if the validation fails -* ``checkMX``: Whether MX records should be checked for the domain. Default: - ``false`` - -File -~~~~ - -Validates that a value is an existing file:: - - /** @validation:File(maxSize="64k") */ - private $filename; - -Options: - -* ``maxSize``: The maximum allowed file size. Can be provided in bytes, - kilobytes (with the suffix "k") or megabytes (with the suffix "M") -* ``mimeTypes``: One or more allowed mime types -* ``notFoundMessage``: The error message if the file was not found -* ``notReadableMessage``: The error message if the file could not be read -* ``maxSizeMessage``: The error message if ``maxSize`` validation fails -* ``mimeTypesMessage``: The error message if ``mimeTypes`` validation fails - -Max -~~~ - -Validates that a value is at most the given limit:: - - /** @validation:Max(99) */ - private $age; - -Options: - -* ``limit`` (default): The limit -* ``message``: The error message if validation fails - -Min -~~~ - -Works like ``Max``. - -MaxLength -~~~~~~~~~ - -Validates that the string length of a value is at most the given limit:: - - /** @validation:MaxLength(32) */ - private $hash; - -Options: - -* ``limit`` (default): The size limit -* ``message``: The error message if validation fails - -MinLength -~~~~~~~~~ - -Works like ``MaxLength``. - -Regex -~~~~~ - -Validates that a value matches the given regular expression:: - - /** @validation:Regex("/\w+/") */ - private $title; - -Options: - -* ``pattern`` (default): The regular expression pattern -* ``match``: Whether the pattern must be matched or must not be matched. - Default: ``true`` -* ``message``: The error message if validation fails - -Url -~~~ - -Validates that a value is a valid URL:: - - /** @validation:Url */ - private $website; - -Options: - -* ``protocols``: A list of allowed protocols. Default: "http", "https", "ftp" - and "ftps". -* ``message``: The error message if validation fails - -.. index:: - single: Validators; Configuration - -Custom Constraints ------------------- - -You can create a custom constraint by extending the base constraint class, -``Symfony\Component\Validator\Constraint``. Options for your constraint are -represented by public properties on the constraint class. For example, the -``Url`` constraint includes ``message`` and ``protocols`` properties:: - - namespace Symfony\Component\Validator\Constraints; - - class Url extends \Symfony\Component\Validator\Constraint - { - public $message = 'This value is not a valid URL'; - public $protocols = array('http', 'https', 'ftp', 'ftps'); - } - -As you can see, a constraint class is fairly minimal. The actual validation is -performed by a another "constraint validator" class. Which constraint -validator is specified by the constraint's ``validatedBy()`` method, which -includes some simple default logic:: - - // in the base Symfony\Component\Validator\Constraint class - public function validatedBy() - { - return get_class($this).'Validator'; - } - -Constraint Validators with Dependencies -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If your constraint validator has dependencies, such as a database connection, -it will need to be configured as a service in the dependency injection -container. This service must include the `validator.constraint_validator` tag -and an `alias` attribute: - -.. configuration-block:: - - .. code-block:: yaml - - services: - validator.unique.your_validator_name: - class: Fully\Qualified\Validator\Class\Name - tags: - - { name: validator.constraint_validator, alias: alias_name } - - .. code-block:: xml - - - - - - - .. code-block:: php - - $container - ->register('validator.unique.your_validator_name', 'Fully\Qualified\Validator\Class\Name') - ->addTag('validator.constraint_validator', array('alias' => 'alias_name')) - ; - -Your constraint class may now use this alias to reference the appropriate -validator:: - - public function validatedBy() - { - return 'alias_name'; - } - -Other Configuration Drivers ---------------------------- - -As always in Symfony2, there are multiple ways of configuring the constraints -for your classes. Symfony2 supports the following four drivers. - -XML Configuration -~~~~~~~~~~~~~~~~~ - -The XML driver is a little verbose, but has the benefit that the XML file can -be validated to prevent errors. To use the driver, simply put a file called -``validation.xml`` in the ``Resources/config/`` directory of your bundle: - -.. code-block:: xml - - - - - - - - 4 - - - - - - - - - -YAML Configuration -~~~~~~~~~~~~~~~~~~ - -The YAML driver offers the same functionality as the XML driver. To use it, put -the file ``validation.yml`` in the ``Resources/config/`` directory of your -bundle: - -.. code-block:: yaml - - Application\HelloBundle\Model\Author: - properties: - firstName: - - NotBlank: ~ - - MinLength: 4 - - getters: - email: - - Email: { message: "Ok, seriously now. Your email address please" } - -PHP Configuration -~~~~~~~~~~~~~~~~~ - -If you prefer to write configurations in plain old PHP, you can add the static -method ``loadValidatorMetadata()`` to the classes that you want to validate:: - - use Symfony\Component\Validator\Constraints; - use Symfony\Component\Validator\Mapping\ClassMetadata; - - class Author - { - public static function loadValidatorMetadata(ClassMetadata $metadata) - { - $metadata->addPropertyConstraint('firstName', new Constraints\NotBlank()); - $metadata->addPropertyConstraint('firstName', new Constraints\MinLength(3)); - $metadata->addGetterConstraint('email', new Constraints\Email(array( - 'message' => 'Ok, seriously now. Your email address please', - ))); - } - } - -You can use either of the configuration drivers, or all together. Symfony2 will -merge all the information it can find. - -.. _JSR303 Bean Validation specification: http://jcp.org/en/jsr/detail?id=303 diff --git a/guides/validator/constraints.markdown b/guides/validator/constraints.markdown new file mode 100644 index 00000000000..bfc98e3e118 --- /dev/null +++ b/guides/validator/constraints.markdown @@ -0,0 +1,218 @@ +Constraints +=========== + +The Validator is designed to validate objects against *constraints*. +In real life, a constraint could be: "The cake must not be burned". In +Symfony2, constraints are similar: They are assertions that a condition is +true. + +Supported Constraints +--------------------- + +The following constraints are natively available in Symfony2: + +* `AssertFalse `_ +* `AssertTrue `_ +* `AssertType `_ +* `Choice `_ +* `Collection `_ +* `Date `_ +* `DateTime `_ +* `Email `_ +* `File `_ +* `Max `_ +* `MaxLength `_ +* `Min `_ +* `MinLength `_ +* `NotBlank `_ +* `NotNull `_ +* `Regex `_ +* `Time `_ +* `Url `_ +* `Valid `_ + +Constraint Targets +------------------ + +Constraints can be put on properties of a class, on public getters and on the +class itself. The benefit of class constraints is that they can validate +the whole state of an object at once, with all of its properties and methods. + +Properties +~~~~~~~~~~ + +Validating class properties is the most basic validation technique. Symfony2 +allows you to validate private, protected or public properties. The next listing +shows how to configure the properties ``$firstName`` and ``$lastName`` of a class +``Author`` to have at least 3 characters. + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Author: + properties: + firstName: + - NotBlank: ~ + - MinLength: 3 + lastName: + - NotBlank: ~ + - MinLength: 3 + + .. code-block:: xml + + + + + + 3 + + + + 3 + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:NotBlank() + * @validation:MinLength(3) + */ + private $firstName; + + /** + * @validation:NotBlank() + * @validation:MinLength(3) + */ + private $firstName; + } + +Getters +~~~~~~~ + +The next validation technique is to constrain the return value of a method. +Symfony2 allows you to constrain any public method whose name starts with +"get" or "is". In this guide, this is commonly referred to as "getter". + +The benefit of this technique is that it allows you to validate your object +dynamically. Depending on the state of your object, the method may return +different values which are then validated. + +The next listing shows you how to use the `AssertTrue `_ +constraint to validate whether a dynamically generated token is correct. + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Author: + getters: + tokenValid: + - AssertTrue: { message: "The token is invalid" } + + .. code-block:: xml + + + + + + + + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:AssertTrue(message = "The token is invalid") + */ + public function isTokenValid() + { + // return true or false + } + } + +.. note:: + + The keen-eyed among you will have noticed that the prefix of the getter + ("get" or "is") is omitted in the mapping. This allows you to move the + constraint to a property with the same name later (or vice versa) without + changing your validation logic. + +Custom Constraints +------------------ + +You can create a custom constraint by extending the base constraint class, +:class::`Symfony\Component\Validator\Constraint`::. Options for your constraint are +represented by public properties on the constraint class. For example, the +``Url`` constraint includes ``message`` and ``protocols`` properties:: + + namespace Symfony\Component\Validator\Constraints; + + class Url extends \Symfony\Component\Validator\Constraint + { + public $message = 'This value is not a valid URL'; + public $protocols = array('http', 'https', 'ftp', 'ftps'); + } + +As you can see, a constraint class is fairly minimal. The actual validation is +performed by a another "constraint validator" class. Which constraint +validator is specified by the constraint's ``validatedBy()`` method, which +includes some simple default logic:: + + // in the base Symfony\Component\Validator\Constraint class + public function validatedBy() + { + return get_class($this).'Validator'; + } + +Constraint Validators with Dependencies +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your constraint validator has dependencies, such as a database connection, +it will need to be configured as a service in the dependency injection +container. This service must include the ``validator.constraint_validator`` tag +and an ``alias`` attribute: + +.. configuration-block:: + + .. code-block:: yaml + + services: + validator.unique.your_validator_name: + class: Fully\Qualified\Validator\Class\Name + tags: + - { name: validator.constraint_validator, alias: alias_name } + + .. code-block:: xml + + + + + + + .. code-block:: php + + $container + ->register('validator.unique.your_validator_name', 'Fully\Qualified\Validator\Class\Name') + ->addTag('validator.constraint_validator', array('alias' => 'alias_name')) + ; + +Your constraint class may now use this alias to reference the appropriate +validator: + +.. code-block:: php + + public function validatedBy() + { + return 'alias_name'; + } \ No newline at end of file diff --git a/guides/validator/constraints/AssertFalse.rst b/guides/validator/constraints/AssertFalse.rst new file mode 100644 index 00000000000..e91c64de5cf --- /dev/null +++ b/guides/validator/constraints/AssertFalse.rst @@ -0,0 +1,18 @@ +AssertTrue +========== + +Validates that a value is ``false``. + +.. code-block:: yaml + + properties: + deleted: + - AssertFalse: ~ + +Options +------- + +* ``message``: The error message if validation fails + + +See `AssertTrue `_. \ No newline at end of file diff --git a/guides/validator/constraints/AssertTrue.rst b/guides/validator/constraints/AssertTrue.rst new file mode 100644 index 00000000000..3c05b7f0a25 --- /dev/null +++ b/guides/validator/constraints/AssertTrue.rst @@ -0,0 +1,83 @@ +AssertTrue +========== + +Validates that a value is ``true``. + +.. code-block:: yaml + + properties: + termsAccepted: + - AssertTrue: ~ + +Options +------- + +* ``message``: The error message if validation fails + + +Example +------- + +This constraint is very useful to execute custom validation logic. You can +put the logic in a method which returns either ``true`` or ``false``. + +.. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + protected $token; + + public function isTokenValid() + { + return $this->token == $this->generateToken(); + } + } + +Then you can constrain this method with ``AssertTrue``. + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Author: + getters: + tokenValid: + - AssertTrue: { message: "The token is invalid" } + + .. code-block:: xml + + + + + + + + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + namespace Application\HelloBundle; + + class Author + { + protected $token; + + /** + * @validation:AssertTrue(message = "The token is invalid") + */ + public function isTokenValid() + { + return $this->token == $this->generateToken(); + } + } + +If the validation of this method fails, you will see a message similar to this: + +:: + + Application\HelloBundle\Author.tokenValid: + This value should not be null diff --git a/guides/validator/constraints/AssertType.rst b/guides/validator/constraints/AssertType.rst new file mode 100644 index 00000000000..0996805ffbb --- /dev/null +++ b/guides/validator/constraints/AssertType.rst @@ -0,0 +1,34 @@ +AssertType +========== + +Validates that a value has a specific data type + +.. code-block:: yaml + + properties: + age: + - AssertType: integer + +Options +------- + +* ``type`` (**default**, required): A fully qualified class name or one of the + PHP datatypes as determined by PHP's ``is_`` functions. + + * `array `_ + * `bool `_ + * `callable `_ + * `float `_ + * `double `_ + * `int `_ + * `integer `_ + * `long `_ + * `null `_ + * `numeric `_ + * `object `_ + * `real `_ + * `resource `_ + * `scalar `_ + * `string `_ + +* ``message``: The error message in case the validation fails diff --git a/guides/validator/constraints/Choice.rst b/guides/validator/constraints/Choice.rst new file mode 100644 index 00000000000..c462d3375c0 --- /dev/null +++ b/guides/validator/constraints/Choice.rst @@ -0,0 +1,154 @@ +Choice +====== + +Validates that a value is one or more of a list of choices. + +.. code-block:: yaml + + properties: + gender: + - Choice: [male, female] + +Options +------- + +* ``choices`` (**default**, required): The available choices +* ``callback``: Can be used instead of ``choices``. A static callback method + returning the choices. If you pass a string, it is expected to be + the name of a static method in the validated class. +* ``multiple``: Whether multiple choices are allowed. Default: ``false`` +* ``min``: The minimum amount of selected choices +* ``max``: The maximum amount of selected choices +* ``message``: The error message if validation fails +* ``minMessage``: The error message if ``min`` validation fails +* ``maxMessage``: The error message if ``max`` validation fails + +Example 1: Choices as static array +---------------------------------- + +If the choices are few and easy to determine, they can be passed to the +constraint definition as array. + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Author: + properties: + gender: + - Choice: [male, female] + + .. code-block:: xml + + + + + + male + female + + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:Choice({"male", "female"}) + */ + protected $gender; + } + +Example 2: Choices from a callback +---------------------------------- + +When you also need the choices in other contexts (such as a drop-down box in +a form), it is more flexible to bind them to your domain model using a static +callback method. + +.. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + public static function getGenders() + { + return array('male', 'female'); + } + } + +You can pass the name of this method to the ``callback`` option of the ``Choice`` +constraint. + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Author: + properties: + gender: + - Choice: { callback: getGenders } + + .. code-block:: xml + + + + + + + + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:Choice(callback = "getGenders") + */ + protected $gender; + } + +If the static callback is stored in a different class, for example ``Util``, +you can pass the class name and the method as array. + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Author: + properties: + gender: + - Choice: { callback: [Util, getGenders] } + + .. code-block:: xml + + + + + + + + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:Choice(callback = {"Util", "getGenders"}) + */ + protected $gender; + } diff --git a/guides/validator/constraints/Collection.rst b/guides/validator/constraints/Collection.rst new file mode 100644 index 00000000000..6e0a8477e3f --- /dev/null +++ b/guides/validator/constraints/Collection.rst @@ -0,0 +1,109 @@ +Collection +========== + +Validates array entries against different constraints. + +.. code-block:: yaml + + - Collection: + fields: + key1: + - NotNull: ~ + key2: + - MinLength: 10 + +Options +------- + +* ``fields`` (required): An associative array of array keys and one or more + constraints +* ``allowMissingFields``: Whether some of the keys may not be present in the + array. Default: ``false`` +* ``allowExtraFields``: Whether the array may contain keys not present in the + ``fields`` option. Default: ``false`` +* ``missingFieldsMessage``: The error message if the ``allowMissingFields`` + validation fails +* ``allowExtraFields``: The error message if the ``allowExtraFields`` validation + fails + +Example: +-------- + +Let's validate an array with two indexes ``firstName`` and ``lastName``. The +value of ``firstName`` must not be blank, while the value of ``lastName`` must +not be blank with a minimum length of four characters. Furthermore, both keys +may not exist in the array. + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Author: + properties: + options: + - Collection: + fields: + firstName: + - NotBlank: ~ + lastName: + - NotBlank: ~ + - MinLength: 4 + allowMissingFields: true + + .. code-block:: xml + + + + + + + + + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:Collection( + * fields = { + * "firstName" = @validation:NotNull, + * "lastName" = { @validation:NotBlank, @validation:MinLength(4) } + * }, + * allowMissingFields = true + * ) + */ + private $options = array(); + } + +The following object would fail the validation. + +.. code-block:: php + + $author = new Author(); + $author->options['firstName'] = null; + $author->options['lastName'] = 'foo'; + + print $validator->validate($author); + +You should see the following error messages: + +:: + + Application\HelloBundle\Author.options[firstName]: + This value should not be null + Application\HelloBundle\Author.options[lastName]: + This value is too short. It should have 4 characters or more + diff --git a/guides/validator/constraints/Date.rst b/guides/validator/constraints/Date.rst new file mode 100644 index 00000000000..748e408dd97 --- /dev/null +++ b/guides/validator/constraints/Date.rst @@ -0,0 +1,15 @@ +Date +==== + +Validates that a value is a valid date string with format "YYYY-MM-DD". + +.. code-block:: yaml + + properties: + birthday: + - Date: ~ + +Options +------- + +* ``message``: The error message if the validation fails \ No newline at end of file diff --git a/guides/validator/constraints/DateTime.rst b/guides/validator/constraints/DateTime.rst new file mode 100644 index 00000000000..47d814010d0 --- /dev/null +++ b/guides/validator/constraints/DateTime.rst @@ -0,0 +1,15 @@ +DateTime +======== + +Validates that a value is a valid datetime string with format "YYYY-MM-DD HH:MM:SS". + +.. code-block:: yaml + + properties: + createdAt: + - DateTime: ~ + +Options +------- + +* ``message``: The error message if the validation fails \ No newline at end of file diff --git a/guides/validator/constraints/Email.rst b/guides/validator/constraints/Email.rst new file mode 100644 index 00000000000..6283099f246 --- /dev/null +++ b/guides/validator/constraints/Email.rst @@ -0,0 +1,16 @@ +Email +===== + +Validates that a value is a valid email address. + +.. code-block:: yaml + + properties: + email: + - Email: ~ + +Options +------- + +* ``checkMX``: Whether MX records should be checked for the domain. Default: ``false`` +* ``message``: The error message if the validation fails \ No newline at end of file diff --git a/guides/validator/constraints/File.rst b/guides/validator/constraints/File.rst new file mode 100644 index 00000000000..273a72f5044 --- /dev/null +++ b/guides/validator/constraints/File.rst @@ -0,0 +1,73 @@ +File +==== + +Validates that a value is the path to an existing file. + +.. code-block:: yaml + + properties: + filename: + - File: ~ + +Options +------- + +* ``maxSize``: The maximum allowed file size. Can be provided in bytes, kilobytes + (with the suffix "k") or megabytes (with the suffix "M") +* ``mimeTypes``: One or more allowed mime types +* ``notFoundMessage``: The error message if the file was not found +* ``notReadableMessage``: The error message if the file could not be read +* ``maxSizeMessage``: The error message if ``maxSize`` validation fails +* ``mimeTypesMessage``: The error message if ``mimeTypes`` validation fails + +Example: Validating the file size and mime type +----------------------------------------------- + +In this example we use the ``File`` constraint to verify that the file does +not exceed a maximum size of 128 kilobytes and is a PDF document. + +.. configuration-block:: + + .. code-block:: yaml + + properties: + filename: + - File: { maxSize: 128k, mimeTypes: [application/pdf, application/x-pdf] } + + .. code-block:: xml + + + + + + + + + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:File(maxSize = "128k", mimeTypes = { + * "application/pdf", + * "application/x-pdf" + * }) + */ + private $filename; + } + +When you validate the object with a file that doesn't satisfy one of these +constraints, a proper error message is returned by the validator. + +:: + + Application\HelloBundle\Author.filename: + The file is too large (150 kB). Allowed maximum size is 128 kB + diff --git a/guides/validator/constraints/Max.rst b/guides/validator/constraints/Max.rst new file mode 100644 index 00000000000..e284ef14121 --- /dev/null +++ b/guides/validator/constraints/Max.rst @@ -0,0 +1,16 @@ +Max +=== + +Validates that a value is not greater than the given limit. + +.. code-block:: yaml + + properties: + age: + - Max: 99 + +Options +------- + +* ``limit`` (**default**, required): The limit +* ``message``: The error message if validation fails \ No newline at end of file diff --git a/guides/validator/constraints/MaxLength.rst b/guides/validator/constraints/MaxLength.rst new file mode 100644 index 00000000000..3b79dc734b4 --- /dev/null +++ b/guides/validator/constraints/MaxLength.rst @@ -0,0 +1,16 @@ +MaxLength +========= + +Validates that the string length of a value is not greater than the given limit. + +.. code-block:: yaml + + properties: + firstName: + - MaxLength: 20 + +Options +------- + +* ``limit`` (**default**, required): The limit +* ``message``: The error message if validation fails \ No newline at end of file diff --git a/guides/validator/constraints/Min.rst b/guides/validator/constraints/Min.rst new file mode 100644 index 00000000000..b2c904eca15 --- /dev/null +++ b/guides/validator/constraints/Min.rst @@ -0,0 +1,16 @@ +Min +=== + +Validates that a value is not smaller than the given limit. + +.. code-block:: yaml + + properties: + age: + - Min: 1 + +Options +------- + +* ``limit`` (**default**, required): The limit +* ``message``: The error message if validation fails \ No newline at end of file diff --git a/guides/validator/constraints/MinLength.rst b/guides/validator/constraints/MinLength.rst new file mode 100644 index 00000000000..e5015e839f6 --- /dev/null +++ b/guides/validator/constraints/MinLength.rst @@ -0,0 +1,16 @@ +MinLength +========= + +Validates that the string length of a value is not smaller than the given limit. + +.. code-block:: yaml + + properties: + firstName: + - MinLength: 3 + +Options +------- + +* ``limit`` (**default**, required): The limit +* ``message``: The error message if validation fails \ No newline at end of file diff --git a/guides/validator/constraints/NotBlank.rst b/guides/validator/constraints/NotBlank.rst new file mode 100644 index 00000000000..0b0b826e4e5 --- /dev/null +++ b/guides/validator/constraints/NotBlank.rst @@ -0,0 +1,16 @@ +NotBlank +======== + +Validates that a value is not empty (as determined by the +`empty `_ construct). + +.. code-block:: yaml + + properties: + firstName: + - NotBlank: ~ + +Options +------- + +* ``message``: The error message if validation fails \ No newline at end of file diff --git a/guides/validator/constraints/NotNull.rst b/guides/validator/constraints/NotNull.rst new file mode 100644 index 00000000000..b5f4e3e04dd --- /dev/null +++ b/guides/validator/constraints/NotNull.rst @@ -0,0 +1,15 @@ +NotNull +======= + +Validates that a value is not ``null``. + +.. code-block:: yaml + + properties: + firstName: + - NotNull: ~ + +Options +------- + + * ``message``: The error message if validation fails diff --git a/guides/validator/constraints/Regex.rst b/guides/validator/constraints/Regex.rst new file mode 100644 index 00000000000..1981b5f7955 --- /dev/null +++ b/guides/validator/constraints/Regex.rst @@ -0,0 +1,18 @@ +Regex +===== + +Validates that a value matches a regular expression. + +.. code-block:: yaml + + properties: + title: + - Regex: /\w+/ + +Options +------- + +* ``pattern`` (**default**, required): The regular expression pattern +* ``match``: Whether the pattern must be matched or must not be matched. + Default: ``true`` +* ``message``: The error message if validation fails \ No newline at end of file diff --git a/guides/validator/constraints/Time.rst b/guides/validator/constraints/Time.rst new file mode 100644 index 00000000000..d9babc193be --- /dev/null +++ b/guides/validator/constraints/Time.rst @@ -0,0 +1,15 @@ +Time +==== + +Validates that a value is a valid time string with format "HH:MM:SS". + +.. code-block:: yaml + + properties: + createdAt: + - DateTime: ~ + +Options +------- + +* ``message``: The error message if the validation fails \ No newline at end of file diff --git a/guides/validator/constraints/Url.rst b/guides/validator/constraints/Url.rst new file mode 100644 index 00000000000..a669024f792 --- /dev/null +++ b/guides/validator/constraints/Url.rst @@ -0,0 +1,17 @@ +Url +=== + +Validates that a value is a valid URL string. + +.. code-block:: yaml + + properties: + website: + - Url: ~ + +Options +------- + +* ``protocols``: A list of allowed protocols. Default: "http", "https", "ftp" + and "ftps". +* ``message``: The error message if validation fails \ No newline at end of file diff --git a/guides/validator/constraints/Valid.rst b/guides/validator/constraints/Valid.rst new file mode 100644 index 00000000000..d63d509a6a7 --- /dev/null +++ b/guides/validator/constraints/Valid.rst @@ -0,0 +1,186 @@ +Valid +===== + +Validates an associated object. + +.. code-block:: yaml + + properties: + address: + - Valid: ~ + +Options +------- + + * ``class``: The expected class of the object + * ``message``: The error message if the class doesn't match + +Example: Validate object graphs +------------------------------- + +This constraint helps to validate whole object graphs. In the following example, +we create two classes ``Author`` and ``Address`` that both have constraints on +their properties. Furthermore, ``Author`` stores an ``Address`` instance in the +``$address`` property. + +.. code-block:: php + + // Application/HelloBundle/Address.php + class Address + { + protected $street; + protected $zipCode; + } + +.. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + protected $firstName; + protected $lastName; + protected $address; + } + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Address: + properties: + street: + - NotBlank: ~ + zipCode: + - NotBlank: ~ + - MaxLength: 5 + + Application\HelloBundle\Author: + properties: + firstName: + - NotBlank: ~ + - MinLength: 4 + lastName: + - NotBlank: ~ + + .. code-block:: xml + + + + + + + + + 5 + + + + + + + 4 + + + + + + + .. code-block:: php + + // Application/HelloBundle/Address.php + class Author + { + /** + * @validation:NotBlank() + */ + protected $street; + + /** + * @validation:NotBlank() + * @validation:MaxLength(5) + */ + protected $zipCode; + } + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:NotBlank() + * @validation:MinLength(4) + */ + protected $firstName; + + /** + * @validation:NotBlank() + */ + protected $lastName; + } + +With this mapping it is possible to successfully validate an author with an +invalid address. To prevent that, we add the ``Valid`` constraint to the +``$address`` property. + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Author: + properties: + address: + - Valid: ~ + + .. code-block:: xml + + + + + + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:Valid() + */ + protected $address; + } + +We can even go one step further and validate the class of the related object +to be ``Address`` or one of its subclasses. + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Author: + properties: + address: + - Valid: { class: Application\ḨelloBundle\Address } + + .. code-block:: xml + + + + + Application\HelloBundle\Address + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:Valid(class = "Application\HelloBundle\Address") + */ + protected $address; + } diff --git a/guides/validator/index.rst b/guides/validator/index.rst new file mode 100644 index 00000000000..ae6fec3107c --- /dev/null +++ b/guides/validator/index.rst @@ -0,0 +1,9 @@ +Symfony2 Validator +================== + +.. toctree:: + :maxdepth: 2 + + overview + view + twig diff --git a/guides/validator/overview.markdown b/guides/validator/overview.markdown new file mode 100644 index 00000000000..46bf83c7755 --- /dev/null +++ b/guides/validator/overview.markdown @@ -0,0 +1,89 @@ +The Validator +============= + +Validation is a very common task in web applications. Data entered in forms +needs to be validated. Data also needs to be validated before it is written +into a database or passed to a web service. + +Symfony2 ships with a new Validator component that makes this task very easy. +This component is based on the +`JSR303 Bean Validation specification `_. +What? A Java specification in PHP? You heard right, but it's not as bad as it +sounds. Let's look at how we use it in PHP. + +The validator validates objects against `constraints `_. Let's start +with the simple constraint that the ``$name`` property of a class ``Author`` must +not be empty. + +.. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + private $name; + } + +The next listing shows a YAML file that connects properties of the class with +constraints. This process is called the "mapping". + +.. configuration-block:: + + .. code-block:: yaml + + # Application/HelloBundle/Resources/config/validation.yml + Application\HelloBundle\Author: + properties: + name: + - NotBlank: ~ + + .. code-block:: xml + + + + + + + + + .. code-block:: php + + // Application/HelloBundle/Author.php + class Author + { + /** + * @validation:NotBlank() + */ + private $name; + } + +Finally, we can use the :class:`Symfony\Component\Validator\Validator`:: class +for `validation `_. Symfony2 provides a validator instance as a +service in the Dependency Injection Container. To use that service, adapt your +application configuration. + +.. code-block:: yaml + + # hello/config/config.yml + app.config: + validation: + enabled: true + +Now call the ``validate()`` method on the service, which delivers a list of +errors if validation fails. + +.. code-block:: php + + $validator = $container->getService('validator'); + $author = new Author(); + + print $validator->validate($author); + +Because the ``$name`` property is empty, you will see the following error +message. + +:: + + Application\HelloBundle\Author.name: + This value should not be blank + +Insert a value into the property and the error message will disappear. diff --git a/guides/validator/validation.markdown b/guides/validator/validation.markdown new file mode 100644 index 00000000000..e18e7fcee52 --- /dev/null +++ b/guides/validator/validation.markdown @@ -0,0 +1,45 @@ +Constraint Validation +===================== + +Objects with constraints are validated by the +:class:`Symfony\Component\Validator\Validator`:: class. If you use +Symfony2, this class is already registered as a service in the Dependency +Injection Container. To enable the service, add the following lines to your +configuration: + +.. code-block:: yaml + + # hello/config/config.yml + app.config: + validation: + enabled: true + +Then you can get the validator from the container and start validating your +objects. + +.. code-block:: php + + $validator = $container->getService('validator'); + $author = new Author(); + + print $validator->validate($author); + +The ``validate()`` method returns a +:class:`Symfony\Component\Validator\ConstraintViolationList`:: object. This object +behaves exactly like an array. You can iterate over it and you can even print +it in a nicely formatted manner. Every element of the list corresponds to +one validation error. If the list is empty, it's time to dance, because then +validation succeeded. + +The above call will output something similar to this: + +:: + + Application\HelloBundle\Author.firstName: + This value should not be blank + Application\HelloBundle\Author.lastName: + This value should not be blank + Application\HelloBundle\Author.fullName: + This value is too short. It should have 10 characters or more + +If you fill the object with correct values the validation errors disappear.