Passed
Pull Request — master (#3021)
by Jesse
05:24
created

MetaData::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 4
dl 0
loc 12
ccs 5
cts 5
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Frontend\Core\Header;
4
5
use InvalidArgumentException;
6
7
final class MetaData
8
{
9
    /** @var array */
10
    private $attributes;
11
12
    /** @var string */
13
    private $uniqueKey;
14
15
    /**
16
     * @param string $content since we always need content we've added it as a separate parameter
17
     * @param string[] $attributes
18
     * @param string[] $uniqueAttributeKeys
19
     * @param string|null $uniqueKeySuffix
20
     *
21
     * @throws InvalidArgumentException when the content is empty
22
     */
23 10
    public function __construct(
24
        string $content,
25
        array $attributes,
26
        array $uniqueAttributeKeys = ['content'],
27
        string $uniqueKeySuffix = null
28
    ) {
29 10
        if (empty($content)) {
30 1
            throw new InvalidArgumentException('The content can not be empty');
31
        }
32
33 9
        $this->attributes = ['content' => $content] + $attributes;
34 9
        $this->createUniqueKey($uniqueAttributeKeys, $uniqueKeySuffix);
35 9
    }
36
37
    /**
38
     * @param string[] $uniqueAttributeKeys
39
     * @param string|null $uniqueKeySuffix
40
     */
41 9
    private function createUniqueKey(array $uniqueAttributeKeys, string $uniqueKeySuffix = null): void
42
    {
43
        // make sure the keys are sorted alphabetically
44 9
        sort($uniqueAttributeKeys);
45
46 9
        $this->uniqueKey = implode(
47 9
            '|',
48 9
            array_filter(
49 9
                array_map(
50 9
                    function (string $attributeKey) {
51 9
                        return $this->attributes[$attributeKey] ?? '';
52 9
                    },
53 9
                    $uniqueAttributeKeys
54
                )
55
            )
56
        );
57
58 9
        if ($uniqueKeySuffix !== null) {
59
            $this->uniqueKey .= '|' . $uniqueKeySuffix;
60
        }
61 9
    }
62
63 5
    public function getUniqueKey(): string
64
    {
65 5
        return $this->uniqueKey;
66
    }
67
68 4
    public function hasAttributeWithValue(string $attributeKey, string $attributeValue): bool
69
    {
70 4
        return isset($this->attributes[$attributeKey]) && $this->attributes[$attributeKey] === $attributeValue;
71
    }
72
73
    /**
74
     * Some things should be appended instead of ignored when the meta data is already set instead of ignored.
75
     *
76
     * @return bool
77
     */
78 1
    public function shouldMergeOnDuplicateKey(): bool
79
    {
80 1
        return in_array($this->uniqueKey, ['description', 'keywords', 'robots'], true);
81
    }
82
83 1
    public function merge(self $metaData): void
84
    {
85 1
        foreach ($metaData->attributes as $attributeKey => $attributeValue) {
86
            // the content should be appended, the rest of the attributes gets overwritten or added
87 1
            if ($attributeKey === 'content' && isset($this->attributes[$attributeKey])) {
88 1
                $this->attributes[$attributeKey] .= ', ' . $attributeValue;
89
90 1
                continue;
91
            }
92
93
            $this->attributes[$attributeKey] = $attributeValue;
94
        }
95 1
    }
96
97 4
    public static function forName(
98
        string $name,
99
        string $content
100
    ): self {
101 4
        return new self($content, ['name' => $name], ['name']);
102
    }
103
104 1
    public static function forProperty(
105
        string $property,
106
        string $content,
107
        array $uniqueAttributeKeys = ['property']
108
    ): self {
109 1
        return new self($content, ['property' => $property], $uniqueAttributeKeys);
110
    }
111
112 2
    public function __toString(): string
113
    {
114 2
        $html = '<meta ';
115 2
        $html .= implode(
116 2
            ' ',
117 2
            array_map(
118 2
                function (string $parameterKey, string $parameterValue) {
119 2
                    return $parameterKey . '="' . $parameterValue . '"';
120 2
                },
121
                array_keys($this->attributes),
122
                $this->attributes
123
            )
124
        );
125
        $html .= '>';
126
127
        return $html;
128
    }
129
}
130