Size.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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 Psr\Http\Message\StreamInterface;
  9. use Psr\Http\Message\UploadedFileInterface;
  10. use Respect\Validation\Exceptions\ComponentException;
  11. use SplFileInfo;
  12. use function filesize;
  13. use function floatval;
  14. use function is_numeric;
  15. use function is_string;
  16. use function preg_match;
  17. use function sprintf;
  18. /**
  19. * Validates whether the input is a file that is of a certain size or not.
  20. *
  21. * @author Danilo Correa <danilosilva87@gmail.com>
  22. * @author Henrique Moody <henriquemoody@gmail.com>
  23. * @author Felipe Stival <v0idpwn@gmail.com>
  24. */
  25. final class Size extends AbstractRule
  26. {
  27. /**
  28. * @var string|int|null
  29. */
  30. private $minSize;
  31. /**
  32. * @var float|null
  33. */
  34. private $minValue;
  35. /**
  36. * @var string|int|null
  37. */
  38. private $maxSize;
  39. /**
  40. * @var float|null
  41. */
  42. private $maxValue;
  43. /**
  44. * @param string|int|null $minSize
  45. * @param string|int|null $maxSize
  46. */
  47. public function __construct($minSize = null, $maxSize = null)
  48. {
  49. $this->minSize = $minSize;
  50. $this->minValue = $minSize ? $this->toBytes((string) $minSize) : null;
  51. $this->maxSize = $maxSize;
  52. $this->maxValue = $maxSize ? $this->toBytes((string) $maxSize) : null;
  53. }
  54. /**
  55. * {@inheritDoc}
  56. */
  57. public function validate($input): bool
  58. {
  59. if ($input instanceof SplFileInfo) {
  60. return $this->isValidSize((float) $input->getSize());
  61. }
  62. if ($input instanceof UploadedFileInterface) {
  63. return $this->isValidSize((float) $input->getSize());
  64. }
  65. if ($input instanceof StreamInterface) {
  66. return $this->isValidSize((float) $input->getSize());
  67. }
  68. if (is_string($input)) {
  69. return $this->isValidSize((float) filesize($input));
  70. }
  71. return false;
  72. }
  73. /**
  74. * @todo Move it to a trait
  75. *
  76. */
  77. private function toBytes(string $size): float
  78. {
  79. $value = $size;
  80. $units = ['b', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb', 'zb', 'yb'];
  81. foreach ($units as $exponent => $unit) {
  82. if (!preg_match('/^(\d+(.\d+)?)' . $unit . '$/i', $size, $matches)) {
  83. continue;
  84. }
  85. $value = floatval($matches[1]) * 1024 ** $exponent;
  86. break;
  87. }
  88. if (!is_numeric($value)) {
  89. throw new ComponentException(sprintf('"%s" is not a recognized file size.', $size));
  90. }
  91. return (float) $value;
  92. }
  93. private function isValidSize(float $size): bool
  94. {
  95. if ($this->minValue !== null && $this->maxValue !== null) {
  96. return $size >= $this->minValue && $size <= $this->maxValue;
  97. }
  98. if ($this->minValue !== null) {
  99. return $size >= $this->minValue;
  100. }
  101. return $size <= $this->maxValue;
  102. }
  103. }