Test Setup Failed
Push — next ( 738e04...b06172 )
by Jonathan
25:05
created

ColorRepresentation::rgbToHsl()   C

Complexity

Conditions 8
Paths 11

Size

Total Lines 43
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 29
nc 11
nop 3
dl 0
loc 43
rs 5.3846
c 0
b 0
f 0
1
<?php
2
3
namespace Kint\Object\Representation;
4
5
use InvalidArgumentException;
6
7
class ColorRepresentation extends Representation
0 ignored issues
show
Coding Style introduced by
The property $implicit_label is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $color_map is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
8
{
9
    const COLOR_NAME = 1;
10
    const COLOR_HEX_3 = 2;
11
    const COLOR_HEX_6 = 3;
12
    const COLOR_RGB = 4;
13
    const COLOR_RGBA = 5;
14
    const COLOR_HSL = 6;
15
    const COLOR_HSLA = 7;
16
    const COLOR_HEX_4 = 8;
17
    const COLOR_HEX_8 = 9;
18
19
    public static $color_map = array(
0 ignored issues
show
Coding Style introduced by
$color_map does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
20
        'aliceblue' => 'f0f8ff',
21
        'antiquewhite' => 'faebd7',
22
        'aqua' => '00ffff',
23
        'aquamarine' => '7fffd4',
24
        'azure' => 'f0ffff',
25
        'beige' => 'f5f5dc',
26
        'bisque' => 'ffe4c4',
27
        'black' => '000000',
28
        'blanchedalmond' => 'ffebcd',
29
        'blue' => '0000ff',
30
        'blueviolet' => '8a2be2',
31
        'brown' => 'a52a2a',
32
        'burlywood' => 'deb887',
33
        'cadetblue' => '5f9ea0',
34
        'chartreuse' => '7fff00',
35
        'chocolate' => 'd2691e',
36
        'coral' => 'ff7f50',
37
        'cornflowerblue' => '6495ed',
38
        'cornsilk' => 'fff8dc',
39
        'crimson' => 'dc143c',
40
        'cyan' => '00ffff',
41
        'darkblue' => '00008b',
42
        'darkcyan' => '008b8b',
43
        'darkgoldenrod' => 'b8860b',
44
        'darkgray' => 'a9a9a9',
45
        'darkgreen' => '006400',
46
        'darkgrey' => 'a9a9a9',
47
        'darkkhaki' => 'bdb76b',
48
        'darkmagenta' => '8b008b',
49
        'darkolivegreen' => '556b2f',
50
        'darkorange' => 'ff8c00',
51
        'darkorchid' => '9932cc',
52
        'darkred' => '8b0000',
53
        'darksalmon' => 'e9967a',
54
        'darkseagreen' => '8fbc8f',
55
        'darkslateblue' => '483d8b',
56
        'darkslategray' => '2f4f4f',
57
        'darkslategrey' => '2f4f4f',
58
        'darkturquoise' => '00ced1',
59
        'darkviolet' => '9400d3',
60
        'deeppink' => 'ff1493',
61
        'deepskyblue' => '00bfff',
62
        'dimgray' => '696969',
63
        'dimgrey' => '696969',
64
        'dodgerblue' => '1e90ff',
65
        'firebrick' => 'b22222',
66
        'floralwhite' => 'fffaf0',
67
        'forestgreen' => '228b22',
68
        'fuchsia' => 'ff00ff',
69
        'gainsboro' => 'dcdcdc',
70
        'ghostwhite' => 'f8f8ff',
71
        'gold' => 'ffd700',
72
        'goldenrod' => 'daa520',
73
        'gray' => '808080',
74
        'green' => '008000',
75
        'greenyellow' => 'adff2f',
76
        'grey' => '808080',
77
        'honeydew' => 'f0fff0',
78
        'hotpink' => 'ff69b4',
79
        'indianred' => 'cd5c5c',
80
        'indigo' => '4b0082',
81
        'ivory' => 'fffff0',
82
        'khaki' => 'f0e68c',
83
        'lavender' => 'e6e6fa',
84
        'lavenderblush' => 'fff0f5',
85
        'lawngreen' => '7cfc00',
86
        'lemonchiffon' => 'fffacd',
87
        'lightblue' => 'add8e6',
88
        'lightcoral' => 'f08080',
89
        'lightcyan' => 'e0ffff',
90
        'lightgoldenrodyellow' => 'fafad2',
91
        'lightgray' => 'd3d3d3',
92
        'lightgreen' => '90ee90',
93
        'lightgrey' => 'd3d3d3',
94
        'lightpink' => 'ffb6c1',
95
        'lightsalmon' => 'ffa07a',
96
        'lightseagreen' => '20b2aa',
97
        'lightskyblue' => '87cefa',
98
        'lightslategray' => '778899',
99
        'lightslategrey' => '778899',
100
        'lightsteelblue' => 'b0c4de',
101
        'lightyellow' => 'ffffe0',
102
        'lime' => '00ff00',
103
        'limegreen' => '32cd32',
104
        'linen' => 'faf0e6',
105
        'magenta' => 'ff00ff',
106
        'maroon' => '800000',
107
        'mediumaquamarine' => '66cdaa',
108
        'mediumblue' => '0000cd',
109
        'mediumorchid' => 'ba55d3',
110
        'mediumpurple' => '9370db',
111
        'mediumseagreen' => '3cb371',
112
        'mediumslateblue' => '7b68ee',
113
        'mediumspringgreen' => '00fa9a',
114
        'mediumturquoise' => '48d1cc',
115
        'mediumvioletred' => 'c71585',
116
        'midnightblue' => '191970',
117
        'mintcream' => 'f5fffa',
118
        'mistyrose' => 'ffe4e1',
119
        'moccasin' => 'ffe4b5',
120
        'navajowhite' => 'ffdead',
121
        'navy' => '000080',
122
        'oldlace' => 'fdf5e6',
123
        'olive' => '808000',
124
        'olivedrab' => '6b8e23',
125
        'orange' => 'ffa500',
126
        'orangered' => 'ff4500',
127
        'orchid' => 'da70d6',
128
        'palegoldenrod' => 'eee8aa',
129
        'palegreen' => '98fb98',
130
        'paleturquoise' => 'afeeee',
131
        'palevioletred' => 'db7093',
132
        'papayawhip' => 'ffefd5',
133
        'peachpuff' => 'ffdab9',
134
        'peru' => 'cd853f',
135
        'pink' => 'ffc0cb',
136
        'plum' => 'dda0dd',
137
        'powderblue' => 'b0e0e6',
138
        'purple' => '800080',
139
        'rebeccapurple' => '663399',
140
        'red' => 'ff0000',
141
        'rosybrown' => 'bc8f8f',
142
        'royalblue' => '4169e1',
143
        'saddlebrown' => '8b4513',
144
        'salmon' => 'fa8072',
145
        'sandybrown' => 'f4a460',
146
        'seagreen' => '2e8b57',
147
        'seashell' => 'fff5ee',
148
        'sienna' => 'a0522d',
149
        'silver' => 'c0c0c0',
150
        'skyblue' => '87ceeb',
151
        'slateblue' => '6a5acd',
152
        'slategray' => '708090',
153
        'slategrey' => '708090',
154
        'snow' => 'fffafa',
155
        'springgreen' => '00ff7f',
156
        'steelblue' => '4682b4',
157
        'tan' => 'd2b48c',
158
        'teal' => '008080',
159
        'thistle' => 'd8bfd8',
160
        'tomato' => 'ff6347',
161
        // To quote MDN:
162
        // "Technically, transparent is a shortcut for rgba(0,0,0,0)."
163
        'transparent' => '00000000',
164
        'turquoise' => '40e0d0',
165
        'violet' => 'ee82ee',
166
        'wheat' => 'f5deb3',
167
        'white' => 'ffffff',
168
        'whitesmoke' => 'f5f5f5',
169
        'yellow' => 'ffff00',
170
        'yellowgreen' => '9acd32',
171
    );
172
173
    public $r = 0;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
174
    public $g = 0;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $g. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
175
    public $b = 0;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $b. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
176
    public $a = 1.0;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $a. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
177
    public $variant = null;
178
    public $implicit_label = true;
0 ignored issues
show
Coding Style introduced by
$implicit_label does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
179
    public $hints = array('color');
180
181
    public function getColor($variant = null)
182
    {
183
        if (!$variant) {
184
            $variant = $this->variant;
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $variant. This often makes code more readable.
Loading history...
185
        }
186
187
        switch ($variant) {
188
            case self::COLOR_NAME:
189
                $hex = sprintf('%02x%02x%02x', $this->r, $this->g, $this->b);
190
                $hex_alpha = sprintf('%02x%02x%02x%02x', $this->r, $this->g, $this->b, round($this->a * 0xFF));
0 ignored issues
show
Coding Style introduced by
$hex_alpha does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
191
192
                return array_search($hex, self::$color_map) ?: array_search($hex_alpha, self::$color_map);
0 ignored issues
show
Coding Style introduced by
$hex_alpha does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
193
           case self::COLOR_HEX_3:
194
                if ($this->r % 0x11 === 0 && $this->g % 0x11 === 0 && $this->b % 0x11 === 0) {
195
                    return sprintf(
196
                        '#%1X%1X%1X',
197
                        round($this->r / 0x11),
198
                        round($this->g / 0x11),
199
                        round($this->b / 0x11)
200
                    );
201
                } else {
202
                    return false;
203
                }
204
            case self::COLOR_HEX_6:
205
                return sprintf('#%02X%02X%02X', $this->r, $this->g, $this->b);
206
            case self::COLOR_RGB:
207
                if ($this->a === 1.0) {
208
                    return sprintf('rgb(%d, %d, %d)', $this->r, $this->g, $this->b);
209
                } else {
210
                    return sprintf('rgb(%d, %d, %d, %s)', $this->r, $this->g, $this->b, round($this->a, 4));
211
                }
212 View Code Duplication
            case self::COLOR_RGBA:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
213
                return sprintf('rgba(%d, %d, %d, %s)', $this->r, $this->g, $this->b, round($this->a, 4));
214
            case self::COLOR_HSL:
215
                $val = self::rgbToHsl($this->r, $this->g, $this->b);
216
                if ($this->a === 1.0) {
217
                    return vsprintf('hsl(%d, %d%%, %d%%)', $val);
218
                } else {
219
                    return sprintf('hsl(%d, %d%%, %d%%, %s)', $val[0], $val[1], $val[2], round($this->a, 4));
220
                }
221
            case self::COLOR_HSLA:
222
                $val = self::rgbToHsl($this->r, $this->g, $this->b);
223
224
                return sprintf('hsla(%d, %d%%, %d%%, %s)', $val[0], $val[1], $val[2], round($this->a, 4));
225
            case self::COLOR_HEX_4:
226
                if ($this->r % 0x11 === 0 && $this->g % 0x11 === 0 && $this->b % 0x11 === 0 && ($this->a * 255) % 0x11 === 0) {
227
                    return sprintf(
228
                        '#%1X%1X%1X%1X',
229
                        round($this->r / 0x11),
230
                        round($this->g / 0x11),
231
                        round($this->b / 0x11),
232
                        round($this->a * 0xF)
233
                    );
234
                } else {
235
                    return false;
236
                }
237 View Code Duplication
            case self::COLOR_HEX_8:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
238
                return sprintf('#%02X%02X%02X%02X', $this->r, $this->g, $this->b, round($this->a * 0xFF));
239
        }
240
241
        return false;
242
    }
243
244
    public function __construct($value)
245
    {
246
        parent::__construct('Color');
247
248
        $this->contents = $value;
249
        $this->setValues($value);
250
    }
251
252
    public function hasAlpha($variant = null)
253
    {
254
        if ($variant === null) {
255
            $variant = $this->variant;
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $variant. This often makes code more readable.
Loading history...
256
        }
257
258
        switch ($variant) {
259
            case self::COLOR_NAME:
260
            case self::COLOR_RGB:
261
            case self::COLOR_HSL:
262
                return abs($this->a - 1) >= 0.0001;
263
            case self::COLOR_RGBA:
264
            case self::COLOR_HSLA:
265
            case self::COLOR_HEX_4:
266
            case self::COLOR_HEX_8:
267
                return true;
268
            default:
269
                return false;
270
        }
271
    }
272
273
    protected function setValues($value)
274
    {
275
        $value = strtolower(trim($value));
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $value. This often makes code more readable.
Loading history...
276
        // Find out which variant of color input it is
277
        if (isset(self::$color_map[$value])) {
278
            $variant = self::COLOR_NAME;
279
        } elseif ($value[0] === '#') {
280
            $value = substr($value, 1);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $value. This often makes code more readable.
Loading history...
281
282
            if (dechex(hexdec($value)) !== $value) {
283
                return;
284
            }
285
286
            switch (strlen($value)) {
287
                case 3:
288
                    $variant = self::COLOR_HEX_3;
289
                    break;
290
                case 6:
291
                    $variant = self::COLOR_HEX_6;
292
                    break;
293
                case 4:
294
                    $variant = self::COLOR_HEX_4;
295
                    break;
296
                case 8:
297
                    $variant = self::COLOR_HEX_8;
298
                    break;
299
                default:
300
                    return;
301
            }
302
        } else {
303
            if (!preg_match('/^((?:rgb|hsl)a?)\s*\(([0-9\.%,\s\/\-]+)\)$/i', $value, $match)) {
304
                return;
305
            }
306
307
            switch (strtolower($match[1])) {
308
                case 'rgb':
309
                    $variant = self::COLOR_RGB;
310
                    break;
311
                case 'rgba':
312
                    $variant = self::COLOR_RGBA;
313
                    break;
314
                case 'hsl':
315
                    $variant = self::COLOR_HSL;
316
                    break;
317
                case 'hsla':
318
                    $variant = self::COLOR_HSLA;
319
                    break;
320
            }
321
322
            $value = preg_replace('/[,\s\/]+/', ',', trim($match[2]));
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $value. This often makes code more readable.
Loading history...
323
            $value = explode(',', $value);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $value. This often makes code more readable.
Loading history...
324
325
            if (count($value) < 3 || count($value) > 4) {
326
                return;
327
            }
328
329
            foreach ($value as $i => &$color) {
330
                $color = trim($color);
331
332
                if (strpos($color, '%') !== false) {
333
                    $color = str_replace('%', '', $color);
334
335
                    if ($i === 3) {
336
                        $color = $color / 100;
337
                    } elseif (in_array($variant, array(self::COLOR_RGB, self::COLOR_RGBA))) {
0 ignored issues
show
Bug introduced by
The variable $variant does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
338
                        $color = round($color / 100 * 0xFF);
339
                    }
340
                }
341
342
                if ($i === 0 && in_array($variant, array(self::COLOR_HSL, self::COLOR_HSLA))) {
343
                    $color = ($color % 360 + 360) % 360;
344
                }
345
            }
346
        }
347
348
        // Assign the correct properties based on the variant
349
        switch ($variant) {
350
            case self::COLOR_HEX_4:
351
                $this->a = hexdec($value[3]) / 0xF;
352
                // Fallthrough
353
            case self::COLOR_HEX_3:
354
                $this->r = hexdec($value[0]) * 0x11;
0 ignored issues
show
Documentation Bug introduced by
It seems like hexdec($value[0]) * 17 can also be of type double. However, the property $r is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
355
                $this->g = hexdec($value[1]) * 0x11;
0 ignored issues
show
Documentation Bug introduced by
It seems like hexdec($value[1]) * 17 can also be of type double. However, the property $g is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
356
                $this->b = hexdec($value[2]) * 0x11;
0 ignored issues
show
Documentation Bug introduced by
It seems like hexdec($value[2]) * 17 can also be of type double. However, the property $b is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
357
                break;
358
            case self::COLOR_NAME:
359
                $value = self::$color_map[$value].'FF';
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $value. This often makes code more readable.
Loading history...
360
               // Fallthrough
361
            case self::COLOR_HEX_8:
362
                $this->a = hexdec(substr($value, 6, 2)) / 0xFF;
363
                // Fallthrough
364
            case self::COLOR_HEX_6:
365
                $value = str_split($value, 2);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $value. This often makes code more readable.
Loading history...
366
                $this->r = hexdec($value[0]);
0 ignored issues
show
Documentation Bug introduced by
It seems like hexdec($value[0]) can also be of type double. However, the property $r is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
367
                $this->g = hexdec($value[1]);
0 ignored issues
show
Documentation Bug introduced by
It seems like hexdec($value[1]) can also be of type double. However, the property $g is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
368
                $this->b = hexdec($value[2]);
0 ignored issues
show
Documentation Bug introduced by
It seems like hexdec($value[2]) can also be of type double. However, the property $b is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
369
                break;
370
            case self::COLOR_RGBA:
371
            case self::COLOR_RGB:
372
                if (min($value) < 0 || max($value) > 0xFF) {
373
                    return;
374
                }
375
376 View Code Duplication
                if (count($value) === 4) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
377
                    if ($value[3] > 1) {
378
                        return;
379
                    }
380
381
                    $this->a = $value[3];
382
                }
383
384
                list($this->r, $this->g, $this->b) = $value;
385
                break;
386
            case self::COLOR_HSLA:
387
            case self::COLOR_HSL:
388
                if (min($value) < 0 || $value[0] > 360 || max($value[1], $value[2]) > 100) {
389
                    return;
390
                }
391
392 View Code Duplication
                if (count($value) === 4) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
393
                    if ($value[3] > 1) {
394
                        return;
395
                    }
396
397
                    $this->a = $value[3];
398
                }
399
400
                $value = self::hslToRgb($value[0], $value[1], $value[2]);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $value. This often makes code more readable.
Loading history...
401
                list($this->r, $this->g, $this->b) = $value;
402
                break;
403
        }
