Test Failed
Push — develop ( 1febff...e7b0b3 )
by Paul
09:43
created

Shortcode::normalizeClass()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Shortcodes;
4
5
use GeminiLabs\SiteReviews\Contracts\ShortcodeContract;
6
use GeminiLabs\SiteReviews\Database\ShortcodeOptionManager;
7
use GeminiLabs\SiteReviews\Defaults\DefaultsAbstract;
8
use GeminiLabs\SiteReviews\Helper;
9
use GeminiLabs\SiteReviews\Helpers\Arr;
10
use GeminiLabs\SiteReviews\Helpers\Cast;
11
use GeminiLabs\SiteReviews\Helpers\Str;
12
use GeminiLabs\SiteReviews\Modules\Html\Builder;
13
use GeminiLabs\SiteReviews\Modules\Multilingual;
14
use GeminiLabs\SiteReviews\Modules\Rating;
15
use GeminiLabs\SiteReviews\Modules\Sanitizer;
16
use GeminiLabs\SiteReviews\Modules\Style;
17
18
abstract class Shortcode implements ShortcodeContract
19
{
20
    public array $args;
21
    public string $debug;
22
    public string $description;
23
    public string $from;
24 8
    public string $name;
25
    public string $tag;
26 8
27
    public function __construct()
28
    {
29
        $this->args = [];
30
        $this->debug = '';
31
        $this->description = $this->description();
32
        $this->from = '';
33
        $this->name = $this->name();
34
        $this->tag = $this->tag();
35
    }
36
37
    public function attributes(array $values, string $from = 'function'): array
38
    {
39
        $attributes = $this->defaults()->dataAttributes($values);
40
        $attributes = wp_parse_args($attributes, [
41
            'class' => glsr(Style::class)->styleClasses(),
42
            'data-from' => $from,
43
            'data-shortcode' => $this->tag,
44
            'id' => $values['id'] ?? '',
45
        ]);
46
        unset($attributes['data-class']);
47
        unset($attributes['data-id']);
48
        unset($attributes['data-form_id']);
49
        $attributes = glsr()->filterArray("shortcode/{$this->tag}/attributes", $attributes, $this);
50
        $attributes = array_map('esc_attr', $attributes);
51
        return $attributes;
52
    }
53
54
    public function build($args = [], string $from = 'shortcode'): string
55
    {
56
        $this->normalize(wp_parse_args($args), $from);
57
        $template = $this->buildTemplate();
58
        $attributes = $this->attributes($this->args, $from);
59
        $html = glsr(Builder::class)->div($template, $attributes);
60
        $rendered = sprintf('%s%s', $this->debug, $html);
61
        return glsr(Builder::class)->div([
62
            'class' => $this->args['class'],
63
            'text' => $rendered,
64
        ]);
65
    }
66
67
    public function defaults(): DefaultsAbstract
68
    {
69
        $classname = str_replace('Shortcodes\\', 'Defaults\\', get_class($this));
70
        $classname = str_replace('Shortcode', 'Defaults', $classname);
71
        return glsr($classname);
72
    }
73
74
    public function hasVisibleFields(array $args = []): bool
75
    {
76
        if (!empty($args)) {
77
            $this->normalize($args);
78
        }
79
        $defaults = $this->options('hide');
80
        $hide = $this->args['hide'] ?? [];
81
        $hide = array_flip(Arr::consolidate($hide));
82
        unset($defaults['if_empty'], $hide['if_empty']);
83 8
        return !empty(array_diff_key($defaults, $hide));
84
    }
85 8
86 8
    public function normalize(array $args, string $from = ''): ShortcodeContract
87
    {
88
        if (!empty($from)) {
89
            $this->from = $from;
90
        }
91
        $args = glsr()->filterArray('shortcode/args', $args, $this->tag);
92
        $args = $this->defaults()->unguardedRestrict($args);
93
        foreach ($args as $key => &$value) {
94
            $method = Helper::buildMethodName('normalize', $key);
95
            if (method_exists($this, $method)) {
96
                $value = call_user_func([$this, $method], $value, $args);
97
            }
98
        }
99
        $this->args = $args;
100
        return $this;
101
    }
102
103
    /**
104
     * Returns the options for a shortcode setting. Results are filtered
105
     * by the "site-reviews/shortcode/options/{$options}" hook.
106
     */
107
    public function options(string $option, array $args = []): array
108
    {
109
        $args['option'] = $option;
110
        $args['shortcode'] = $this->tag;
111
        return call_user_func([glsr(ShortcodeOptionManager::class), $option], $args);
112
    }
113
114
    public function register(): void
115
    {
116
        if (!function_exists('add_shortcode')) {
117
            return;
118
        }
119
        $shortcode = (new \ReflectionClass($this))->getShortName();
120
        $shortcode = Str::snakeCase($shortcode);
121
        $shortcode = str_replace('_shortcode', '', $shortcode);
122
        add_shortcode($shortcode, fn ($atts) => $this->build($atts));
123
        glsr()->append('shortcodes', get_class($this), $shortcode);
124
    }
125
126
    /**
127
     * Returns the filtered shortcode settings configuration.
128
     */
129
    public function settings(): array
130
    {
131
        $config = $this->config();
132
        $config = glsr()->filterArray("shortcode/{$this->tag}/config", $config, $this);
133
        $config = glsr()->filterArray('shortcode/config', $config, $this);
134
        return $config;
135
    }
136
137
    public function tag(): string
138
    {
139
        return Str::snakeCase(
140
            str_replace('Shortcode', '', (new \ReflectionClass($this))->getShortName())
141
        );
142
    }
143
144
    /**
145
     * Returns the unfiltered shortcode settings configuration.
146
     */
147
    abstract protected function config(): array;
148
149
    protected function debug(array $data = []): void
150
    {
151
        if (empty($this->args['debug']) || 'shortcode' !== $this->from) {
152
            return;
153
        }
154
        $data = wp_parse_args($data, [
155
            'args' => $this->args,
156
            'shortcode' => $this->tag,
157
        ]);
158
        ksort($data);
159
        ob_start();
160
        glsr_debug($data);
161
        $this->debug = ob_get_clean();
162
    }
163
164
    protected function hideOptions(): array
165
    {
166
        return [];
167
    }
168
169
    /**
170
     * @param string $value
171
     */
172
    protected function normalizeAssignedPosts($value): string
173
    {
174
        $values = Cast::toArray($value);
175
        $postTypes = [];
176
        foreach ($values as $postType) {
177
            if (!is_numeric($postType) && post_type_exists((string) $postType)) {
178
                $postTypes[] = $postType;
179
            }
180
        }
181
        $values = glsr(Sanitizer::class)->sanitizePostIds($values);
182
        $values = glsr(Multilingual::class)->getPostIdsForAllLanguages($values);
183
        $values = array_merge($values, $postTypes);
184
        return implode(',', $values);
185
    }
186
187
    /**
188
     * @param string $value
189
     */
190
    protected function normalizeAssignedTerms($value): string
191
    {
192
        $values = glsr(Sanitizer::class)->sanitizeTermIds($value);
193
        $values = glsr(Multilingual::class)->getTermIdsForAllLanguages($values);
194
        return implode(',', $values);
195
    }
196
197
    /**
198
     * @param string $value
199
     */
200
    protected function normalizeAssignedUsers($value): string
201
    {
202
        $values = glsr(Sanitizer::class)->sanitizeUserIds($value);
203
        return implode(',', $values);
204
    }
205
206
    protected function normalizeClass($value): string
207
    {
208
        $from = Str::dashCase("{$this->from}-{$this->tag}");
209
        return glsr(Sanitizer::class)->sanitizeAttrClass("{$from} {$value}");
210
    }
211
212
    /**
213
     * @param string|array $value
214
     */
215
    protected function normalizeHide($value): array
216
    {
217 8
        $hideKeys = array_keys($this->options('hide'));
218
        return array_filter(Cast::toArray($value),
219 8
            fn ($value) => in_array($value, $hideKeys)
220 8
        );
221 8
    }
222
223
    /**
224
     * @param string $value
225
     */
226
    protected function normalizeLabels($value): array
227
    {
228
        $defaults = [
229
            __('Excellent', 'site-reviews'),
230
            __('Very good', 'site-reviews'),
231
            __('Average', 'site-reviews'),
232
            __('Poor', 'site-reviews'),
233
            __('Terrible', 'site-reviews'),
234
        ];
235
        $maxRating = Rating::max();
236
        $defaults = array_pad(array_slice($defaults, 0, $maxRating), $maxRating, '');
237
        $labels = array_map('trim', explode(',', $value));
238
        foreach ($defaults as $i => $label) {
239
            if (!empty($labels[$i])) {
240
                $defaults[$i] = $labels[$i];
241
            }
242
        }
243
        return array_combine(range($maxRating, 1), $defaults);
244
    }
245
}
246