vendor/symfony/src/Symfony/Component/Validator/Mapping/ClassMetadata.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Symfony\Component\Validator\Mapping;
       
    13 
       
    14 use Symfony\Component\Validator\Constraint;
       
    15 use Symfony\Component\Validator\Constraints\Valid;
       
    16 use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
       
    17 use Symfony\Component\Validator\Exception\GroupDefinitionException;
       
    18 
       
    19 /**
       
    20  * Represents all the configured constraints on a given class.
       
    21  *
       
    22  * @author Bernhard Schussek <bernhard.schussek@symfony.com>
       
    23  * @author Fabien Potencier <fabien@symfony.com>
       
    24  */
       
    25 class ClassMetadata extends ElementMetadata
       
    26 {
       
    27     public $name;
       
    28     public $defaultGroup;
       
    29     public $members = array();
       
    30     public $properties = array();
       
    31     public $getters = array();
       
    32     public $groupSequence = array();
       
    33     private $reflClass;
       
    34 
       
    35     /**
       
    36      * Constructs a metadata for the given class
       
    37      *
       
    38      * @param string $class
       
    39      */
       
    40     public function __construct($class)
       
    41     {
       
    42         $this->name = $class;
       
    43         // class name without namespace
       
    44         if (false !== $nsSep = strrpos($class, '\\')) {
       
    45             $this->defaultGroup = substr($class, $nsSep + 1);
       
    46         } else {
       
    47             $this->defaultGroup = $class;
       
    48         }
       
    49     }
       
    50 
       
    51     /**
       
    52      * Returns the properties to be serialized
       
    53      *
       
    54      * @return array
       
    55      */
       
    56     public function __sleep()
       
    57     {
       
    58         return array_merge(parent::__sleep(), array(
       
    59             'getters',
       
    60             'groupSequence',
       
    61             'members',
       
    62             'name',
       
    63             'properties',
       
    64             'defaultGroup'
       
    65         ));
       
    66     }
       
    67 
       
    68     /**
       
    69      * Returns the fully qualified name of the class
       
    70      *
       
    71      * @return string  The fully qualified class name
       
    72      */
       
    73     public function getClassName()
       
    74     {
       
    75         return $this->name;
       
    76     }
       
    77 
       
    78     /**
       
    79      * Returns the name of the default group for this class
       
    80      *
       
    81      * For each class, the group "Default" is an alias for the group
       
    82      * "<ClassName>", where <ClassName> is the non-namespaced name of the
       
    83      * class. All constraints implicitly or explicitly assigned to group
       
    84      * "Default" belong to both of these groups, unless the class defines
       
    85      * a group sequence.
       
    86      *
       
    87      * If a class defines a group sequence, validating the class in "Default"
       
    88      * will validate the group sequence. The constraints assigned to "Default"
       
    89      * can still be validated by validating the class in "<ClassName>".
       
    90      *
       
    91      * @return string  The name of the default group
       
    92      */
       
    93     public function getDefaultGroup()
       
    94     {
       
    95         return $this->defaultGroup;
       
    96     }
       
    97 
       
    98     /**
       
    99      * {@inheritDoc}
       
   100      */
       
   101     public function addConstraint(Constraint $constraint)
       
   102     {
       
   103         if (!in_array(Constraint::CLASS_CONSTRAINT, (array) $constraint->getTargets())) {
       
   104             throw new ConstraintDefinitionException(sprintf(
       
   105                 'The constraint %s cannot be put on classes',
       
   106                 get_class($constraint)
       
   107             ));
       
   108         }
       
   109 
       
   110         $constraint->addImplicitGroupName($this->getDefaultGroup());
       
   111 
       
   112         parent::addConstraint($constraint);
       
   113     }
       
   114 
       
   115     /**
       
   116      * Adds a constraint to the given property.
       
   117      *
       
   118      * @param string     $property   The name of the property
       
   119      * @param Constraint $constraint The constraint
       
   120      *
       
   121      * @return ClassMetadata           This object
       
   122      */
       
   123     public function addPropertyConstraint($property, Constraint $constraint)
       
   124     {
       
   125         if (!isset($this->properties[$property])) {
       
   126             $this->properties[$property] = new PropertyMetadata($this->getClassName(), $property);
       
   127 
       
   128             $this->addMemberMetadata($this->properties[$property]);
       
   129         }
       
   130 
       
   131         $constraint->addImplicitGroupName($this->getDefaultGroup());
       
   132 
       
   133         $this->properties[$property]->addConstraint($constraint);
       
   134 
       
   135         return $this;
       
   136     }
       
   137 
       
   138     /**
       
   139      * Adds a constraint to the getter of the given property.
       
   140      *
       
   141      * The name of the getter is assumed to be the name of the property with an
       
   142      * uppercased first letter and either the prefix "get" or "is".
       
   143      *
       
   144      * @param string     $property   The name of the property
       
   145      * @param Constraint $constraint The constraint
       
   146      *
       
   147      * @return ClassMetadata This object
       
   148      */
       
   149     public function addGetterConstraint($property, Constraint $constraint)
       
   150     {
       
   151         if (!isset($this->getters[$property])) {
       
   152             $this->getters[$property] = new GetterMetadata($this->getClassName(), $property);
       
   153 
       
   154             $this->addMemberMetadata($this->getters[$property]);
       
   155         }
       
   156 
       
   157         $constraint->addImplicitGroupName($this->getDefaultGroup());
       
   158 
       
   159         $this->getters[$property]->addConstraint($constraint);
       
   160 
       
   161         return $this;
       
   162     }
       
   163 
       
   164     /**
       
   165      * Merges the constraints of the given metadata into this object.
       
   166      *
       
   167      * @param ClassMetadata $source The source metadata
       
   168      */
       
   169     public function mergeConstraints(ClassMetadata $source)
       
   170     {
       
   171         foreach ($source->getConstraints() as $constraint) {
       
   172             $this->addConstraint(clone $constraint);
       
   173         }
       
   174 
       
   175         foreach ($source->getConstrainedProperties() as $property) {
       
   176             foreach ($source->getMemberMetadatas($property) as $member) {
       
   177                 $member = clone $member;
       
   178 
       
   179                 foreach ($member->getConstraints() as $constraint) {
       
   180                     $constraint->addImplicitGroupName($this->getDefaultGroup());
       
   181                 }
       
   182 
       
   183                 $this->addMemberMetadata($member);
       
   184 
       
   185                 if (!$member->isPrivate()) {
       
   186                     $property = $member->getPropertyName();
       
   187 
       
   188                     if ($member instanceof PropertyMetadata && !isset($this->properties[$property])) {
       
   189                         $this->properties[$property] = $member;
       
   190                     } else if ($member instanceof GetterMetadata && !isset($this->getters[$property])) {
       
   191                         $this->getters[$property] = $member;
       
   192                     }
       
   193                 }
       
   194             }
       
   195         }
       
   196     }
       
   197 
       
   198     /**
       
   199      * Adds a member metadata
       
   200      *
       
   201      * @param MemberMetadata $metadata
       
   202      */
       
   203     protected function addMemberMetadata(MemberMetadata $metadata)
       
   204     {
       
   205         $property = $metadata->getPropertyName();
       
   206 
       
   207         $this->members[$property][] = $metadata;
       
   208     }
       
   209 
       
   210     /**
       
   211      * Returns true if metadatas of members is present for the given property.
       
   212      *
       
   213      * @param string $property The name of the property
       
   214      *
       
   215      * @return Boolean
       
   216      */
       
   217     public function hasMemberMetadatas($property)
       
   218     {
       
   219         return array_key_exists($property, $this->members);
       
   220     }
       
   221 
       
   222     /**
       
   223      * Returns all metadatas of members describing the given property
       
   224      *
       
   225      * @param string $property The name of the property
       
   226      * @array of MemberMetadata
       
   227      */
       
   228     public function getMemberMetadatas($property)
       
   229     {
       
   230         return $this->members[$property];
       
   231     }
       
   232 
       
   233     /**
       
   234      * Returns all properties for which constraints are defined.
       
   235      *
       
   236      * @return array An array of property names
       
   237      */
       
   238     public function getConstrainedProperties()
       
   239     {
       
   240         return array_keys($this->members);
       
   241     }
       
   242 
       
   243     /**
       
   244      * Sets the default group sequence for this class.
       
   245      *
       
   246      * @param array $groups An array of group names
       
   247      */
       
   248     public function setGroupSequence(array $groups)
       
   249     {
       
   250         if (in_array(Constraint::DEFAULT_GROUP, $groups, true)) {
       
   251             throw new GroupDefinitionException(sprintf('The group "%s" is not allowed in group sequences', Constraint::DEFAULT_GROUP));
       
   252         }
       
   253 
       
   254         if (!in_array($this->getDefaultGroup(), $groups, true)) {
       
   255             throw new GroupDefinitionException(sprintf('The group "%s" is missing in the group sequence', $this->getDefaultGroup()));
       
   256         }
       
   257 
       
   258         $this->groupSequence = $groups;
       
   259 
       
   260         return $this;
       
   261     }
       
   262 
       
   263     /**
       
   264      * Returns whether this class has an overridden default group sequence.
       
   265      *
       
   266      * @return Boolean
       
   267      */
       
   268     public function hasGroupSequence()
       
   269     {
       
   270         return count($this->groupSequence) > 0;
       
   271     }
       
   272 
       
   273     /**
       
   274      * Returns the default group sequence for this class.
       
   275      *
       
   276      * @return array An array of group names
       
   277      */
       
   278     public function getGroupSequence()
       
   279     {
       
   280         return $this->groupSequence;
       
   281     }
       
   282 
       
   283     /**
       
   284      * Returns a ReflectionClass instance for this class.
       
   285      *
       
   286      * @return ReflectionClass
       
   287      */
       
   288     public function getReflectionClass()
       
   289     {
       
   290         if (!$this->reflClass) {
       
   291             $this->reflClass = new \ReflectionClass($this->getClassName());
       
   292         }
       
   293 
       
   294         return $this->reflClass;
       
   295     }
       
   296 }