404
405
        // If something has gone horribly wrong
406
        if ($this->r > 0xFF || $this->g > 0xFF || $this->b > 0xFF || $this->a > 1) {
407
            $this->variant = null; // @codeCoverageIgnore
408
        } else {
409
            $this->variant = $variant;
410
            $this->r = (int) $this->r;
411
            $this->g = (int) $this->g;
412
            $this->b = (int) $this->b;
413
            $this->a = (float) $this->a;
414
        }
415
    }
416
417
    /**
418
     * Turns HSL color to RGB. Black magic.
419
     *
420
     * @param float $h Hue
421
     * @param float $s Saturation
422
     * @param float $l Lightness
423
     *
424
     * @return int[] RGB array
425
     */
426
    public static function hslToRgb($h, $s, $l)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $h. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $s. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $l. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
427
    {
428
        if (min($h, $s, $l) < 0) {
429
            throw new InvalidArgumentException('The parameters for hslToRgb should be no less than 0');
430
        } elseif ($h > 360 || max($s, $l) > 100) {
431
            throw new InvalidArgumentException('The parameters for hslToRgb should be no more than 360, 100, and 100 respectively');
432
        }
433
434
        $h /= 360;
435
        $s /= 100;
436
        $l /= 100;
437
438
        $m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l * $s;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $m2. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
439
        $m1 = $l * 2 - $m2;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $m1. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
440
441
        return array(
442
            (int) round(self::hueToRgb($m1, $m2, $h + 1 / 3) * 0xFF),
443
            (int) round(self::hueToRgb($m1, $m2, $h) * 0xFF),
444
            (int) round(self::hueToRgb($m1, $m2, $h - 1 / 3) * 0xFF),
445
        );
446
    }
