Passed
Push — ft/field-contract ( 898325 )
by Ben
10:44
created

ValidationNames::removeEmptyTranslations()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 23
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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