Completed
Push — master ( 458234...a0327e )
by Adrian
01:39
created

RuleHelper   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 29
lcom 1
cbo 0
dl 0
loc 159
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
B normalizeOptions() 0 31 11
A parseHttpQueryString() 0 6 1
A convertBooleanStrings() 0 14 4
B parseCsvString() 0 22 6
A arrayIsAssoc() 0 4 1
A normalizeFileSize() 0 14 2
A normalizeImageRatio() 0 13 4
1
<?php
2
declare(strict_types=1);
3
4
namespace Sirius\Validation\Util;
5
6
class RuleHelper
7
{
8
    /**
9
     * Method that parses the option variable and converts it into an array
10
     * You can pass anything to a validator like:
11
     * - a query string: 'min=3&max=5'
12
     * - a JSON string: '{"min":3,"max":5}'
13
     * - a CSV string: '5,true' (for this scenario the 'optionsIndexMap' property is required)
14
     *
15
     * @param mixed $options
16
     *
17
     * @return array
18
     * @throws \InvalidArgumentException
19
     */
20
    public static function normalizeOptions($options, array $optionsIndexMap = [])
21
    {
22
        if ('0' === $options && count($optionsIndexMap) > 0) {
23
            $options = [$optionsIndexMap[0] => '0'];
24
        }
25
        if (! $options) {
26
            return [];
27
        }
28
29
        if (is_array($options) && static::arrayIsAssoc($options)) {
30
            return $options;
31
        }
32
33
        $result = $options;
34
        if ($options && is_string($options)) {
35
            $startChar = substr($options, 0, 1);
36
            if ($startChar == '{') {
37
                $result = json_decode($options, true);
38
            } elseif (strpos($options, '=') !== false) {
39
                $result = static::parseHttpQueryString($options);
40
            } else {
41
                $result = static::parseCsvString($options, $optionsIndexMap);
42
            }
43
        }
44
45
        if (! is_array($result)) {
46
            throw new \InvalidArgumentException('Validator options should be an array, JSON string or query string');
47
        }
48
49
        return $result;
50
    }
51
52
    /**
53
     * Converts a HTTP query string to an array
54
     *
55
     * @param $str
56
     *
57
     * @return array
58
     */
59
    public static function parseHttpQueryString(string $str)
60
    {
61
        parse_str($str, $arr);
62
63
        return static::convertBooleanStrings($arr);
64
    }
65
66
    /**
67
     * Converts 'true' and 'false' strings to TRUE and FALSE
68
     *
69
     * @param $arr
70
     *
71
     * @return bool|array
72
     */
73
    public static function convertBooleanStrings($arr)
74
    {
75
        if (is_array($arr)) {
76
            return array_map([ __CLASS__, 'convertBooleanStrings'], $arr);
77
        }
78
        if ($arr === 'true') {
79
            return true;
80
        }
81
        if ($arr === 'false') {
82
            return false;
83
        }
84
85
        return $arr;
86
    }
87
88
89
    /**
90
     * Parses a CSV string and converts the result into an "options" array
91
     * (an associative array that contains the options for the validation rule)
92
     *
93
     * @param $str
94
     *
95
     * @param array $optionsIndexMap
96
     *
97
     * @return array
98
     */
99
    public static function parseCsvString($str, array $optionsIndexMap = [])
100
    {
101
        if (! isset($optionsIndexMap) || ! is_array($optionsIndexMap) || empty($optionsIndexMap)) {
102
            throw new \InvalidArgumentException(
103
                '`$optionsIndexMap` argument must be provided for CSV-type parameters'
104
            );
105
        }
106
107
        $options = explode(',', $str);
108
        $result  = [];
109
        foreach ($options as $k => $v) {
110
            if (! isset($optionsIndexMap[$k])) {
111
                throw new \InvalidArgumentException(sprintf(
112
                    '`$optionsIndexMap` for the validator is missing the %s index',
113
                    $k
114
                ));
115
            }
116
            $result[$optionsIndexMap[$k]] = $v;
117
        }
118
119
        return static::convertBooleanStrings($result);
120
    }
121
122
    /**
123
     * Checks if an array is associative (ie: the keys are not numbers in sequence)
124
     *
125
     * @param array $arr
126
     *
127
     * @return bool
128
     */
129
    public static function arrayIsAssoc($arr)
130
    {
131
        return array_keys($arr) !== range(0, count($arr));
132
    }
133
134
    public static function normalizeFileSize($size)
135
    {
136
        $size = (string) $size;
137
        $units = ['B' => 0, 'K' => 1, 'M' => 2, 'G' => 3 ];
138
        $unit  = strtoupper(substr($size, strlen($size) - 1, 1));
139
        if (! isset($units[$unit])) {
140
            $normalizedSize = filter_var($size, FILTER_SANITIZE_NUMBER_INT);
141
        } else {
142
            $size           = filter_var(substr($size, 0, strlen($size) - 1), FILTER_SANITIZE_NUMBER_FLOAT);
143
            $normalizedSize = $size * pow(1024, $units[$unit]);
144
        }
145
146
        return $normalizedSize;
147
    }
148
149
150
151
    public static function normalizeImageRatio($ratio)
152
    {
153
        if (is_numeric($ratio) || $ratio == filter_var($ratio, FILTER_SANITIZE_NUMBER_FLOAT)) {
154
            return floatval($ratio);
155
        }
156
        if (strpos($ratio, ':') !== false) {
157
            list($width, $height) = explode(':', $ratio);
158
159
            return $width / $height;
160
        }
161
162
        return 0;
163
    }
164
}
165