447
448
    /**
449
     * Helper function for hslToRgb. Even blacker magic.
450
     *
451
     * @return float Color value
452
     */
453
    private static function hueToRgb($m1, $m2, $hue)
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $m1. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $m2. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
454
    {
455
        $hue = ($hue < 0) ? $hue + 1 : (($hue > 1) ? $hue - 1 : $hue);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $hue. This often makes code more readable.
Loading history...
456 View Code Duplication
        if ($hue * 6 < 1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
457
            return $m1 + ($m2 - $m1) * $hue * 6;
458
        }
459
        if ($hue * 2 < 1) {
460
            return $m2;
461
        }
462 View Code Duplication
        if ($hue * 3 < 2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
463
            return $m1 + ($m2 - $m1) * (2 / 3 - $hue) * 6;
464
        }
465
466
        return $m1;
467
    }
468
469
    /**
470
     * Converts RGB to HSL. Color inversion of previous black magic is white magic?
471
     *
472
     * @param int|float $red   Red
473
     * @param int|float $green Green
474
     * @param int|float $blue  Blue
475
     *
476
     * @return float[] HSL array
477
     */
478
    public static function rgbToHsl($red, $green, $blue)
479
    {
480
        if (min($red, $green, $blue) < 0) {
481
            throw new InvalidArgumentException('The parameters for rgbToHsl should be no less than 0');
482
        } elseif (max($red, $green, $blue) > 0xFF) {
483
            throw new InvalidArgumentException('The parameters for rgbToHsl should be no more than 255');
484
        }
485
486
        $clrMin = min($red, $green, $blue);
487
        $clrMax = max($red, $green, $blue);
488
        $deltaMax = $clrMax - $clrMin;
489
490
        $L = ($clrMax + $clrMin) / 510;
0 ignored issues
show
Coding Style introduced by
$L does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $L. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
491
492
        if (0 == $deltaMax) {
493
            $H = 0;
0 ignored issues
show
Coding Style introduced by
$H does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $H. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
494
            $S = 0;
0 ignored issues
show
Coding Style introduced by
$S does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $S. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
495
        } else {
496
            if (0.5 > $L) {
0 ignored issues
show
Coding Style introduced by
$L does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
497
                $S = $deltaMax / ($clrMax + $clrMin);
0 ignored issues
show
Coding Style introduced by
$S does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
498
            } else {
499
                $S = $deltaMax / (510 - $clrMax - $clrMin);
0 ignored issues
show
Coding Style introduced by
$S does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
500
            }
501
502
            if ($clrMax === $red) {
503
                $H = ($green - $blue) / (6.0 * $deltaMax);
0 ignored issues
show
Coding Style introduced by
$H does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
504
505
                if (0 > $H) {
0 ignored issues
show
Coding Style introduced by
$H does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
506
                    $H += 1;
0 ignored issues
show
Coding Style introduced by
$H does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
507
                }
508
            } elseif ($clrMax === $green) {
509
                $H = 1 / 3 + ($blue - $red) / (6.0 * $deltaMax);
0 ignored issues
show
Coding Style introduced by
$H does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
510
            } else {
511
                $H = 2 / 3 + ($red - $green) / (6.0 * $deltaMax);
0 ignored issues
show
Coding Style introduced by
$H does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
512
            }
513
        }
514
515
        return array(
516
            (float) ($H * 360 % 360),
0 ignored issues
show
Coding Style introduced by
$H does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
517
            (float) ($S * 100),
0 ignored issues
show
Coding Style introduced by
$S does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
518
            (float) ($L * 100),
0 ignored issues
show
Coding Style introduced by
$L does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
519
        );
520
    }
521
}
522