dimtrovich /
validation
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * This file is part of Dimtrovich/Validation. |
||
| 5 | * |
||
| 6 | * (c) 2023 Dimitri Sitchet Tomkeu <[email protected]> |
||
| 7 | * |
||
| 8 | * For the full copyright and license information, please view |
||
| 9 | * the LICENSE file that was distributed with this source code. |
||
| 10 | */ |
||
| 11 | |||
| 12 | namespace Dimtrovich\Validation\Rules; |
||
| 13 | |||
| 14 | use BlitzPHP\Filesystem\Files\UploadedFile; |
||
| 15 | use Dimtrovich\Validation\Traits\FileTrait; |
||
| 16 | |||
| 17 | class Dimensions extends AbstractRule |
||
| 18 | { |
||
| 19 | use FileTrait; |
||
| 20 | |||
| 21 | /** |
||
| 22 | * @var array |
||
| 23 | */ |
||
| 24 | protected $fillableParams = ['dimensions']; |
||
| 25 | |||
| 26 | /** |
||
| 27 | * {@inheritDoc} |
||
| 28 | */ |
||
| 29 | public function check($value): bool |
||
| 30 | { |
||
| 31 | if ($this->isValidFileInstance($value) |
||
| 32 | && in_array($value->getMimeType(), ['image/svg+xml', 'image/svg'], true)) { |
||
| 33 | 2 | return true; |
|
| 34 | } |
||
| 35 | |||
| 36 | 2 | $this->requireParameters($this->fillableParams); |
|
| 37 | |||
| 38 | if ($this->isValueFromUploadedFiles($value)) { |
||
| 39 | $value = new UploadedFile( |
||
| 40 | $value['tmp_name'], |
||
| 41 | (int) $value['size'], |
||
| 42 | $value['error'], |
||
| 43 | $value['name'] ?? null, |
||
| 44 | $value['type'] ?? null |
||
| 45 | 2 | ); |
|
| 46 | } |
||
| 47 | |||
| 48 | if (! $this->isValidFileInstance($value)) { |
||
| 49 | 2 | return false; |
|
| 50 | } |
||
| 51 | |||
| 52 | $dimensions = method_exists($value, 'dimensions') |
||
| 53 | ? $value->dimensions() |
||
| 54 | 2 | : @getimagesize($value->realPath()); |
|
| 55 | |||
| 56 | if (! $dimensions) { |
||
| 57 | 2 | return false; |
|
| 58 | } |
||
| 59 | |||
| 60 | 2 | [$width, $height] = $dimensions; |
|
| 61 | |||
| 62 | 2 | $parameters = $this->parseNamedParameters($this->params); |
|
| 63 | |||
| 64 | return ! ($this->failsBasicDimensionChecks($parameters, $width, $height) |
||
| 65 | 2 | || $this->failsRatioCheck($parameters, $width, $height)); |
|
| 66 | } |
||
| 67 | |||
| 68 | /** |
||
| 69 | * Test if the given width and height fail any conditions. |
||
| 70 | * |
||
| 71 | * @param array<string,string> $parameters |
||
| 72 | */ |
||
| 73 | protected function failsBasicDimensionChecks(array $parameters, int $width, int $height): bool |
||
| 74 | { |
||
| 75 | 2 | $parameters = array_map(fn ($v) => (int) $v, $parameters); |
|
| 76 | |||
| 77 | return (isset($parameters['width']) && $parameters['width'] !== $width) |
||
| 78 | || (isset($parameters['min_width']) && $parameters['min_width'] > $width) |
||
| 79 | || (isset($parameters['max_width']) && $parameters['max_width'] < $width) |
||
| 80 | || (isset($parameters['height']) && $parameters['height'] !== $height) |
||
| 81 | || (isset($parameters['min_height']) && $parameters['min_height'] > $height) |
||
| 82 | 2 | || (isset($parameters['max_height']) && $parameters['max_height'] < $height); |
|
| 83 | } |
||
| 84 | |||
| 85 | /** |
||
| 86 | * Determine if the given parameters fail a dimension ratio check. |
||
| 87 | * |
||
| 88 | * @param array<string,string> $parameters |
||
| 89 | */ |
||
| 90 | protected function failsRatioCheck(array $parameters, int $width, int $height): bool |
||
| 91 | { |
||
| 92 | if (! isset($parameters['ratio'])) { |
||
| 93 | 2 | return false; |
|
| 94 | } |
||
| 95 | |||
| 96 | [$numerator, $denominator] = array_replace( |
||
| 97 | [1, 1], |
||
| 98 | array_filter(sscanf($parameters['ratio'], '%f/%d')) |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 99 | 2 | ); |
|
| 100 | |||
| 101 | 2 | $precision = 1 / (max($width, $height) + 1); |
|
| 102 | |||
| 103 | 2 | return abs($numerator / $denominator - $width / $height) > $precision; |
|
| 104 | } |
||
| 105 | } |
||
| 106 |