AbstractRelated.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. /*
  3. * Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
  4. * SPDX-License-Identifier: MIT
  5. */
  6. declare(strict_types=1);
  7. namespace Respect\Validation\Rules;
  8. use Respect\Validation\Exceptions\NestedValidationException;
  9. use Respect\Validation\Exceptions\ValidationException;
  10. use Respect\Validation\Validatable;
  11. use function is_scalar;
  12. /**
  13. * @author Alexandre Gomes Gaigalas <alganet@gmail.com>
  14. * @author Emmerson Siqueira <emmersonsiqueira@gmail.com>
  15. * @author Henrique Moody <henriquemoody@gmail.com>
  16. * @author Nick Lombard <github@jigsoft.co.za>
  17. */
  18. abstract class AbstractRelated extends AbstractRule
  19. {
  20. /**
  21. * @var bool
  22. */
  23. private $mandatory = true;
  24. /**
  25. * @var mixed
  26. */
  27. private $reference;
  28. /**
  29. * @var Validatable|null
  30. */
  31. private $rule;
  32. /**
  33. * @param mixed $input
  34. */
  35. abstract public function hasReference($input): bool;
  36. /**
  37. * @param mixed $input
  38. *
  39. * @return mixed
  40. */
  41. abstract public function getReferenceValue($input);
  42. /**
  43. * @param mixed $reference
  44. */
  45. public function __construct($reference, ?Validatable $rule = null, bool $mandatory = true)
  46. {
  47. $this->reference = $reference;
  48. $this->rule = $rule;
  49. $this->mandatory = $mandatory;
  50. if ($rule && $rule->getName() !== null) {
  51. $this->setName($rule->getName());
  52. } elseif (is_scalar($reference)) {
  53. $this->setName((string) $reference);
  54. }
  55. }
  56. /**
  57. * @return mixed
  58. */
  59. public function getReference()
  60. {
  61. return $this->reference;
  62. }
  63. public function isMandatory(): bool
  64. {
  65. return $this->mandatory;
  66. }
  67. /**
  68. * {@inheritDoc}
  69. */
  70. public function setName(string $name): Validatable
  71. {
  72. parent::setName($name);
  73. if ($this->rule instanceof Validatable) {
  74. $this->rule->setName($name);
  75. }
  76. return $this;
  77. }
  78. /**
  79. * {@inheritDoc}
  80. */
  81. public function assert($input): void
  82. {
  83. $hasReference = $this->hasReference($input);
  84. if ($this->mandatory && !$hasReference) {
  85. throw $this->reportError($input, ['hasReference' => false]);
  86. }
  87. if ($this->rule === null || !$hasReference) {
  88. return;
  89. }
  90. try {
  91. $this->rule->assert($this->getReferenceValue($input));
  92. } catch (ValidationException $validationException) {
  93. /** @var NestedValidationException $nestedValidationException */
  94. $nestedValidationException = $this->reportError($this->reference, ['hasReference' => true]);
  95. $nestedValidationException->addChild($validationException);
  96. throw $nestedValidationException;
  97. }
  98. }
  99. /**
  100. * {@inheritDoc}
  101. */
  102. public function check($input): void
  103. {
  104. $hasReference = $this->hasReference($input);
  105. if ($this->mandatory && !$hasReference) {
  106. throw $this->reportError($input, ['hasReference' => false]);
  107. }
  108. if ($this->rule === null || !$hasReference) {
  109. return;
  110. }
  111. $this->rule->check($this->getReferenceValue($input));
  112. }
  113. /**
  114. * {@inheritDoc}
  115. */
  116. public function validate($input): bool
  117. {
  118. $hasReference = $this->hasReference($input);
  119. if ($this->mandatory && !$hasReference) {
  120. return false;
  121. }
  122. if ($this->rule === null || !$hasReference) {
  123. return true;
  124. }
  125. return $this->rule->validate($this->getReferenceValue($input));
  126. }
  127. }