PageRenderTime 51ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Symfony/Component/Validator/ExecutionContext.php

https://github.com/thomas2411/symfony
PHP | 412 lines | 187 code | 48 blank | 177 comment | 11 complexity | 0ef24a5e18bac8885aff9df2d5b326c7 MD5 | raw file
  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. use Symfony\Component\Translation\TranslatorInterface;
  12. /**
  13. * Default implementation of {@link ExecutionContextInterface}.
  14. *
  15. * This class is immutable by design.
  16. *
  17. * @author Fabien Potencier <fabien@symfony.com>
  18. * @author Bernhard Schussek <bschussek@gmail.com>
  19. */
  20. class ExecutionContext implements ExecutionContextInterface
  21. {
  22. /**
  23. * @var GlobalExecutionContextInterface
  24. */
  25. private $globalContext;
  26. /**
  27. * @var TranslatorInterface
  28. */
  29. private $translator;
  30. /**
  31. * @var null|string
  32. */
  33. private $translationDomain;
  34. /**
  35. * @var MetadataInterface
  36. */
  37. private $metadata;
  38. /**
  39. * @var mixed
  40. */
  41. private $value;
  42. /**
  43. * @var string
  44. */
  45. private $group;
  46. /**
  47. * @var string
  48. */
  49. private $propertyPath;
  50. /**
  51. * Creates a new execution context.
  52. *
  53. * @param GlobalExecutionContextInterface $globalContext The global context storing node-independent state.
  54. * @param TranslatorInterface $translator The translator for translating violation messages.
  55. * @param null|string $translationDomain The domain of the validation messages.
  56. * @param MetadataInterface $metadata The metadata of the validated node.
  57. * @param mixed $value The value of the validated node.
  58. * @param string $group The current validation group.
  59. * @param string $propertyPath The property path to the current node.
  60. */
  61. public function __construct(GlobalExecutionContextInterface $globalContext, TranslatorInterface $translator, $translationDomain = null, MetadataInterface $metadata = null, $value = null, $group = null, $propertyPath = '')
  62. {
  63. if (null === $group) {
  64. $group = Constraint::DEFAULT_GROUP;
  65. }
  66. $this->globalContext = $globalContext;
  67. $this->translator = $translator;
  68. $this->translationDomain = $translationDomain;
  69. $this->metadata = $metadata;
  70. $this->value = $value;
  71. $this->propertyPath = $propertyPath;
  72. $this->group = $group;
  73. }
  74. /**
  75. * {@inheritdoc}
  76. */
  77. public function addViolation($message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null)
  78. {
  79. $this->globalContext->getViolations()->add(new ConstraintViolation(
  80. null === $pluralization
  81. ? $this->translator->trans($message, $params, $this->translationDomain)
  82. : $this->translator->transChoice($message, $pluralization, $params, $this->translationDomain),
  83. $message,
  84. $params,
  85. $this->globalContext->getRoot(),
  86. $this->propertyPath,
  87. // check using func_num_args() to allow passing null values
  88. func_num_args() >= 3 ? $invalidValue : $this->value,
  89. $pluralization,
  90. $code
  91. ));
  92. }
  93. /**
  94. * Adds a violation at the validation graph node with the given property
  95. * path.
  96. *
  97. * @param string $propertyPath The property path for the violation.
  98. * @param string $message The error message.
  99. * @param array $params The parameters parsed into the error message.
  100. * @param mixed $invalidValue The invalid, validated value.
  101. * @param integer|null $pluralization The number to use to pluralize of the message.
  102. * @param integer|null $code The violation code.
  103. *
  104. * @deprecated Deprecated since version 2.2, to be removed in 2.3.
  105. */
  106. public function addViolationAtPath($propertyPath, $message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null)
  107. {
  108. trigger_error('addViolationAtPath() is deprecated since version 2.2 and will be removed in 2.3.', E_USER_DEPRECATED);
  109. $this->globalContext->getViolations()->add(new ConstraintViolation(
  110. null === $pluralization
  111. ? $this->translator->trans($message, $params, $this->translationDomain)
  112. : $this->translator->transChoice($message, $pluralization, $params, $this->translationDomain),
  113. $message,
  114. $params,
  115. $this->globalContext->getRoot(),
  116. $propertyPath,
  117. // check using func_num_args() to allow passing null values
  118. func_num_args() >= 4 ? $invalidValue : $this->value,
  119. $pluralization,
  120. $code
  121. ));
  122. }
  123. /**
  124. * Adds a violation at the validation graph node with the given property
  125. * path relative to the current property path.
  126. *
  127. * @param string $subPath The relative property path for the violation.
  128. * @param string $message The error message.
  129. * @param array $params The parameters parsed into the error message.
  130. * @param mixed $invalidValue The invalid, validated value.
  131. * @param integer|null $pluralization The number to use to pluralize of the message.
  132. * @param integer|null $code The violation code.
  133. *
  134. * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use the
  135. * method {@link addViolationAt} instead.
  136. */
  137. public function addViolationAtSubPath($subPath, $message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null)
  138. {
  139. trigger_error('addViolationAtSubPath() is deprecated since version 2.2 and will be removed in 2.3. Use addViolationAt() instead.', E_USER_DEPRECATED);
  140. if (func_num_args() >= 4) {
  141. $this->addViolationAt($subPath, $message, $params, $invalidValue, $pluralization, $code);
  142. } else {
  143. // Needed in order to make the check for func_num_args() inside work
  144. $this->addViolationAt($subPath, $message, $params);
  145. }
  146. }
  147. /**
  148. * {@inheritdoc}
  149. */
  150. public function addViolationAt($subPath, $message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null)
  151. {
  152. $this->globalContext->getViolations()->add(new ConstraintViolation(
  153. null === $pluralization
  154. ? $this->translator->trans($message, $params, $this->translationDomain)
  155. : $this->translator->transChoice($message, $pluralization, $params, $this->translationDomain),
  156. $message,
  157. $params,
  158. $this->globalContext->getRoot(),
  159. $this->getPropertyPath($subPath),
  160. // check using func_num_args() to allow passing null values
  161. func_num_args() >= 4 ? $invalidValue : $this->value,
  162. $pluralization,
  163. $code
  164. ));
  165. }
  166. /**
  167. * {@inheritdoc}
  168. */
  169. public function getViolations()
  170. {
  171. return $this->globalContext->getViolations();
  172. }
  173. /**
  174. * {@inheritdoc}
  175. */
  176. public function getRoot()
  177. {
  178. return $this->globalContext->getRoot();
  179. }
  180. /**
  181. * {@inheritdoc}
  182. */
  183. public function getPropertyPath($subPath = '')
  184. {
  185. if ('' != $subPath && '' !== $this->propertyPath && '[' !== $subPath[0]) {
  186. return $this->propertyPath . '.' . $subPath;
  187. }
  188. return $this->propertyPath . $subPath;
  189. }
  190. /**
  191. * {@inheritdoc}
  192. */
  193. public function getClassName()
  194. {
  195. if ($this->metadata instanceof ClassBasedInterface) {
  196. return $this->metadata->getClassName();
  197. }
  198. return null;
  199. }
  200. /**
  201. * {@inheritdoc}
  202. */
  203. public function getPropertyName()
  204. {
  205. if ($this->metadata instanceof PropertyMetadataInterface) {
  206. return $this->metadata->getPropertyName();
  207. }
  208. return null;
  209. }
  210. /**
  211. * {@inheritdoc}
  212. */
  213. public function getValue()
  214. {
  215. return $this->value;
  216. }
  217. /**
  218. * {@inheritdoc}
  219. */
  220. public function getGroup()
  221. {
  222. return $this->group;
  223. }
  224. /**
  225. * {@inheritdoc}
  226. */
  227. public function getMetadata()
  228. {
  229. return $this->metadata;
  230. }
  231. /**
  232. * {@inheritdoc}
  233. */
  234. public function getMetadataFor($value)
  235. {
  236. return $this->globalContext->getMetadataFactory()->getMetadataFor($value);
  237. }
  238. /**
  239. * {@inheritdoc}
  240. */
  241. public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false)
  242. {
  243. $propertyPath = $this->getPropertyPath($subPath);
  244. foreach ($this->resolveGroups($groups) as $group) {
  245. $this->globalContext->getVisitor()->validate($value, $group, $propertyPath, $traverse, $deep);
  246. }
  247. }
  248. /**
  249. * {@inheritdoc}
  250. */
  251. public function validateValue($value, $constraints, $subPath = '', $groups = null)
  252. {
  253. $constraints = is_array($constraints) ? $constraints : array($constraints);
  254. if (null === $groups && '' === $subPath) {
  255. $context = clone $this;
  256. $context->value = $value;
  257. $context->executeConstraintValidators($value, $constraints);
  258. return;
  259. }
  260. $propertyPath = $this->getPropertyPath($subPath);
  261. foreach ($this->resolveGroups($groups) as $group) {
  262. $context = clone $this;
  263. $context->value = $value;
  264. $context->group = $group;
  265. $context->propertyPath = $propertyPath;
  266. $context->executeConstraintValidators($value, $constraints);
  267. }
  268. }
  269. /**
  270. * Returns the class name of the current node.
  271. *
  272. * @return string|null The class name or null, if the current node does not
  273. * hold information about a class.
  274. *
  275. * @see getClassName
  276. *
  277. * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
  278. * {@link getClassName} instead.
  279. */
  280. public function getCurrentClass()
  281. {
  282. trigger_error('getCurrentClass() is deprecated since version 2.2 and will be removed in 2.3. Use getClassName() instead', E_USER_DEPRECATED);
  283. return $this->getClassName();
  284. }
  285. /**
  286. * Returns the property name of the current node.
  287. *
  288. * @return string|null The property name or null, if the current node does
  289. * not hold information about a property.
  290. *
  291. * @see getPropertyName
  292. *
  293. * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
  294. * {@link getClassName} instead.
  295. */
  296. public function getCurrentProperty()
  297. {
  298. trigger_error('getCurrentProperty() is deprecated since version 2.2 and will be removed in 2.3. Use getClassName() instead', E_USER_DEPRECATED);
  299. return $this->getPropertyName();
  300. }
  301. /**
  302. * Returns the currently validated value.
  303. *
  304. * @return mixed The current value.
  305. *
  306. * @see getValue
  307. *
  308. * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
  309. * {@link getValue} instead.
  310. */
  311. public function getCurrentValue()
  312. {
  313. trigger_error('getCurrentValue() is deprecated since version 2.2 and will be removed in 2.3. Use getValue() instead', E_USER_DEPRECATED);
  314. return $this->value;
  315. }
  316. /**
  317. * Returns the graph walker instance.
  318. *
  319. * @return GraphWalker The graph walker.
  320. *
  321. * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
  322. * {@link validate} and {@link validateValue} instead.
  323. */
  324. public function getGraphWalker()
  325. {
  326. trigger_error('getGraphWalker() is deprecated since version 2.2 and will be removed in 2.3. Use validate() and validateValue() instead', E_USER_DEPRECATED);
  327. return $this->globalContext->getVisitor()->getGraphWalker();
  328. }
  329. /**
  330. * {@inheritdoc}
  331. */
  332. public function getMetadataFactory()
  333. {
  334. return $this->globalContext->getMetadataFactory();
  335. }
  336. /**
  337. * Executes the validators of the given constraints for the given value.
  338. *
  339. * @param mixed $value The value to validate.
  340. * @param Constraint[] $constraints The constraints to match against.
  341. */
  342. private function executeConstraintValidators($value, array $constraints)
  343. {
  344. foreach ($constraints as $constraint) {
  345. $validator = $this->globalContext->getValidatorFactory()->getInstance($constraint);
  346. $validator->initialize($this);
  347. $validator->validate($value, $constraint);
  348. }
  349. }
  350. /**
  351. * Returns an array of group names.
  352. *
  353. * @param null|string|string[] $groups The groups to resolve. If a single string is
  354. * passed, it is converted to an array. If null
  355. * is passed, an array containing the current
  356. * group of the context is returned.
  357. *
  358. * @return array An array of validation groups.
  359. */
  360. private function resolveGroups($groups)
  361. {
  362. return $groups ? (array) $groups : (array) $this->group;
  363. }
  364. }