Issues (88)

src/Rules/Dimensions.php (1 issue)

Labels
Severity
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
It seems like sscanf($parameters['ratio'], '%f/%d') can also be of type integer and null; however, parameter $array of array_filter() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

98
            array_filter(/** @scrutinizer ignore-type */ sscanf($parameters['ratio'], '%f/%d'))
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