Test Failed
Push — fix/media-validation ( 390e9c...bd2169 )
by Ben
06:53
created

ValidationNames::requiredLocale()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 1
1
<?php declare(strict_types=1);
2
3
namespace Thinktomorrow\Chief\Fields\Validation;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Support\Arr;
7
8
class ValidationNames
9
{
10
    /** @var array */
11
    private $filters = [
12
        'replacePlaceholders',
13
        'removeEmptyTranslations',
14
        'removeEmptyLocalizedFileEntries',
15
        'removeKeysToBeRemoved',
16
    ];
17
18
    /** @var string */
19
    private $format;
20
21
    /** @var array */
22
    private $placeholders;
23
24
    /** @var array */
25
    private $payload;
26
27
    /** @var array */
28
    private $keysToBeRemoved;
29
30
    /** @var string */
31
    private $requiredLocale;
32
33
    final private function __construct(string $format)
34
    {
35
        $this->format = $format;
36
        $this->placeholders = $this->payload = $this->keysToBeRemoved = [];
37
38
        $this->requiredLocale((string) config('app.fallback_locale', 'nl'));
39
    }
40
41
    public static function fromFormat(string $format)
42
    {
43
        return new static($format);
44
    }
45
46
    public function get(): array
47
    {
48
        $names = [$this->format];
49
50
        foreach($this->filters as $filter){
51
            $names = call_user_func_array([$this, $filter], [$names]);
52
        }
53
54
        return array_values($names);
55
    }
56
57
    public function replace($placeholder, array $replacements): self
58
    {
59
        $this->placeholders[$placeholder] = $replacements;
60
61
        return $this;
62
    }
63
64
    public function payload(array $payload): self
65
    {
66
        $this->payload = $payload;
67
68
        return $this;
69
    }
70
71
    public function requiredLocale(string $requiredLocale): self
72
    {
73
        $this->requiredLocale = $requiredLocale;
74
75
        return $this;
76
    }
77
78
    public function removeKeysContaining(array $keysToBeRemoved): self
79
    {
80
        $this->keysToBeRemoved = array_merge($this->keysToBeRemoved, $keysToBeRemoved);
81
82
        return $this;
83
    }
84
85
    private function replacePlaceholders(array $keys): array
86
    {
87
        foreach ($this->placeholders as $placeholder => $replacements) {
88
            $newKeySet = [];
89
            foreach ($keys as $i => $key) {
90
91
                if(count($replacements) < 1) {
92
                    $newKeySet[] = $key;
93
                    continue;
94
                }
95
96
                foreach ($replacements as $replacement) {
97
                    $newKeySet[] = str_replace(':' . $placeholder, $replacement, $key);
98
                }
99
            }
100
101
            $keys = $newKeySet;
102
        }
103
104
        return $keys;
105
    }
106
107
    private function removeKeysToBeRemoved(array $keys): array
108
    {
109
        $filteredKeys = $keys;
110
111
        foreach($this->keysToBeRemoved as $keyToBeRemoved) {
112
            $pattern = preg_quote($keyToBeRemoved, '#');
113
114
            /* Any asterix which work as an wildcard of characters */
115
            if (false !== strpos($pattern, '*')) {
116
                $pattern = str_replace('\*', '(.+)', $pattern);
117
            }
118
119
            foreach($filteredKeys as $k => $filteredKey) {
120
                if (preg_match("#$pattern#", $filteredKey)) {
121
                    unset($filteredKeys[$k]);
122
                }
123
            }
124
        }
125
126
        return $filteredKeys;
127
    }
128
129
    private function removeEmptyTranslations(array $keys): array
130
    {
131
        if (!isset($this->payload['trans'])) {
132
            return $keys;
133
        }
134
135
        $filteredKeys = $keys;
136
137
        // Remove locales that are considered empty in the request payload
138
        foreach ($this->payload['trans'] as $locale => $values) {
139
            if ($locale == $this->requiredLocale || ! is_array_empty($values)) {
140
                continue;
141
            }
142
143
            // Remove all 'trans' entries for this locale
144
            foreach($filteredKeys as $i => $key){
145
                if(Str::startsWith($key, 'trans.'.$locale)) {
146
                    unset($filteredKeys[$i]);
147
                }
148
            }
149
        }
150
151
        return $filteredKeys;
152
    }
153
154
    private function removeEmptyLocalizedFileEntries(array $keys): array
155
    {
156
        $filteredKeys = $keys;
157
158
        foreach($filteredKeys as $i => $key) {
159
            if (!Str::startsWith($key, ['images.', 'files.'])) continue;
160
161
            $payload = Arr::get($this->payload, $key);
162
163
            // If the payload is empty and this is not the entry for the required locale
164
            if(!$payload && !Str::endsWith($key, '.'.$this->requiredLocale)) {
165
                unset($filteredKeys[$i]);
166
            }
167
        }
168
169
        return $filteredKeys;
170
    }
171
}
172