Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
Color
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
5 / 5
9
100.00% covered (success)
100.00%
1 / 1
 __toString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 raw
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 json
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 isset
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 normalize
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Value;
6
7use Override;
8
9class Color extends Value
10{
11    /**
12     * Only a normalized `#rrggbb` ever leaves the value, so it is safe
13     * in a style attribute or custom property where HTML escaping is not
14     * enough; anything else stored reads as no colour.
15     */
16    #[Override]
17    public function __toString(): string
18    {
19        return $this->raw();
20    }
21
22    #[Override]
23    public function raw(): string
24    {
25        return self::normalize($this->value()) ?? '';
26    }
27
28    #[Override]
29    public function json(): ?string
30    {
31        return $this->isset() ? $this->raw() : null;
32    }
33
34    #[Override]
35    public function isset(): bool
36    {
37        return $this->raw() !== '';
38    }
39
40    /**
41     * Lowercase `#rrggbb` from a hex colour with three or six digits and
42     * an optional leading `#`, or null for anything else.
43     */
44    public static function normalize(mixed $value): ?string
45    {
46        if (!is_string($value) || preg_match('/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i', trim($value), $match) !== 1) {
47            return null;
48        }
49
50        $hex = strtolower($match[1]);
51
52        if (strlen($hex) === 3) {
53            $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
54        }
55
56        return '#' . $hex;
57    }
58}