123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- Inline Validation
- =================
- The inline validation is about delegating model validation to a dedicated service.
- The current validation implementation built in the Symfony2 framework is very powerful
- as it allows to declare validation on a : class, field and getter. However these declarations
- can take a while to code for complex rules. As rules must be a set of a ``Constraint``
- and a ``Validator`` instances.
- The inline validation tries to provide a nice solution by introducing an ``ErrorElement``
- object. The object can be used to check assertions against the model :
- .. code-block:: php
- <?php
- $errorElement
- ->with('settings.url')
- ->assertNotNull(array())
- ->assertNotBlank()
- ->end()
- ->with('settings.title')
- ->assertNotNull(array())
- ->assertNotBlank()
- // for minimum length constraint
- ->assertLength(array('min' => 50))
- // for maximum length constraint
- ->assertLength(array('max' => 100))
- ->addViolation('ho yeah!')
- ->end();
- if (/* complex rules */) {
- $errorElement->with('value')->addViolation('Fail to check the complex rules')->end()
- }
- /* conditional validation */
- if ($this->getSubject()->getState() == Post::STATUS_ONLINE) {
- $errorElement
- ->with('enabled')
- ->assertNotNull()
- ->assertTrue()
- ->end();
- }
- .. note::
- This solution relies on the validator component so validation defined through
- the validator component will be used.
- .. tip::
- You can also use ``$errorElement->addConstraint(new \Symfony\Component\Validator\Constraints\NotBlank())``
- instead of calling assertNotBlank().
-
- You can also use ``$errorElement->addConstraint(new \Symfony\Component\Validator\Constraints\Length(array('min'=>5, 'max'=>100))``
- instead of calling assertLength().
- Using this validator
- --------------------
- Add the ``InlineConstraint`` class constraint to your bundle's validation configuration, for example:
- .. configuration-block::
- .. code-block:: xml
- <!-- src/Application/Sonata/PageBundle/Resources/config/validation.xml -->
- <?xml version="1.0" ?>
- <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
- <class name="Application\Sonata\PageBundle\Entity\Block">
- <constraint name="Sonata\AdminBundle\Validator\Constraints\InlineConstraint">
- <option name="service">sonata.page.cms.page</option>
- <option name="method">validateBlock</option>
- </constraint>
- </class>
- </constraint-mapping>
- .. code-block:: yaml
- # src/Application/Sonata/PageBundle/Resources/config/validation.yml
- Application\Sonata\PageBundle\Entity\Block:
- constraints:
- - Sonata\AdminBundle\Validator\Constraints\InlineConstraint:
- service: sonata.page.cms.page
- method: validateBlock
- There are two important options:
- - ``service``: the service where the validation method is defined
- - ``method``: the service's method to call
- The method must accept two arguments:
- - ``ErrorElement``: the instance where assertion can be checked
- - ``value``: the object instance
- Example from the ``SonataPageBundle``
- -------------------------------------
- .. code-block:: php
- <?php
- namespace Sonata\PageBundle\Block;
- use Sonata\PageBundle\Model\PageInterface;
- use Sonata\AdminBundle\Validator\ErrorElement;
- class RssBlockService extends BaseBlockService
- {
- // ... code removed for simplification
- public function validateBlock(ErrorElement $errorElement, BlockInterface $block)
- {
- $errorElement
- ->with('settings.url')
- ->assertNotNull(array())
- ->assertNotBlank()
- ->end()
- ->with('settings.title')
- ->assertNotNull(array())
- ->assertNotBlank()
- // for minimum length constraint
- ->assertLength(array('min' => 50))
- // for maximum length constraint
- ->assertLength(array('max' => 100))
- ->addViolation('ho yeah!')
- ->end();
- }
- }
- Using the Admin class
- ---------------------
- This feature is deprecated and will be removed on the 2.2 branch.
- The above examples show how to delegate validation to a service. For completeness, it's worth remembering that
- the ``Admin`` class itself contains an empty ``validate`` method. This is automatically called, so you can override it in your own admin class:
- .. code-block:: php
- // add this to your existing use statements
- use Sonata\AdminBundle\Validator\ErrorElement;
- class MyAdmin extends Admin
- {
- // add this method
- public function validate(ErrorElement $errorElement, $object)
- {
- $errorElement
- ->with('name')
- ->assertLength(array('max' => 32))
- ->end()
- ;
- }
- Troubleshooting
- ---------------
- Make sure your validator method is being called. If in doubt, try throwing an exception:
- .. code-block:: php
- public function validate(ErrorElement $errorElement, $object)
- {
- throw new \Exception(__METHOD__);
- }
- There should not be any validation_groups defined for the form. If you have code like the example below in
- your ``Admin`` class, remove the 'validation_groups' entry, the whole $formOptions property or set validation_groups
- to an empty array:
- .. code-block:: php
- protected $formOptions = array(
- 'validation_groups' => array()
- );
|