PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php

https://gitlab.com/Marwamimo/Crowdrise_Web
PHP | 204 lines | 117 code | 30 blank | 57 comment | 26 complexity | 6d4f5b206e915869287699fb91f1b088 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\Form\Extension\Validator\Constraints;
  11. use Symfony\Component\Form\FormInterface;
  12. use Symfony\Component\Validator\Constraint;
  13. use Symfony\Component\Validator\ConstraintValidator;
  14. use Symfony\Component\Validator\Context\ExecutionContextInterface;
  15. use Symfony\Component\Validator\Exception\UnexpectedTypeException;
  16. /**
  17. * @author Bernhard Schussek <bschussek@gmail.com>
  18. */
  19. class FormValidator extends ConstraintValidator
  20. {
  21. /**
  22. * {@inheritdoc}
  23. */
  24. public function validate($form, Constraint $constraint)
  25. {
  26. if (!$constraint instanceof Form) {
  27. throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Form');
  28. }
  29. if (!$form instanceof FormInterface) {
  30. return;
  31. }
  32. /* @var FormInterface $form */
  33. $config = $form->getConfig();
  34. $validator = null;
  35. if ($this->context instanceof ExecutionContextInterface) {
  36. $validator = $this->context->getValidator()->inContext($this->context);
  37. }
  38. if ($form->isSynchronized()) {
  39. // Validate the form data only if transformation succeeded
  40. $groups = self::getValidationGroups($form);
  41. // Validate the data against its own constraints
  42. if (self::allowDataWalking($form)) {
  43. foreach ($groups as $group) {
  44. if ($validator) {
  45. $validator->atPath('data')->validate($form->getData(), null, $group);
  46. } else {
  47. // 2.4 API
  48. $this->context->validate($form->getData(), 'data', $group, true);
  49. }
  50. }
  51. }
  52. // Validate the data against the constraints defined
  53. // in the form
  54. $constraints = $config->getOption('constraints');
  55. foreach ($constraints as $constraint) {
  56. foreach ($groups as $group) {
  57. if (in_array($group, $constraint->groups)) {
  58. if ($validator) {
  59. $validator->atPath('data')->validate($form->getData(), $constraint, $group);
  60. } else {
  61. // 2.4 API
  62. $this->context->validateValue($form->getData(), $constraint, 'data', $group);
  63. }
  64. // Prevent duplicate validation
  65. continue 2;
  66. }
  67. }
  68. }
  69. } else {
  70. $childrenSynchronized = true;
  71. foreach ($form as $child) {
  72. if (!$child->isSynchronized()) {
  73. $childrenSynchronized = false;
  74. break;
  75. }
  76. }
  77. // Mark the form with an error if it is not synchronized BUT all
  78. // of its children are synchronized. If any child is not
  79. // synchronized, an error is displayed there already and showing
  80. // a second error in its parent form is pointless, or worse, may
  81. // lead to duplicate errors if error bubbling is enabled on the
  82. // child.
  83. // See also https://github.com/symfony/symfony/issues/4359
  84. if ($childrenSynchronized) {
  85. $clientDataAsString = is_scalar($form->getViewData())
  86. ? (string) $form->getViewData()
  87. : gettype($form->getViewData());
  88. $this->buildViolation($config->getOption('invalid_message'))
  89. ->setParameters(array_replace(array('{{ value }}' => $clientDataAsString), $config->getOption('invalid_message_parameters')))
  90. ->setInvalidValue($form->getViewData())
  91. ->setCode(Form::ERR_INVALID)
  92. ->addViolation();
  93. }
  94. }
  95. // Mark the form with an error if it contains extra fields
  96. if (count($form->getExtraData()) > 0) {
  97. $this->buildViolation($config->getOption('extra_fields_message'))
  98. ->setParameter('{{ extra_fields }}', implode('", "', array_keys($form->getExtraData())))
  99. ->setInvalidValue($form->getExtraData())
  100. ->addViolation();
  101. }
  102. }
  103. /**
  104. * Returns whether the data of a form may be walked.
  105. *
  106. * @param FormInterface $form The form to test.
  107. *
  108. * @return bool Whether the graph walker may walk the data.
  109. */
  110. private static function allowDataWalking(FormInterface $form)
  111. {
  112. $data = $form->getData();
  113. // Scalar values cannot have mapped constraints
  114. if (!is_object($data) && !is_array($data)) {
  115. return false;
  116. }
  117. // Root forms are always validated
  118. if ($form->isRoot()) {
  119. return true;
  120. }
  121. // Non-root forms are validated if validation cascading
  122. // is enabled in all ancestor forms
  123. while (null !== ($form = $form->getParent())) {
  124. if (!$form->getConfig()->getOption('cascade_validation')) {
  125. return false;
  126. }
  127. }
  128. return true;
  129. }
  130. /**
  131. * Returns the validation groups of the given form.
  132. *
  133. * @param FormInterface $form The form.
  134. *
  135. * @return array The validation groups.
  136. */
  137. private static function getValidationGroups(FormInterface $form)
  138. {
  139. // Determine the clicked button of the complete form tree
  140. $clickedButton = null;
  141. if (method_exists($form, 'getClickedButton')) {
  142. $clickedButton = $form->getClickedButton();
  143. }
  144. if (null !== $clickedButton) {
  145. $groups = $clickedButton->getConfig()->getOption('validation_groups');
  146. if (null !== $groups) {
  147. return self::resolveValidationGroups($groups, $form);
  148. }
  149. }
  150. do {
  151. $groups = $form->getConfig()->getOption('validation_groups');
  152. if (null !== $groups) {
  153. return self::resolveValidationGroups($groups, $form);
  154. }
  155. $form = $form->getParent();
  156. } while (null !== $form);
  157. return array(Constraint::DEFAULT_GROUP);
  158. }
  159. /**
  160. * Post-processes the validation groups option for a given form.
  161. *
  162. * @param array|callable $groups The validation groups.
  163. * @param FormInterface $form The validated form.
  164. *
  165. * @return array The validation groups.
  166. */
  167. private static function resolveValidationGroups($groups, FormInterface $form)
  168. {
  169. if (!is_string($groups) && is_callable($groups)) {
  170. $groups = call_user_func($groups, $form);
  171. }
  172. return (array) $groups;
  173. }
  174. }