Kint_Parsers_Color   B
last analyzed

Complexity

Total Complexity 46

Size/Duplication

Total Lines 438
Duplicated Lines 1.37 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 9.49%

Importance

Changes 0
Metric Value
dl 6
loc 438
ccs 13
cts 137
cp 0.0949
rs 8.3999
c 0
b 0
f 0
wmc 46
lcom 1
cbo 1

6 Methods

Rating   Name   Duplication   Size   Complexity  
A _HSLtoRGB() 0 12 2
C _RGBtoHSL() 0 46 7
F _convert() 0 128 23
B _fits() 0 21 5
B _hue2rgb() 6 19 6
A _parse() 0 17 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Kint_Parsers_Color often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Kint_Parsers_Color, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace kint\parsers\custom;
4
5
use kint\inc\KintParser;
6
7
/**
8
 * Class Kint_Parsers_Color
9
 */
10
class Kint_Parsers_Color extends KintParser
11
{
12
  /**
13
   * @var array
14
   */
15
  private static $_css3Named = array(
16
      'aliceblue'            => '#f0f8ff',
17
      'antiquewhite'         => '#faebd7',
18
      'aqua'                 => '#00ffff',
19
      'aquamarine'           => '#7fffd4',
20
      'azure'                => '#f0ffff',
21
      'beige'                => '#f5f5dc',
22
      'bisque'               => '#ffe4c4',
23
      'black'                => '#000000',
24
      'blanchedalmond'       => '#ffebcd',
25
      'blue'                 => '#0000ff',
26
      'blueviolet'           => '#8a2be2',
27
      'brown'                => '#a52a2a',
28
      'burlywood'            => '#deb887',
29
      'cadetblue'            => '#5f9ea0',
30
      'chartreuse'           => '#7fff00',
31
      'chocolate'            => '#d2691e',
32
      'coral'                => '#ff7f50',
33
      'cornflowerblue'       => '#6495ed',
34
      'cornsilk'             => '#fff8dc',
35
      'crimson'              => '#dc143c',
36
      'cyan'                 => '#00ffff',
37
      'darkblue'             => '#00008b',
38
      'darkcyan'             => '#008b8b',
39
      'darkgoldenrod'        => '#b8860b',
40
      'darkgray'             => '#a9a9a9',
41
      'darkgrey'             => '#a9a9a9',
42
      'darkgreen'            => '#006400',
43
      'darkkhaki'            => '#bdb76b',
44
      'darkmagenta'          => '#8b008b',
45
      'darkolivegreen'       => '#556b2f',
46
      'darkorange'           => '#ff8c00',
47
      'darkorchid'           => '#9932cc',
48
      'darkred'              => '#8b0000',
49
      'darksalmon'           => '#e9967a',
50
      'darkseagreen'         => '#8fbc8f',
51
      'darkslateblue'        => '#483d8b',
52
      'darkslategray'        => '#2f4f4f',
53
      'darkslategrey'        => '#2f4f4f',
54
      'darkturquoise'        => '#00ced1',
55
      'darkviolet'           => '#9400d3',
56
      'deeppink'             => '#ff1493',
57
      'deepskyblue'          => '#00bfff',
58
      'dimgray'              => '#696969',
59
      'dimgrey'              => '#696969',
60
      'dodgerblue'           => '#1e90ff',
61
      'firebrick'            => '#b22222',
62
      'floralwhite'          => '#fffaf0',
63
      'forestgreen'          => '#228b22',
64
      'fuchsia'              => '#ff00ff',
65
      'gainsboro'            => '#dcdcdc',
66
      'ghostwhite'           => '#f8f8ff',
67
      'gold'                 => '#ffd700',
68
      'goldenrod'            => '#daa520',
69
      'gray'                 => '#808080',
70
      'grey'                 => '#808080',
71
      'green'                => '#008000',
72
      'greenyellow'          => '#adff2f',
73
      'honeydew'             => '#f0fff0',
74
      'hotpink'              => '#ff69b4',
75
      'indianred'            => '#cd5c5c',
76
      'indigo'               => '#4b0082',
77
      'ivory'                => '#fffff0',
78
      'khaki'                => '#f0e68c',
79
      'lavender'             => '#e6e6fa',
80
      'lavenderblush'        => '#fff0f5',
81
      'lawngreen'            => '#7cfc00',
82
      'lemonchiffon'         => '#fffacd',
83
      'lightblue'            => '#add8e6',
84
      'lightcoral'           => '#f08080',
85
      'lightcyan'            => '#e0ffff',
86
      'lightgoldenrodyellow' => '#fafad2',
87
      'lightgray'            => '#d3d3d3',
88
      'lightgrey'            => '#d3d3d3',
89
      'lightgreen'           => '#90ee90',
90
      'lightpink'            => '#ffb6c1',
91
      'lightsalmon'          => '#ffa07a',
92
      'lightseagreen'        => '#20b2aa',
93
      'lightskyblue'         => '#87cefa',
94
      'lightslategray'       => '#778899',
95
      'lightslategrey'       => '#778899',
96
      'lightsteelblue'       => '#b0c4de',
97
      'lightyellow'          => '#ffffe0',
98
      'lime'                 => '#00ff00',
99
      'limegreen'            => '#32cd32',
100
      'linen'                => '#faf0e6',
101
      'magenta'              => '#ff00ff',
102
      'maroon'               => '#800000',
103
      'mediumaquamarine'     => '#66cdaa',
104
      'mediumblue'           => '#0000cd',
105
      'mediumorchid'         => '#ba55d3',
106
      'mediumpurple'         => '#9370d8',
107
      'mediumseagreen'       => '#3cb371',
108
      'mediumslateblue'      => '#7b68ee',
109
      'mediumspringgreen'    => '#00fa9a',
110
      'mediumturquoise'      => '#48d1cc',
111
      'mediumvioletred'      => '#c71585',
112
      'midnightblue'         => '#191970',
113
      'mintcream'            => '#f5fffa',
114
      'mistyrose'            => '#ffe4e1',
115
      'moccasin'             => '#ffe4b5',
116
      'navajowhite'          => '#ffdead',
117
      'navy'                 => '#000080',
118
      'oldlace'              => '#fdf5e6',
119
      'olive'                => '#808000',
120
      'olivedrab'            => '#6b8e23',
121
      'orange'               => '#ffa500',
122
      'orangered'            => '#ff4500',
123
      'orchid'               => '#da70d6',
124
      'palegoldenrod'        => '#eee8aa',
125
      'palegreen'            => '#98fb98',
126
      'paleturquoise'        => '#afeeee',
127
      'palevioletred'        => '#d87093',
128
      'papayawhip'           => '#ffefd5',
129
      'peachpuff'            => '#ffdab9',
130
      'peru'                 => '#cd853f',
131
      'pink'                 => '#ffc0cb',
132
      'plum'                 => '#dda0dd',
133
      'powderblue'           => '#b0e0e6',
134
      'purple'               => '#800080',
135
      'red'                  => '#ff0000',
136
      'rosybrown'            => '#bc8f8f',
137
      'royalblue'            => '#4169e1',
138
      'saddlebrown'          => '#8b4513',
139
      'salmon'               => '#fa8072',
140
      'sandybrown'           => '#f4a460',
141
      'seagreen'             => '#2e8b57',
142
      'seashell'             => '#fff5ee',
143
      'sienna'               => '#a0522d',
144
      'silver'               => '#c0c0c0',
145
      'skyblue'              => '#87ceeb',
146
      'slateblue'            => '#6a5acd',
147
      'slategray'            => '#708090',
148
      'slategrey'            => '#708090',
149
      'snow'                 => '#fffafa',
150
      'springgreen'          => '#00ff7f',
151
      'steelblue'            => '#4682b4',
152
      'tan'                  => '#d2b48c',
153
      'teal'                 => '#008080',
154
      'thistle'              => '#d8bfd8',
155
      'tomato'               => '#ff6347',
156
      'turquoise'            => '#40e0d0',
157
      'violet'               => '#ee82ee',
158
      'wheat'                => '#f5deb3',
159
      'white'                => '#ffffff',
160
      'whitesmoke'           => '#f5f5f5',
161
      'yellow'               => '#ffff00',
162
      'yellowgreen'          => '#9acd32',
163
  );
164
165
  /**
166
   * @param array $hsl
167
   *
168
   * @return array
169
   */
170
  private static function _HSLtoRGB(array $hsl)
171
  {
172
    list($h, $s, $l) = $hsl;
173
    $m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l * $s;
174
    $m1 = $l * 2 - $m2;
175
176
    return array(
177
        round(self::_hue2rgb($m1, $m2, $h + 0.33333) * 255),
178
        round(self::_hue2rgb($m1, $m2, $h) * 255),
179
        round(self::_hue2rgb($m1, $m2, $h - 0.33333) * 255),
180
    );
181
  }
182
183
  /**
184
   * @param array $rgb
185
   *
186
   * @return array
187
   */
188
  private static function _RGBtoHSL(array $rgb)
189
  {
190
    list($clrR, $clrG, $clrB) = $rgb;
191
192
    $clrMin = min($clrR, $clrG, $clrB);
193
    $clrMax = max($clrR, $clrG, $clrB);
194
    $deltaMax = $clrMax - $clrMin;
195
196
    $L = ($clrMax + $clrMin) / 510;
197
198
    if (0 == $deltaMax) {
199
      $H = 0;
200
      $S = 0;
201
    } else {
202
203
      if (0.5 > $L) {
204
        $S = $deltaMax / ($clrMax + $clrMin);
205
      } else {
206
        $S = $deltaMax / (510 - $clrMax - $clrMin);
207
      }
208
209
      if ($clrMax == $clrR) {
210
        $H = ($clrG - $clrB) / (6.0 * $deltaMax);
211
      } elseif ($clrMax == $clrG) {
212
        $H = 1 / 3 + ($clrB - $clrR) / (6.0 * $deltaMax);
213
      } else {
214
        $H = 2 / 3 + ($clrR - $clrG) / (6.0 * $deltaMax);
215
      }
216
217
      if (0 > $H) {
218
        /** @noinspection PrefixedIncDecrementEquivalentInspection */
219
        $H += 1;
220
      }
221
222
      if (1 < $H) {
223
        /** @noinspection PrefixedIncDecrementEquivalentInspection */
224
        $H -= 1;
225
      }
226
    }
227
228
    return array(
229
        round($H * 360),
230
        round($S * 100) . '%',
231
        round($L * 100) . '%',
232
    );
233
  }
234
235
  /**
236
   * @param $color
237
   *
238
   * @return array
239
   */
240
  private static function _convert(&$color)
241
  {
242
    $color = strtolower($color);
243
244
    $decimalColors = array();
245
    $variants = array(
246
        'hex'  => null,
247
        'rgb'  => null,
248
        'name' => null,
249
        'hsl'  => null,
250
    );
251
252
    if (isset(self::$_css3Named[$color])) {
253
      /** @noinspection ReferenceMismatchInspection */
254
      $variants['name'] = $color;
255
      $color = self::$_css3Named[$color];
256
    }
257
258
    if ($color[0] === '#') {
259
      /** @noinspection ReferenceMismatchInspection */
260
      $variants['hex'] = $color;
261
      $color = substr($color, 1);
262
      if (strlen($color) === 6) {
263
        $colors = str_split($color, 2);
264
      } else {
265
        $colors = array(
266
            $color[0] . $color[0],
267
            $color[1] . $color[1],
268
            $color[2] . $color[2],
269
        );
270
      }
271
272
      $decimalColors = array_map('hexdec', $colors);
273
274
    } elseif (0 === strpos($color, 'rgb')) {
275
276
      /** @noinspection ReferenceMismatchInspection */
277
      $variants['rgb'] = $color;
278
      preg_match_all('#([0-9.%]+)#', $color, $matches);
279
      $decimalColors = $matches[1];
280
      foreach ($decimalColors as &$colorInner) {
281
        if (strpos($colorInner, '%') !== false) {
282
          $colorInner = str_replace('%', '', $colorInner) * 2.55;
283
        }
284
      }
285
      if (isset($colorInner)) {
286
        /** @noinspection ReferenceMismatchInspection */
287
        $color = $colorInner;
288
      }
289
      unset($colorInner);
290
291
    } elseif (0 === strpos($color, 'hsl')) {
292
293
      /** @noinspection ReferenceMismatchInspection */
294
      $variants['hsl'] = $color;
295
      preg_match_all('#([0-9.%]+)#', $color, $matches);
296
297
      $colors = $matches[1];
298
      $colors[0] /= 360;
299
      $colors[1] = str_replace('%', '', $colors[1]) / 100;
300
      $colors[2] = str_replace('%', '', $colors[2]) / 100;
301
302
      $decimalColors = self::_HSLtoRGB($colors);
303
      if (isset($colors[3])) {
304
        $decimalColors[] = $colors[3];
305
      }
306
    }
307
308
    if (isset($decimalColors[3])) {
309
      $alpha = $decimalColors[3];
310
      unset($decimalColors[3]);
311
    } else {
312
      $alpha = null;
313
    }
314
315
    foreach ($variants as $type => &$variant) {
316
      if (isset($variant)) {
317
        continue;
318
      }
319
320
      switch ($type) {
321
        case 'hex':
322
          $variant = '#';
323
          foreach ($decimalColors as &$decimalColorsSingle) {
324
            $variant .= str_pad(dechex($decimalColorsSingle), 2, '0', STR_PAD_LEFT);
325
          }
326
          unset($decimalColorsSingle);
327
          $variant .= isset($alpha) ? ' (alpha omitted)' : '';
328
          break;
329
        case 'rgb':
330
          $rgb = $decimalColors;
331
          if (isset($alpha)) {
332
            $rgb[] = $alpha;
333
            $a = 'a';
334
          } else {
335
            $a = '';
336
          }
337
          $variant = "rgb{$a}( " . implode(', ', $rgb) . ' )';
338
          break;
339
        case 'hsl':
340
          $rgb = self::_RGBtoHSL($decimalColors);
341
          if ($rgb === null) {
342
            unset($variants[$type]);
343
            break;
344
          }
345
          if (isset($alpha)) {
346
            $rgb[] = $alpha;
347
            $a = 'a';
348
          } else {
349
            $a = '';
350
          }
351
352
          $variant = "hsl{$a}( " . implode(', ', $rgb) . ' )';
353
          break;
354
        case 'name':
355
          // [!] name in initial variants array must go after hex
356
          if (($key = array_search($variants['hex'], self::$_css3Named, true)) !== false) {
357
            $variant = $key;
358
          } else {
359
            unset($variants[$type]);
360
          }
361
          break;
362
      }
363
364
    }
365
366
    return $variants;
367
  }
368
369
  /**
370
   * @param $variable
371
   *
372
   * @return bool
373
   */
374 1
  private static function _fits(&$variable)
375
  {
376
    if (
377 1
        is_object($variable)
378
        ||
379 1
        is_array($variable)
380
        ||
381 1
        (string)$variable === $variable
382
    ) {
383 1
      return false;
384
    }
385
386 1
    $var = strtolower(trim($variable));
387
388
    // TODO: make this readable ...
389 1
    return isset(self::$_css3Named[$var])
390 1
           || preg_match(
391 1
               '/^(?:#[0-9A-Fa-f]{3}|#[0-9A-Fa-f]{6}|(?:rgb|hsl)a?\s*\((?:\s*[0-9.%]+\s*,?){3,4}\))$/',
392 1
               $var
393
           );
394
  }
395
396
  /**
397
   * Helper function for _color_hsl2rgb().
398
   *
399
   * @param $m1
400
   * @param $m2
401
   * @param $h
402
   *
403
   * @return mixed
404
   */
405
  private static function _hue2rgb($m1, $m2, $h)
406
  {
407
    /** @noinspection NestedTernaryOperatorInspection */
408
    $h = ($h < 0) ? $h + 1 : (($h > 1) ? $h - 1 : $h);
409
410 View Code Duplication
    if ($h * 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...
411
      return $m1 + ($m2 - $m1) * $h * 6;
412
    }
413
414
    if ($h * 2 < 1) {
415
      return $m2;
416
    }
417
418 View Code Duplication
    if ($h * 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...
419
      return $m1 + ($m2 - $m1) * (0.66666 - $h) * 6;
420
    }
421
422
    return $m1;
423
  }
424
425
  /**
426
   * @param mixed $variable
427
   *
428
   * @return bool
429
   */
430 1
  protected function _parse(&$variable)
431
  {
432 1
    if (!self::_fits($variable)) {
433 1
      return false;
434
    }
435
436
    $this->type = 'CSS color';
437
    $variants = self::_convert($variable);
438
    $this->value =
439
        "<div style=\"background:{$variable}\" class=\"kint-color-preview\">{$variable}</div>"
440
        . "<strong>hex :</strong> {$variants['hex']}\n"
441
        . "<strong>rgb :</strong> {$variants['rgb']}\n"
442
        . (isset($variants['name']) ? "<strong>name:</strong> {$variants['name']}\n" : '')
443
        . "<strong>hsl :</strong> {$variants['hsl']}";
444
445
    return true;
446
  }
447
}
448