GenericMetadata.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Validator\Mapping;
  11. use Symfony\Component\Validator\Constraint;
  12. use Symfony\Component\Validator\Constraints\Cascade;
  13. use Symfony\Component\Validator\Constraints\DisableAutoMapping;
  14. use Symfony\Component\Validator\Constraints\EnableAutoMapping;
  15. use Symfony\Component\Validator\Constraints\Traverse;
  16. use Symfony\Component\Validator\Constraints\Valid;
  17. use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
  18. /**
  19. * A generic container of {@link Constraint} objects.
  20. *
  21. * This class supports serialization and cloning.
  22. *
  23. * @author Bernhard Schussek <bschussek@gmail.com>
  24. */
  25. class GenericMetadata implements MetadataInterface
  26. {
  27. /**
  28. * @var Constraint[]
  29. *
  30. * @internal This property is public in order to reduce the size of the
  31. * class' serialized representation. Do not access it. Use
  32. * {@link getConstraints()} and {@link findConstraints()} instead.
  33. */
  34. public $constraints = [];
  35. /**
  36. * @var array
  37. *
  38. * @internal This property is public in order to reduce the size of the
  39. * class' serialized representation. Do not access it. Use
  40. * {@link findConstraints()} instead.
  41. */
  42. public $constraintsByGroup = [];
  43. /**
  44. * The strategy for cascading objects.
  45. *
  46. * By default, objects are not cascaded.
  47. *
  48. * @var int
  49. *
  50. * @see CascadingStrategy
  51. *
  52. * @internal This property is public in order to reduce the size of the
  53. * class' serialized representation. Do not access it. Use
  54. * {@link getCascadingStrategy()} instead.
  55. */
  56. public $cascadingStrategy = CascadingStrategy::NONE;
  57. /**
  58. * The strategy for traversing traversable objects.
  59. *
  60. * By default, traversable objects are not traversed.
  61. *
  62. * @var int
  63. *
  64. * @see TraversalStrategy
  65. *
  66. * @internal This property is public in order to reduce the size of the
  67. * class' serialized representation. Do not access it. Use
  68. * {@link getTraversalStrategy()} instead.
  69. */
  70. public $traversalStrategy = TraversalStrategy::NONE;
  71. /**
  72. * Is auto-mapping enabled?
  73. *
  74. * @var int
  75. *
  76. * @see AutoMappingStrategy
  77. *
  78. * @internal This property is public in order to reduce the size of the
  79. * class' serialized representation. Do not access it. Use
  80. * {@link getAutoMappingStrategy()} instead.
  81. */
  82. public $autoMappingStrategy = AutoMappingStrategy::NONE;
  83. /**
  84. * Returns the names of the properties that should be serialized.
  85. *
  86. * @return string[]
  87. */
  88. public function __sleep()
  89. {
  90. return [
  91. 'constraints',
  92. 'constraintsByGroup',
  93. 'cascadingStrategy',
  94. 'traversalStrategy',
  95. 'autoMappingStrategy',
  96. ];
  97. }
  98. /**
  99. * Clones this object.
  100. */
  101. public function __clone()
  102. {
  103. $constraints = $this->constraints;
  104. $this->constraints = [];
  105. $this->constraintsByGroup = [];
  106. foreach ($constraints as $constraint) {
  107. $this->addConstraint(clone $constraint);
  108. }
  109. }
  110. /**
  111. * Adds a constraint.
  112. *
  113. * If the constraint {@link Valid} is added, the cascading strategy will be
  114. * changed to {@link CascadingStrategy::CASCADE}. Depending on the
  115. * $traverse property of that constraint, the traversal strategy
  116. * will be set to one of the following:
  117. *
  118. * - {@link TraversalStrategy::IMPLICIT} if $traverse is enabled
  119. * - {@link TraversalStrategy::NONE} if $traverse is disabled
  120. *
  121. * @return $this
  122. *
  123. * @throws ConstraintDefinitionException When trying to add the {@link Cascade}
  124. * or {@link Traverse} constraint
  125. */
  126. public function addConstraint(Constraint $constraint)
  127. {
  128. if ($constraint instanceof Traverse || $constraint instanceof Cascade) {
  129. throw new ConstraintDefinitionException(sprintf('The constraint "%s" can only be put on classes. Please use "Symfony\Component\Validator\Constraints\Valid" instead.', get_debug_type($constraint)));
  130. }
  131. if ($constraint instanceof Valid && null === $constraint->groups) {
  132. $this->cascadingStrategy = CascadingStrategy::CASCADE;
  133. if ($constraint->traverse) {
  134. $this->traversalStrategy = TraversalStrategy::IMPLICIT;
  135. } else {
  136. $this->traversalStrategy = TraversalStrategy::NONE;
  137. }
  138. return $this;
  139. }
  140. if ($constraint instanceof DisableAutoMapping || $constraint instanceof EnableAutoMapping) {
  141. $this->autoMappingStrategy = $constraint instanceof EnableAutoMapping ? AutoMappingStrategy::ENABLED : AutoMappingStrategy::DISABLED;
  142. // The constraint is not added
  143. return $this;
  144. }
  145. $this->constraints[] = $constraint;
  146. foreach ($constraint->groups as $group) {
  147. $this->constraintsByGroup[$group][] = $constraint;
  148. }
  149. return $this;
  150. }
  151. /**
  152. * Adds an list of constraints.
  153. *
  154. * @param Constraint[] $constraints The constraints to add
  155. *
  156. * @return $this
  157. */
  158. public function addConstraints(array $constraints)
  159. {
  160. foreach ($constraints as $constraint) {
  161. $this->addConstraint($constraint);
  162. }
  163. return $this;
  164. }
  165. /**
  166. * {@inheritdoc}
  167. */
  168. public function getConstraints()
  169. {
  170. return $this->constraints;
  171. }
  172. /**
  173. * Returns whether this element has any constraints.
  174. *
  175. * @return bool
  176. */
  177. public function hasConstraints()
  178. {
  179. return \count($this->constraints) > 0;
  180. }
  181. /**
  182. * {@inheritdoc}
  183. *
  184. * Aware of the global group (* group).
  185. */
  186. public function findConstraints(string $group)
  187. {
  188. return $this->constraintsByGroup[$group] ?? [];
  189. }
  190. /**
  191. * {@inheritdoc}
  192. */
  193. public function getCascadingStrategy()
  194. {
  195. return $this->cascadingStrategy;
  196. }
  197. /**
  198. * {@inheritdoc}
  199. */
  200. public function getTraversalStrategy()
  201. {
  202. return $this->traversalStrategy;
  203. }
  204. /**
  205. * @see AutoMappingStrategy
  206. */
  207. public function getAutoMappingStrategy(): int
  208. {
  209. return $this->autoMappingStrategy;
  210. }
  211. }