Test Setup Failed
Push — test ( 610d2f...d11afe )
by Jonathan
03:32
created

ColorRepresentation::hslToRgb()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 4
nop 3
dl 0
loc 21
rs 8.7624
c 0
b 0
f 0
1
<?php
2
3
namespace Kint\Object\Representation;
4
5
use Kint\Object\ColorObject;
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...
8
{
9
    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...
10
    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...
11
    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...
12
    public $a = 1;
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...
13
    public $variant = null;
14
    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...
15
    public $hints = array('color');
16
17
    const COLOR_NAME = 1;
18
    const COLOR_HEX_3 = 2;
19
    const COLOR_HEX_6 = 3;
20
    const COLOR_RGB = 4;
21
    const COLOR_RGBA = 5;
22
    const COLOR_HSL = 6;
23
    const COLOR_HSLA = 7;
24
    const COLOR_HEX_4 = 8;
25
    const COLOR_HEX_8 = 9;
26
27
    public function getColor($variant = null)
28
    {
29
        switch ($variant) {
30
            case self::COLOR_NAME:
31
                $hex = sprintf('%02x%02x%02x', $this->r, $this->g, $this->b);
32
33
                return array_search($hex, ColorObject::$color_map);
34
            case self::COLOR_HEX_3:
35
                if ($this->r % 0x11 === 0 && $this->g % 0x11 === 0 && $this->b % 0x11 === 0) {
36
                    return sprintf(
37
                        '#%1X%1X%1X',
38
                        round($this->r / 0x11),
39
                        round($this->g / 0x11),
40
                        round($this->b / 0x11)
41
                    );
42
                } else {
43
                    return false;
44
                }
45
            case self::COLOR_HEX_6:
46
                return sprintf('#%02X%02X%02X', $this->r, $this->g, $this->b);
47
            case self::COLOR_RGB:
48
                return sprintf('rgb(%d, %d, %d)', $this->r, $this->g, $this->b);
49 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...
50
                return sprintf('rgba(%d, %d, %d, %s)', $this->r, $this->g, $this->b, round($this->a, 4));
51
            case self::COLOR_HSL:
52
                $val = ColorObject::rgbToHsl($this->r, $this->g, $this->b);
53
54
                return vsprintf('hsl(%d, %d%%, %d%%)', $val);
55
            case self::COLOR_HSLA:
56
                $val = ColorObject::rgbToHsl($this->r, $this->g, $this->b);
57
58
                return sprintf('hsla(%d, %d%%, %d%%, %s)', $val[0], $val[1], $val[2], round($this->a, 4));
59
            case self::COLOR_HEX_4:
60
                if ($this->r % 0x11 === 0 && $this->g % 0x11 === 0 && $this->b % 0x11 === 0 && ($this->a * 255) % 0x11 === 0) {
61
                    return sprintf(
62
                        '#%1X%1X%1X%1X',
63
                        round($this->r / 0x11),
64
                        round($this->g / 0x11),
65
                        round($this->b / 0x11),
66
                        round($this->a * 0xF)
67
                    );
68
                } else {
69
                    return false;
70
                }
71 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...
72
                return sprintf('#%02X%02X%02X%02X', $this->r, $this->g, $this->b, round($this->a * 0xFF));
73
            case null:
74
                return $this->contents;
75
        }
76
77
        return false;
78
    }
79
80
    public function __construct($value)
81
    {
82
        parent::__construct('Color');
83
84
        $this->contents = $value;
85
        $this->setValues($value);
86
    }
87
88
    public function hasAlpha($variant = null)
89
    {
90
        if ($variant === null) {
91
            $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...
92
        }
93
94
        switch ($variant) {
95
            case self::COLOR_NAME:
96
                return $this->a !== 1;
97
            case self::COLOR_RGBA:
98
            case self::COLOR_HSLA:
99
            case self::COLOR_HEX_4:
100
            case self::COLOR_HEX_8:
101
                return true;
102
            default:
103
                return false;
104
        }
105
    }
106
107
    protected function setValues($value)
108
    {
109
        $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...
110
        // Find out which variant of color input it is
111
        if (isset(ColorObject::$color_map[$value])) {
112
            $variant = self::COLOR_NAME;
113
        } elseif ($value[0] === '#') {
114
            $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...
115
116
            if (dechex(hexdec($value)) !== $value) {
117
                return;
118
            }
119
120 View Code Duplication
            switch (strlen($value)) {
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...
121
                case 3:
122
                    $variant = self::COLOR_HEX_3;
123
                    break;
124
                case 6:
125
                    $variant = self::COLOR_HEX_6;
126
                    break;
127
                case 4:
128
                    $variant = self::COLOR_HEX_4;
129
                    break;
130
                case 8:
131
                    $variant = self::COLOR_HEX_8;
132
                    break;
133
                default:
134
                    return;
135
            }
136
        } else {
137
            if (!preg_match('/^((?:rgb|hsl)a?)\s*\(([0-9\.%,\s]+)\)$/i', $value, $match)) {
138
                return;
139
            }
140
141 View Code Duplication
            switch ($match[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...
142
                case 'rgb':
143
                    $variant = self::COLOR_RGB;
144
                    break;
145
                case 'rgba':
146
                    $variant = self::COLOR_RGBA;
147
                    break;
148
                case 'hsl':
149
                    $variant = self::COLOR_HSL;
150
                    break;
151
                case 'hsla':
152
                    $variant = self::COLOR_HSLA;
153
                    break;
154
                default:
155
                    return;
156
            }
157
158
            $value = explode(',', $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...
159
160
            if ($this->hasAlpha($variant)) {
161
                if (count($value) !== 4) {
162
                    return;
163
                }
164
            } elseif (count($value) !== 3) {
165
                return;
166
            }
167
168
            foreach ($value as $i => &$color) {
169
                $color = trim($color);
170
171
                if (strpos($color, '%') !== false) {
172
                    $color = str_replace('%', '', $color);
173
174
                    if ($i === 3) {
175
                        $color = $color / 100;
176
                    } elseif (in_array($variant, array(self::COLOR_RGB, self::COLOR_RGBA))) {
177
                        $color = round($color / 100 * 255);
178
                    } elseif ($i === 0 && in_array($variant, array(self::COLOR_HSL, self::COLOR_HSLA))) {
179
                        $color = $color / 100 * 360;
180
                    }
181
                }
182
183
                if ($i === 0 && in_array($variant, array(self::COLOR_HSL, self::COLOR_HSLA))) {
184
                    $color = ($color % 360 + 360) % 360;
185
                }
186
            }
187
        }
188
189
        // Assign the correct properties based on the variant
190
        switch ($variant) {
191
            case self::COLOR_HEX_4:
192
                $this->a = hexdec($value[3]) / 0xF;
0 ignored issues
show
Documentation Bug introduced by
It seems like hexdec($value[3]) / 15 can also be of type double. However, the property $a 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...
193
                // Fallthrough
194
            case self::COLOR_HEX_3:
195
                $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...
196
                $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...
197
                $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...
198
                break;
199
            case self::COLOR_NAME:
200
                $value = ColorObject::$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...
201
                // Fallthrough
202
            case self::COLOR_HEX_8:
203
                $this->a = hexdec(substr($value, 6, 2)) / 0xFF;
0 ignored issues
show
Documentation Bug introduced by
It seems like hexdec(substr($value, 6, 2)) / 255 can also be of type double. However, the property $a 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...
204
                // Fallthrough
205
            case self::COLOR_HEX_6:
206
                $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...
207
                $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...
208
                $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...
209
                $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...
210
                break;
211
            case self::COLOR_RGBA:
212
                $this->a = $value[3];
213
                // Fallthrough
214
            case self::COLOR_RGB:
215
                list($this->r, $this->g, $this->b) = $value;
216
                break;
217
            case self::COLOR_HSLA:
218
                $this->a = $value[3];
219
                // Fallthrough
220
            case self::COLOR_HSL:
221
                if (min($value) < 0 || $value[0] > 360 || max($value[1], $value[2]) > 100) {
222
                    return;
223
                }
224
                $value = ColorObject::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...
225
                list($this->r, $this->g, $this->b) = $value;
226
                break;
227
        }
228
229
        // If something has gone horribly wrong
230
        if ($this->r > 0xFF || $this->g > 0xFF || $this->b > 0xFF || $this->a > 1) {
231
            $this->variant = null;
232
        } else {
233
            $this->variant = $variant;
234
        }
235
    }
236
}
237