Config::__construct()   B
last analyzed

Complexity

Conditions 7
Paths 1

Size

Total Lines 19
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 19
rs 8.8333
c 0
b 0
f 0
cc 7
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace dlindberg\BlobChunk\Manager;
6
7
class Config
8
{
9
    public $parentTags                  = [];
10
    public $parentAttributes            = [];
11
    public $specialTags                 = [];
12
    public $specialAttributes           = [];
13
    public $recursionParentTags         = [];
14
    public $recursionParentAttributes   = [];
15
    public $recursionChildrenTags       = [];
16
    public $recursionChildrenAttributes = [];
17
    public $splitWhatTags               = [];
18
    public $splitWhatAttributes         = [];
19
    public $splitOn                     = [];
20
    public $pairParentTags              = [];
21
    public $pairParentAttributes        = [];
22
    public $pairSets                    = [];
23
    public $rowColParentTags            = [];
24
    public $rowColParentAttributes      = [];
25
    public $rowColSets                  = [];
26
27
    public function __construct(array $config)
28
    {
29
        \array_walk($config, function ($config): void {
30
            switch ($config['group']) {
31
                case ('parents'):
32
                case ('specials'):
33
                    $this->addSetting($config, $config['group']);
34
                    break;
35
                case ('recursive'):
36
                    $this->addSetting($config['parents'], 'recursionParents');
37
                    $this->addSetting($config['children'], 'recursionChildren');
38
                    break;
39
                case ('splits'):
40
                    $this->addSetting($config['what'], 'splitWhat');
41
                    $this->splitOn = \array_merge($config['on'], $this->splitOn);
42
                    break;
43
                case ('rowCol'):
44
                case ('pairs'):
45
                    $this->defineCompoundSection($config);
46
            }
47
        });
48
    }
49
50
    public function hasAttribute(string $in, array $attribute): bool
51
    {
52
        if (!\property_exists($this, $in)) {
53
            $in = $this->convertKey($in, 'attributes');
54
        }
55
56
        return \property_exists($this, $in) ? $this->attributeExists($this->$in, $attribute) : false;
57
    }
58
59
    public function convertKey(string $to, string $as): string
60
    {
61
        return \rtrim($to, 's').\mb_convert_case($as, MB_CASE_TITLE);
62
    }
63
64
    private function defineCompoundSection(array $config): void
65
    {
66
        $group = \array_shift($config);
67
        \array_walk($config, function ($setting) use ($group): void {
68
            if ($this->isSettableGroup($setting, 'parent')) {
69
                switch ($group) {
70
                    case ('rowCol'):
71
                        $this->addSetting($setting['parent'], 'rowColParents');
72
                        $this->rowColSets[] = $setting;
73
                        break;
74
                    case ('pairs'):
75
                        $this->addSetting($setting['parent'], 'pairParents');
76
                        $this->pairSets[] = $setting;
77
                        break;
78
                }
79
            }
80
        });
81
    }
82
83
    private function addSetting(?array $what, string $to): void
84
    {
85
        if (\is_array($what)) {
0 ignored issues
show
introduced by
The condition is_array($what) is always true.
Loading history...
86
            if ($this->isSettableGroup($what, 'tags')) {
87
                $this->addValues($what['tags'], $to, 'tags');
88
            }
89
            if ($this->isSettableGroup($what, 'attributes')) {
90
                $this->addValues($what['attributes'], $to, 'attributes');
91
            }
92
            if (\array_key_exists('type', $what)) {
93
                $this->addValues($this->expandSingle($what), $to, $what['type'].'s');
94
            }
95
        }
96
    }
97
98
    private function isSettableGroup(array $what, string $test): bool
99
    {
100
        return \array_key_exists($test, $what) && \is_array($what[$test]) && 0 !== \count($what[$test]);
101
    }
102
103
    private function addValues(array $what, string $to, string $as): void
104
    {
105
        $to = $this->convertKey($to, $as);
106
        if (\is_array($this->$to)) {
107
            $this->$to = $this->addValue($what, $this->$to, $as);
108
        }
109
    }
110
111
    private function addValue(array $new, array $existing, string $as): array
112
    {
113
        if ('attributes' === $as) {
114
            $existing = \array_reduce($new, function ($existing, $attribute): array {
115
116
                $existing = $this->mergeAttributes($attribute, $existing);
117
118
                return $existing;
119
            }, $existing);
120
        }
121
122
        return 'tags' === $as ? \array_merge($new, $existing) : $existing;
123
    }
124
125
    private function mergeAttributes(array $new, array $existing): array
126
    {
127
        if ($this->validAttribute($new) && !$this->attributeExists($existing, $new)) {
128
            $existing[] = ['name' => $new['name'], 'value' => $new['value']];
129
        }
130
131
        return $existing;
132
    }
133
134
    private function attributeExists(array $attributes, array $test): bool
135
    {
136
        return \array_reduce($attributes, function ($carry, $attribute) use ($test): bool {
137
            return ($carry || ($attribute['name'] === $test['name'] && $attribute['value'] === $test['value']));
138
        }, false);
139
    }
140
141
    private function validAttribute(array $attribute): bool
142
    {
143
        return \array_key_exists('name', $attribute) &&
144
               \array_key_exists('value', $attribute) &&
145
               \is_string($attribute['name']) &&
146
               \is_string($attribute['value']);
147
    }
148
149
    private function expandSingle(array $what): array
150
    {
151
        if ('tag' === $what['type']) {
152
            $what = [$what['value'],];
153
        } elseif ('attribute' === $what['type']) {
154
            $what = [['name' => $what['name'], 'value' => $what['value']],];
155
        }
156
157
        return $what;
158
    }
159
}
160