Creative Commons License
This work is licensed under a
Creative Commons
Attribution-Share Alike 3.0
Unported License.

Master Symfony2 fundamentals

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).
trainings.sensiolabs.com

Symfony hosting done right

ServerGrove, outstanding support at the right price for your Symfony hosting needs.
servergrove.com

Discover the SensioLabs Support

Access to the SensioLabs Competency Center for an exclusive and tailor-made support on Symfony
sensiolabs.com

Callback

Lo scopo del vincolo Callback è di poter creare delle regole di validazione completamente personalizzate e di assegnare qualsiasi errore di validazione a campi specifici del proprio oggetto. Se si usa la validazione con i form, questo vuol dire che si possono mostrare questi errori personalizzati accanto a campi specifici, invece di mostrarli semplicemente in cima al form.

Questo processo funziona specificando uno o più metodi di callback, ciascuno dei quali sarà richiamato durante il processo di validazione. Ognuno di questi metodi può fare qualsiasi cosa, incluso creare e assegnare errori di validazione.

Note

Un metodo callback per sé stesso non fallisce, né restituisce valori. Invece, come vedremo nell'esempio, un metodo callback ha l'abilità di aggiungere direttamente "violazioni" al validatore.

Si applica a classi
Opzioni
Classe Callback
Validatore CallbackValidator

Preparazione

  • YAML
    1
    2
    3
    4
    5
    # src/Acme/BlogBundle/Resources/config/validation.yml
    Acme\BlogBundle\Entity\Author:
        constraints:
            - Callback:
                methods:   [isAuthorValid]
    
  • Annotations
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    // src/Acme/BlogBundle/Entity/Author.php
    namespace Acme\BlogBundle\Entity;
    
    use Symfony\Component\Validator\Constraints as Assert;
    
    /**
     * @Assert\Callback(methods={"isAuthorValid"})
     */
    class Author
    {
    }
    
  • XML
    1
    2
    3
    4
    5
    6
    7
    8
    <!-- src/Acme/BlogBundle/Resources/config/validation.xml -->
    <class name="Acme\BlogBundle\Entity\Author">
        <constraint name="Callback">
            <option name="methods">
                <value>isAuthorValid</value>
            </option>
        </constraint>
    </class>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    // src/Acme/BlogBundle/Entity/Author.php
    namespace Acme\BlogBundle\Entity;
    
    use Symfony\Component\Validator\Mapping\ClassMetadata;
    use Symfony\Component\Validator\Constraints as Assert;
    
    class Author
    {
        public static function loadValidatorMetadata(ClassMetadata $metadata)
        {
            $metadata->addConstraint(new Assert\Callback(array(
                'methods' => array('isAuthorValid'),
            )));
        }
    }
    

Il metod callback

Il metod callback è passato a uno speciale oggetto ExecutionContext. Si possono impostare le "violazioni" direttamente su questo oggetto e determinare a quale campo questi errori vadano attribuiti:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// ...
use Symfony\Component\Validator\ExecutionContext;

class Author
{
    // ...
    private $firstName;

    public function isAuthorValid(ExecutionContext $context)
    {
        // si ha in qualche modo un array di nomi fasulli
        $fakeNames = array();

        // verifica se il nome è in effetti un nome fasullo
        if (in_array($this->getFirstName(), $fakeNames)) {
            $context->addViolationAtSubPath('firstname', 'Questo nome  sembra proprio falso!', array(), null);
        }
    }
 }

Opzioni

methods

tipo: array predefinito: array() [opzione predefinita]

Un array di metodi che andrebbero eseguiti durante il processo di validazione. Ogni metodo può avere uno dei seguenti formati:

  1. Stringa con il nome del metodo

    Se il nome di un metodo è una semplice stringa (p.e. isAuthorValid), quel metodo sarà richiamato sullo stesso oggetto in corso di validazione e ExecutionContext sarà l'unico parametro (vedere esempio precedente).

  2. Array statico callback

    Ogni metodo può anche essere specificato con un array callback:

    • YAML
      1
      2
      3
      4
      5
      6
      # src/Acme/BlogBundle/Resources/config/validation.yml
      Acme\BlogBundle\Entity\Author:
          constraints:
              - Callback:
                  methods:
                      -    [Acme\BlogBundle\MyStaticValidatorClass, isAuthorValid]
      
    • Annotations
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      // src/Acme/BlogBundle/Entity/Author.php
      use Symfony\Component\Validator\Constraints as Assert;
      
      /**
       * @Assert\Callback(methods={
       *     { "Acme\BlogBundle\MyStaticValidatorClass", "isAuthorValid"}
       * })
       */
      class Author
      {
      }
      
    • XML
      1
      2
      3
      4
      5
      6
      7
      8
      9
      <!-- src/Acme/BlogBundle/Resources/config/validation.xml -->
      <class name="Acme\BlogBundle\Entity\Author">
          <constraint name="Callback">
              <option name="methods">
                  <value>Acme\BlogBundle\MyStaticValidatorClass</value>
                  <value>isAuthorValid</value>
              </option>
          </constraint>
      </class>
      
    • PHP
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      // src/Acme/BlogBundle/Entity/Author.php
      
      use Symfony\Component\Validator\Mapping\ClassMetadata;
      use Symfony\Component\Validator\Constraints\Callback;
      
      class Author
      {
          public $name;
      
          public static function loadValidatorMetadata(ClassMetadata $metadata)
          {
              $metadata->addConstraint(new Callback(array(
                  'methods' => array('isAuthorValid'),
              )));
          }
      }
      

    In questo caso, sarà richiamato il metodo statico isAuthorValid della classe Acme\BlogBundle\MyStaticValidatorClass. Gli verrà passato sia l'oggetto originale in corso di validazione (p.e. Author) che ExecutionContext:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    namespace Acme\BlogBundle;
    
    use Symfony\Component\Validator\ExecutionContext;
    use Acme\BlogBundle\Entity\Author;
    
    class MyStaticValidatorClass
    {
        public static function isAuthorValid(Author $author, ExecutionContext $context)
        {
            // ...
        }
    }
    

    Tip

    Se si specifica il vincolo Callback tramite PHP, c'è anche l'opzione di rendere il callback una closure PHP o un callback non statico. Tuttavia, non è attualmente possibile specificare un servizio come vincolo. Per validare usando un servizio, si dovrebbe creare un vincolo personalizzato e aggiungere il nuovo vincolo alla propria classe.