Collection

Esta restricción se utiliza cuando los datos subyacentes son una colección (es decir, un arreglo o un objeto que implemente Traversable y ArrayAccess), pero que te gustaría validar las distintas claves de la colección en diferentes maneras. Por ejemplo, puedes validar la clave email usando la restricción Email y la clave inventario de la colección con la restricción Range.

Esta restricción también puede asegurarse de que ciertas claves de la colección están presentes y que no existen claves adicionales.

Aplica a propiedad o método
Opciones
Clase Symfony\Component\Validator\Constraints\Collection
Validador Symfony\Component\Validator\Constraints\CollectionValidator

Uso básico

La restricción Collection te permite validar individualmente las diferentes claves de una colección. Tomemos el siguiente ejemplo:

// src/Acme/BlogBundle/Entity/Author.php
namespace Acme\BlogBundle\Entity;

class Author
{
    protected $profileData = array(
        'personal_email',
        'short_bio',
    );

    public function setProfileData($key, $value)
    {
        $this->profileData[$key] = $value;
    }
}

Para validar que el elemento correo_electronico_personal de la propiedad datosDelPerfil es una dirección de correo electrónico válida y que el elemento mini_biografia no está en blanco, pero no tiene más de 100 caracteres de longitud, debes hacer lo siguiente:

  • YAML
    # src/Acme/BlogBundle/Resources/config/validation.yml
    Acme\BlogBundle\Entity\Author:
        properties:
            profileData:
                - Collection:
                    fields:
                        personal_email: Email
                        short_bio:
                            - NotBlank
                            - Length:
                                max:   100
                                maxMessage: Your short bio is too long!
                    allowMissingFields: true
    
  • Annotations
    // src/Acme/BlogBundle/Entity/Author.php
    namespace Acme\BlogBundle\Entity;
    
    use Symfony\Component\Validator\Constraints as Assert;
    
    class Autor
    {
        /**
         * @Assert\Collection(
         *     fields = {
         *         "personal_email" = @Assert\Email,
         *         "short_bio" = {
         *             @Assert\NotBlank(),
         *             @Assert\Length(
         *                 max = 100,
         *                 maxMessage = "Your bio is too long!"
         *             )
         *         }
         *     },
         *     allowMissingfields = true
         * )
         */
         protected $profileData = array(
             'personal_email',
             'short_bio',
         );
    }
    
  • XML
    <!-- src/Acme/BlogBundle/Resources/config/validation.xml -->
    <class name="Acme\BlogBundle\Entity\Author">
        <property name="profileData">
            <constraint name="Collection">
                <option name="fields">
                    <value key="personal_email">
                        <constraint name="Email" />
                    </value>
                    <value key="short_bio">
                        <constraint name="NotBlank" />
                        <constraint name="Length">
                            <option name="max">100</option>
                            <option name="maxMessage">Your bio is too long!</option>
                        </constraint>
                    </value>
                </option>
                <option name="allowMissingFields">true</option>
            </constraint>
        </property>
    </class>
    
  • PHP
    // src/Acme/BlogBundle/Entity/Author.php
    namespace Acme\BlogBundle\Entity;
    
    use Symfony\Component\Validator\Mapping\ClassMetadata;
    use Symfony\Component\Validator\Constraints as Assert;
    
    class Autor
    {
        private $options = array();
    
        public static function loadValidatorMetadata(ClassMetadata $metadata)
        {
            $metadata->addPropertyConstraint('profileData', new Assert\Collection(array(
                'fields' => array(
                    'personal_email' => new Assert\Email(),
                    'lastName' => array(
                        new Assert\NotBlank(),
                        new Assert\Length(array("max" => 100)),
                    ),
                ),
                'allowMissingFields' => true,
            )));
        }
    }
    

Presencia y ausencia de campos

De manera predeterminada, esta restricción valida más que simplemente si o no los campos individuales de la colección pasan sus restricciones asignadas. De hecho, si falta cualquiera de las claves de una colección o si hay alguna clave desconocida en la colección, lanzará errores de validación.

Si deseas permitir que las claves de la colección estén ausentes o si quisieras permitir claves «extra» en la colección, puedes modificar las opciones allowMissingFields y allowExtraFields, respectivamente. En el ejemplo anterior, la opción allowMissingFields se fijó en true, lo cual significa que si cualquiera de las propiedades personal_email o short_bio no estuviera en $personalData, no ocurrirá ningún error de validación.

Nuevo en la versión 2.1: The Required and Optional constraints are new to Symfony 2.1.

Required and Optional Field Constraints

Constraints for fields within a collection can be wrapped in the Required or Optional constraint to control whether they should always be applied (Required) or only applied when the field is present (Optional).

For instance, if you want to require that the personal_email field of the profileData array is not blank and is a valid email but the alternate_email field is optional but must be a valid email if supplied, you can do the following:

  • Annotations
    // src/Acme/BlogBundle/Entity/Author.php
    namespace Acme\BlogBundle\Entity;
    
    use Symfony\Component\Validator\Constraints as Assert;
    
    class Autor
    {
        /**
         * @Assert\Collection(
         *     fields={
         *         "personal_email"  = @Assert\Collection\Required({@Assert\NotBlank, @Assert\Email}),
         *         "alternate_email" = @Assert\Collection\Optional({@Assert\Email}),
         *     }
         * )
         */
         protected $profileData = array(
             'personal_email',
         );
    }
    
  • PHP
    // src/Acme/BlogBundle/Entity/Author.php
    namespace Acme\BlogBundle\Entity;
    
    use Symfony\Component\Validator\Mapping\ClassMetadata;
    use Symfony\Component\Validator\Constraints as Assert;
    
    class Autor
    {
        protected $profileData = array('personal_email');
    
        public static function loadValidatorMetadata(ClassMetadata $metadata)
        {
            $metadata->addPropertyConstraint('profileData', new Assert\Collection(array(
                'fields' => array(
                    'personal_email'  => new Assert\Collection\Required(array(new Assert\NotBlank(), new Assert\Email())),
                    'alternate_email' => new Assert\Collection\Optional(array(new Assert\Email())),
                ),
            )));
        }
    }
    

Even without allowMissingFields set to true, you can now omit the alternate_email property completely from the profileData array, since it is Optional. However, if the the personal_email field does not exist in the array, the NotBlank constraint will still be applied (since it is wrapped in Required) and you will receive a constraint violation.

Opciones

fields

tipo: array [opción predeterminada]

Esta opción es obligatoria, y es un arreglo asociativo que define todas las claves de la colección y, para cada clave, exactamente, qué validaciones se deben ejecutar contra ese elemento de la colección.

allowExtraFields

tipo: Boolean predeterminado: false

Si esta opción está establecida en false y la colección subyacente contiene uno o más elementos que no están incluidos en la opción fields, devolverá un error de validación. Si se define como true, está bien tener campos adicionales.

extraFieldsMessage

tipo: Boolean predeterminado: The fields {{ fields }} were not expected (Los campos {{ fields }} no se esperaban)

El mensaje aparece si allowExtraFields es false y se detecta un campo adicional.

allowMissingFields

tipo: Boolean predeterminado: false

Si esta opción está establecida en false y uno o más campos de la opción fields no están presentes en la colección subyacente, devolverá un error de validación. Si se define como true, está bien si algunos campos de la opción fields no están presentes en la colección subyacente.

missingFieldsMessage

tipo: Boolean predeterminado: The fields {{ fields }} are missing (Faltan los campos {{ fields }})

El mensaje aparece si allowMissingFields es false y uno o más campos no se encuentran en la colección subyacente.

Bifúrcame en GitHub