ExecutionContext.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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;
  11. @trigger_error('The '.__NAMESPACE__.'\ExecutionContext class is deprecated since version 2.5 and will be removed in 3.0. Use the Symfony\Component\Validator\Context\ExecutionContext class instead.', E_USER_DEPRECATED);
  12. use Symfony\Component\Translation\TranslatorInterface;
  13. /**
  14. * Default implementation of {@link ExecutionContextInterface}.
  15. *
  16. * This class is immutable by design.
  17. *
  18. * @author Fabien Potencier <fabien@symfony.com>
  19. * @author Bernhard Schussek <bschussek@gmail.com>
  20. *
  21. * @deprecated since version 2.5, to be removed in 3.0.
  22. * Use {@link Context\ExecutionContext} instead.
  23. */
  24. class ExecutionContext implements ExecutionContextInterface
  25. {
  26. /**
  27. * @var GlobalExecutionContextInterface
  28. */
  29. private $globalContext;
  30. /**
  31. * @var TranslatorInterface
  32. */
  33. private $translator;
  34. /**
  35. * @var null|string
  36. */
  37. private $translationDomain;
  38. /**
  39. * @var MetadataInterface
  40. */
  41. private $metadata;
  42. /**
  43. * @var mixed
  44. */
  45. private $value;
  46. /**
  47. * @var string
  48. */
  49. private $group;
  50. /**
  51. * @var string
  52. */
  53. private $propertyPath;
  54. /**
  55. * Creates a new execution context.
  56. *
  57. * @param GlobalExecutionContextInterface $globalContext The global context storing node-independent state
  58. * @param TranslatorInterface $translator The translator for translating violation messages
  59. * @param null|string $translationDomain The domain of the validation messages
  60. * @param MetadataInterface $metadata The metadata of the validated node
  61. * @param mixed $value The value of the validated node
  62. * @param string $group The current validation group
  63. * @param string $propertyPath The property path to the current node
  64. */
  65. public function __construct(GlobalExecutionContextInterface $globalContext, TranslatorInterface $translator, $translationDomain = null, MetadataInterface $metadata = null, $value = null, $group = null, $propertyPath = '')
  66. {
  67. if (null === $group) {
  68. $group = Constraint::DEFAULT_GROUP;
  69. }
  70. $this->globalContext = $globalContext;
  71. $this->translator = $translator;
  72. $this->translationDomain = $translationDomain;
  73. $this->metadata = $metadata;
  74. $this->value = $value;
  75. $this->propertyPath = $propertyPath;
  76. $this->group = $group;
  77. }
  78. /**
  79. * {@inheritdoc}
  80. */
  81. public function addViolation($message, array $params = array(), $invalidValue = null, $plural = null, $code = null)
  82. {
  83. if (null === $plural) {
  84. $translatedMessage = $this->translator->trans($message, $params, $this->translationDomain);
  85. } else {
  86. try {
  87. $translatedMessage = $this->translator->transChoice($message, $plural, $params, $this->translationDomain);
  88. } catch (\InvalidArgumentException $e) {
  89. $translatedMessage = $this->translator->trans($message, $params, $this->translationDomain);
  90. }
  91. }
  92. $this->globalContext->getViolations()->add(new ConstraintViolation(
  93. $translatedMessage,
  94. $message,
  95. $params,
  96. $this->globalContext->getRoot(),
  97. $this->propertyPath,
  98. // check using func_num_args() to allow passing null values
  99. func_num_args() >= 3 ? $invalidValue : $this->value,
  100. $plural,
  101. $code
  102. ));
  103. }
  104. /**
  105. * {@inheritdoc}
  106. */
  107. public function addViolationAt($subPath, $message, array $parameters = array(), $invalidValue = null, $plural = null, $code = null)
  108. {
  109. $this->globalContext->getViolations()->add(new ConstraintViolation(
  110. null === $plural
  111. ? $this->translator->trans($message, $parameters, $this->translationDomain)
  112. : $this->translator->transChoice($message, $plural, $parameters, $this->translationDomain),
  113. $message,
  114. $parameters,
  115. $this->globalContext->getRoot(),
  116. $this->getPropertyPath($subPath),
  117. // check using func_num_args() to allow passing null values
  118. func_num_args() >= 4 ? $invalidValue : $this->value,
  119. $plural,
  120. $code
  121. ));
  122. }
  123. /**
  124. * {@inheritdoc}
  125. */
  126. public function getViolations()
  127. {
  128. return $this->globalContext->getViolations();
  129. }
  130. /**
  131. * {@inheritdoc}
  132. */
  133. public function getRoot()
  134. {
  135. return $this->globalContext->getRoot();
  136. }
  137. /**
  138. * {@inheritdoc}
  139. */
  140. public function getPropertyPath($subPath = '')
  141. {
  142. if ('' != $subPath && '' !== $this->propertyPath && '[' !== $subPath[0]) {
  143. return $this->propertyPath.'.'.$subPath;
  144. }
  145. return $this->propertyPath.$subPath;
  146. }
  147. /**
  148. * {@inheritdoc}
  149. */
  150. public function getClassName()
  151. {
  152. if ($this->metadata instanceof ClassBasedInterface) {
  153. return $this->metadata->getClassName();
  154. }
  155. }
  156. /**
  157. * {@inheritdoc}
  158. */
  159. public function getPropertyName()
  160. {
  161. if ($this->metadata instanceof PropertyMetadataInterface) {
  162. return $this->metadata->getPropertyName();
  163. }
  164. }
  165. /**
  166. * {@inheritdoc}
  167. */
  168. public function getValue()
  169. {
  170. return $this->value;
  171. }
  172. /**
  173. * {@inheritdoc}
  174. */
  175. public function getGroup()
  176. {
  177. return $this->group;
  178. }
  179. /**
  180. * {@inheritdoc}
  181. */
  182. public function getMetadata()
  183. {
  184. return $this->metadata;
  185. }
  186. /**
  187. * {@inheritdoc}
  188. */
  189. public function getMetadataFor($value)
  190. {
  191. return $this->globalContext->getMetadataFactory()->getMetadataFor($value);
  192. }
  193. /**
  194. * {@inheritdoc}
  195. */
  196. public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false)
  197. {
  198. $propertyPath = $this->getPropertyPath($subPath);
  199. foreach ($this->resolveGroups($groups) as $group) {
  200. $this->globalContext->getVisitor()->validate($value, $group, $propertyPath, $traverse, $deep);
  201. }
  202. }
  203. /**
  204. * {@inheritdoc}
  205. */
  206. public function validateValue($value, $constraints, $subPath = '', $groups = null)
  207. {
  208. $constraints = is_array($constraints) ? $constraints : array($constraints);
  209. if (null === $groups && '' === $subPath) {
  210. $context = clone $this;
  211. $context->value = $value;
  212. $context->executeConstraintValidators($value, $constraints);
  213. return;
  214. }
  215. $propertyPath = $this->getPropertyPath($subPath);
  216. foreach ($this->resolveGroups($groups) as $group) {
  217. $context = clone $this;
  218. $context->value = $value;
  219. $context->group = $group;
  220. $context->propertyPath = $propertyPath;
  221. $context->executeConstraintValidators($value, $constraints);
  222. }
  223. }
  224. /**
  225. * {@inheritdoc}
  226. */
  227. public function getMetadataFactory()
  228. {
  229. return $this->globalContext->getMetadataFactory();
  230. }
  231. /**
  232. * Executes the validators of the given constraints for the given value.
  233. *
  234. * @param mixed $value The value to validate
  235. * @param Constraint[] $constraints The constraints to match against
  236. */
  237. private function executeConstraintValidators($value, array $constraints)
  238. {
  239. foreach ($constraints as $constraint) {
  240. $validator = $this->globalContext->getValidatorFactory()->getInstance($constraint);
  241. $validator->initialize($this);
  242. $validator->validate($value, $constraint);
  243. }
  244. }
  245. /**
  246. * Returns an array of group names.
  247. *
  248. * @param null|string|string[] $groups The groups to resolve. If a single string is
  249. * passed, it is converted to an array. If null
  250. * is passed, an array containing the current
  251. * group of the context is returned.
  252. *
  253. * @return array An array of validation groups
  254. */
  255. private function resolveGroups($groups)
  256. {
  257. return $groups ? (array) $groups : (array) $this->group;
  258. }
  259. }