Test Failed
Push — tmp ( 15f615...89cc97 )
by Paul
10:31 queued 04:40
created

DefaultsAbstract::restrict()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Defaults;
4
5
use GeminiLabs\SiteReviews\Helper;
6
use GeminiLabs\SiteReviews\Helpers\Arr;
7
use GeminiLabs\SiteReviews\Helpers\Str;
8
use ReflectionClass;
9
10
/**
11
 * @method array defaults():
12
 * @method array filter(array $values = [])
13
 * @method array filteredData(array $values = [])
14
 * @method array merge(array $values = [])
15
 * @method array restrict(array $values = [])
16
 * @method array unguarded()
17
 */
18
abstract class DefaultsAbstract
19
{
20
    /**
21
     * @var array
22
     */
23
    protected $callable = [
24
        'defaults', 'filter', 'filteredData', 'merge', 'restrict', 'unguarded',
25
    ];
26
27
    /**
28
     * @var array
29
     */
30
    protected $casts = [];
31
32
    /**
33
     * @var array
34
     */
35
    protected $guarded = [];
36
37
    /**
38
     * @var array
39
     */
40
    protected $mapped = [];
41
42
    /**
43
     * @param string $name
44
     * @return void|array
45
     */
46 6
    public function __call($name, array $args = [])
47
    {
48 6
        if (!method_exists($this, $name) || !in_array($name, $this->callable)) {
49
            glsr_log()->error("Invalid method [$name].");
50
            return;
51
        }
52 6
        $args[0] = $this->mapKeys(Arr::get($args, 0, []));
53 6
        $defaults = $this->sanitize(call_user_func_array([$this, $name], $args));
54 6
        $hookName = (new ReflectionClass($this))->getShortName();
55 6
        $hookName = str_replace('Defaults', '', $hookName);
56 6
        $hookName = Str::dashCase($hookName);
57 6
        return glsr()->filterArray('defaults/'.$hookName, $defaults, $name);
58
    }
59
60
    /**
61
     * @return array
62
     */
63
    abstract protected function defaults();
64
65
    /**
66
     * @return array
67
     */
68
    protected function filter(array $values = [])
69
    {
70
        return $this->merge(array_filter($values));
71
    }
72
73
    /**
74
     * @return array
75
     */
76
    protected function filteredData(array $values = [])
77
    {
78
        $defaults = $this->flattenArrayValues($this->unguarded());
79
        $values = $this->flattenArrayValues(shortcode_atts($defaults, $values));
80
        $filtered = array_filter(array_diff_assoc($values, $defaults), function ($value) {
81
            return !$this->isEmpty($value);
82
        });
83
        $filteredJson = [];
84
        foreach ($filtered as $key => $value) {
85
            $filteredJson['data-'.$key] = is_array($value)
86
                ? json_encode($value, JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
87
                : $value;
88
        }
89
        return $filteredJson;
90
    }
91
92
    /**
93
     * @return array
94
     */
95
    protected function flattenArrayValues(array $values)
96
    {
97
        array_walk($values, function (&$value) {
98
            if (is_array($value)) {
99
                $value = implode(',', $value);
100
            }
101
        });
102
        return $values;
103
    }
104
105
    /**
106
     * @param mixed $var
107
     * @return bool
108
     */
109
    protected function isEmpty($var)
110
    {
111
        return !is_numeric($var) && !is_bool($var) && empty($var);
112
    }
113
114
    /**
115
     * @return array
116
     */
117 6
    protected function mapKeys(array $args)
118
    {
119 6
        foreach ($this->mapped as $old => $new) {
120
            if (array_key_exists($old, $args)) {
121
                $args[$new] = $args[$old];
122
                unset($args[$old]);
123
            }
124
        }
125 6
        return $args;
126
    }
127
128
    /**
129
     * @return array
130
     */
131
    protected function merge(array $values = [])
132
    {
133
        return $this->parse($values, $this->defaults());
134
    }
135
136
    /**
137
     * @param mixed $values
138
     * @return array
139
     */
140 6
    protected function normalize($values)
141
    {
142 6
        if (!is_string($values)) {
143 6
            return Arr::consolidate($values);
144
        }
145
        $normalized = [];
146
        wp_parse_str($values, $normalized);
147
        return $normalized;
148
    }
149
150
    /**
151
     * @param mixed $values
152
     * @param mixed $defaults
153
     * @return array
154
     */
155
    protected function parse($values, $defaults)
156
    {
157
        $values = $this->normalize($values);
158
        if (!is_array($defaults)) {
159
            return $values;
160
        }
161
        $parsed = $defaults;
162
        foreach ($values as $key => $value) {
163
            if (is_array($value) && isset($parsed[$key])) {
164
                $parsed[$key] = Arr::unique($this->parse($value, $parsed[$key]));
165
                continue;
166
            }
167
            $parsed[$key] = $value;
168
        }
169
        return $parsed;
170
    }
171
172
    /**
173
     * @param mixed $values
174
     * @return array
175
     */
176 6
    protected function parseRestricted($values, array $pairs)
177
    {
178 6
        $values = $this->normalize($values);
179 6
        $parsed = [];
180 6
        foreach ($pairs as $key => $default) {
181 6
          if (!array_key_exists($key, $values)) {
182 6
              $parsed[$key] = $default;
183 6
              continue;
184
          }
185
          if (is_array($default)) {
186
              $parsed[$key] = $this->parse($values[$key], $default);
187
              continue;
188
          }
189
          $parsed[$key] = $values[$key];
190
        }
191 6
        return $parsed;
192
    }
193
194
    /**
195
     * @return array
196
     */
197 6
    protected function restrict(array $values = [])
198
    {
199 6
        return $this->parseRestricted($values, $this->defaults());
200
    }
201
202
    /**
203
     * @return array
204
     */
205 6
    protected function sanitize(array $values = [])
206
    {
207 6
        foreach ($this->casts as $key => $cast) {
208
            if (!array_key_exists($key, $values)) {
209
                continue;
210
            }
211
            $values[$key] = Helper::castTo($cast, $values[$key]);
212
            if ('string' === $cast) {
213
                $values[$key] = sanitize_key($values[$key]);
214
            }
215
        }
216 6
        return $values;
217
    }
218
219
    /**
220
     * @return array
221
     */
222
    protected function unguarded()
223
    {
224
        return array_diff_key($this->defaults(), array_flip($this->guarded));
225
    }
226
}
227