Length.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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 Countable as CountableInterface;
  9. use Respect\Validation\Exceptions\ComponentException;
  10. use function count;
  11. use function get_object_vars;
  12. use function is_array;
  13. use function is_int;
  14. use function is_object;
  15. use function is_string;
  16. use function mb_strlen;
  17. use function sprintf;
  18. /**
  19. * Validates the length of the given input.
  20. *
  21. * @author Alexandre Gomes Gaigalas <alganet@gmail.com>
  22. * @author Blake Hair <blake.hair@gmail.com>
  23. * @author Danilo Correa <danilosilva87@gmail.com>
  24. * @author Henrique Moody <henriquemoody@gmail.com>
  25. * @author Hugo Hamon <hugo.hamon@sensiolabs.com>
  26. * @author João Torquato <joao.otl@gmail.com>
  27. * @author Marcelo Araujo <msaraujo@php.net>
  28. */
  29. final class Length extends AbstractRule
  30. {
  31. /**
  32. * @var int|null
  33. */
  34. private $minValue;
  35. /**
  36. * @var int|null
  37. */
  38. private $maxValue;
  39. /**
  40. * @var bool
  41. */
  42. private $inclusive;
  43. /**
  44. * Creates the rule with a minimum and maximum value.
  45. *
  46. * @throws ComponentException
  47. */
  48. public function __construct(?int $min = null, ?int $max = null, bool $inclusive = true)
  49. {
  50. $this->minValue = $min;
  51. $this->maxValue = $max;
  52. $this->inclusive = $inclusive;
  53. if ($max !== null && $min > $max) {
  54. throw new ComponentException(sprintf('%d cannot be less than %d for validation', $min, $max));
  55. }
  56. }
  57. /**
  58. * {@inheritDoc}
  59. */
  60. public function validate($input): bool
  61. {
  62. $length = $this->extractLength($input);
  63. if ($length === null) {
  64. return false;
  65. }
  66. return $this->validateMin($length) && $this->validateMax($length);
  67. }
  68. /**
  69. * @param mixed $input
  70. */
  71. private function extractLength($input): ?int
  72. {
  73. if (is_string($input)) {
  74. return (int) mb_strlen($input);
  75. }
  76. if (is_array($input) || $input instanceof CountableInterface) {
  77. return count($input);
  78. }
  79. if (is_object($input)) {
  80. return $this->extractLength(get_object_vars($input));
  81. }
  82. if (is_int($input)) {
  83. return $this->extractLength((string) $input);
  84. }
  85. return null;
  86. }
  87. private function validateMin(int $length): bool
  88. {
  89. if ($this->minValue === null) {
  90. return true;
  91. }
  92. if ($this->inclusive) {
  93. return $length >= $this->minValue;
  94. }
  95. return $length > $this->minValue;
  96. }
  97. private function validateMax(int $length): bool
  98. {
  99. if ($this->maxValue === null) {
  100. return true;
  101. }
  102. if ($this->inclusive) {
  103. return $length <= $this->maxValue;
  104. }
  105. return $length < $this->maxValue;
  106. }
  107. }