CallbackValidator.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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\Constraints;
  11. use Symfony\Component\Validator\Constraint;
  12. use Symfony\Component\Validator\ConstraintValidator;
  13. use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
  14. use Symfony\Component\Validator\Exception\UnexpectedTypeException;
  15. /**
  16. * Validator for Callback constraint.
  17. *
  18. * @author Bernhard Schussek <bschussek@gmail.com>
  19. */
  20. class CallbackValidator extends ConstraintValidator
  21. {
  22. /**
  23. * {@inheritdoc}
  24. */
  25. public function validate($object, Constraint $constraint)
  26. {
  27. if (!$constraint instanceof Callback) {
  28. throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Callback');
  29. }
  30. if (null !== $constraint->callback && null !== $constraint->methods) {
  31. throw new ConstraintDefinitionException('The Callback constraint supports either the option "callback" or "methods", but not both at the same time.');
  32. }
  33. // has to be an array so that we can differentiate between callables
  34. // and method names
  35. if (null !== $constraint->methods && !\is_array($constraint->methods)) {
  36. throw new UnexpectedTypeException($constraint->methods, 'array');
  37. }
  38. $methods = $constraint->methods ?: array($constraint->callback);
  39. foreach ($methods as $method) {
  40. if ($method instanceof \Closure) {
  41. $method($object, $this->context);
  42. } elseif (\is_array($method)) {
  43. if (!\is_callable($method)) {
  44. if (isset($method[0]) && \is_object($method[0])) {
  45. $method[0] = \get_class($method[0]);
  46. }
  47. throw new ConstraintDefinitionException(sprintf('%s targeted by Callback constraint is not a valid callable', json_encode($method)));
  48. }
  49. \call_user_func($method, $object, $this->context);
  50. } elseif (null !== $object) {
  51. if (!method_exists($object, $method)) {
  52. throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist in class %s', $method, \get_class($object)));
  53. }
  54. $reflMethod = new \ReflectionMethod($object, $method);
  55. if ($reflMethod->isStatic()) {
  56. $reflMethod->invoke(null, $object, $this->context);
  57. } else {
  58. $reflMethod->invoke($object, $this->context);
  59. }
  60. }
  61. }
  62. }
  63. }