Test Failed
Push — develop ( 86ce5c...8667ea )
by Paul
13:41
created

Shortcode::getAssignedUsersOptions()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
eloc 15
c 0
b 0
f 0
dl 0
loc 21
ccs 0
cts 10
cp 0
rs 9.7666
cc 4
nc 4
nop 1
crap 20
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Shortcodes;
4
5
use GeminiLabs\SiteReviews\Arguments;
6
use GeminiLabs\SiteReviews\Contracts\ShortcodeContract;
7
use GeminiLabs\SiteReviews\Database;
8
use GeminiLabs\SiteReviews\Defaults\DefaultsAbstract;
9
use GeminiLabs\SiteReviews\Defaults\ShortcodeApiFetchDefaults;
10
use GeminiLabs\SiteReviews\Helper;
11
use GeminiLabs\SiteReviews\Helpers\Arr;
12
use GeminiLabs\SiteReviews\Helpers\Cast;
13
use GeminiLabs\SiteReviews\Helpers\Str;
14
use GeminiLabs\SiteReviews\Modules\Html\Builder;
15
use GeminiLabs\SiteReviews\Modules\Multilingual;
16
use GeminiLabs\SiteReviews\Modules\Rating;
17
use GeminiLabs\SiteReviews\Modules\Sanitizer;
18
use GeminiLabs\SiteReviews\Modules\Style;
19
20
abstract class Shortcode implements ShortcodeContract
21
{
22
    public array $args = [];
23
    public string $debug = '';
24 8
    public string $description;
25
    public string $name;
26 8
    public string $shortcode;
27
    public string $type = '';
28
29
    public function __construct()
30
    {
31
        $this->description = $this->shortcodeDescription();
32
        $this->name = $this->shortcodeName();
33
        $this->shortcode = $this->shortcodeTag();
34
    }
35
36
    public function apiFetchResponse(\WP_REST_Request $request): array
37
    {
38
        $args = glsr(ShortcodeApiFetchDefaults::class)->merge($request->get_params());
39
        $args = glsr()->args($args);
40
        $method = Helper::buildMethodName('get', $args->option, 'options');
41
        if (method_exists($this, $method)) {
42
            $values = $this->$method($args);
43
        } else {
44
            $values = glsr()->filterArray('shortcode/api-fetch', [], $args, $request);
45
        }
46
        $results = [];
47
        foreach ($values as $id => $title) {
48
            $results[] = compact('id', 'title');
49
        }
50
        return $results;
51
    }
52
53
    public function attributes(array $values, string $source = 'function'): array
54
    {
55
        $attributes = $this->defaults()->dataAttributes($values);
56
        $attributes = wp_parse_args($attributes, [
57
            'class' => glsr(Style::class)->styleClasses(),
58
            'data-from' => $source,
59
            'data-shortcode' => $this->shortcode,
60
            'id' => Arr::get($values, 'id'),
61
        ]);
62
        unset($attributes['data-id']);
63
        unset($attributes['data-form_id']);
64
        $attributes = glsr()->filterArray("shortcode/{$this->shortcode}/attributes", $attributes, $this);
65
        $attributes = array_map('esc_attr', $attributes);
66
        return $attributes;
67
    }
68
69
    public function build($args = [], string $type = 'shortcode'): string
70
    {
71
        $this->normalize($args, $type);
72
        $template = $this->buildTemplate();
73
        $attributes = $this->attributes($this->args, $type);
74
        $html = glsr(Builder::class)->div($template, $attributes);
75
        return sprintf('%s%s', $this->debug, $html);
76
    }
77
78
    /**
79
     * @param string|array $args
80
     */
81
    public function buildBlock($args = []): string
82
    {
83 8
        return $this->build(wp_parse_args($args), 'block');
84
    }
85 8
86 8
    /**
87
     * @param string|array $args
88
     */
89
    public function buildShortcode($args = []): string
90
    {
91
        return $this->build(wp_parse_args($args), 'shortcode');
92
    }
93
94
    public function defaults(): DefaultsAbstract
95
    {
96
        $classname = str_replace('Shortcodes\\', 'Defaults\\', get_class($this));
97
        $classname = str_replace('Shortcode', 'Defaults', $classname);
98
        return glsr($classname);
99
    }
100
101
    public function getConfig(): array
102
    {
103
        $config = $this->config();
104
        return glsr()->filterArray('shortcode/config', $config, $this->shortcode, $this);
105
    }
106
107
    public function getAssignedPostsOptions(Arguments $args): array
108
    {
109
        $results = [];
110
        if (!empty($args->search)
111
            && !in_array($args->search, ['post_id', 'parent_id'])) {
112
            $results += glsr(Database::class)->posts([
113
                'posts_per_page' => 50,
114
                's' => $args->search,
115
            ]);
116
        }
117
        $include = array_filter($args->include, fn ($id) => !array_key_exists($id, $results));
118
        if (!empty($include)) {
119
            $results += glsr(Database::class)->posts([
120
                'post__in' => $include,
121
            ]);
122
        }
123
        return [
124
            'post_id' => esc_html_x('The Current Page', 'admin-text', 'site-reviews'),
125
            'parent_id' => esc_html_x('The Parent Page', 'admin-text', 'site-reviews'),
126
        ] + $results;
127
    }
128
129
    public function getAssignedTermsOptions(Arguments $args): array
130
    {
131
        $results = [];
132
        if (!empty($args->search)) {
133
            $results += glsr(Database::class)->terms([
134
                'number' => 50,
135
                'search' => $args->search,
136
            ]);
137
        }
138
        if (!empty($args->include)) {
139
            $results += glsr(Database::class)->terms([
140
                'term_taxonomy_id' => $args->include,
141
            ]);
142
        }
143
        return $results;
144
    }
145
146
    public function getAssignedUsersOptions(Arguments $args): array
147
    {
148
        $results = [];
149
        if (!empty($args->search)
150
            && !in_array($args->search, ['author_id', 'profile_id', 'user_id'])) {
151
            $results += glsr(Database::class)->users([
152
                'number' => 50,
153
                'search_wild' => $args->search,
154
            ]);
155
        }
156
        $include = array_filter($args->include, fn ($id) => !array_key_exists($id, $results));
157
        if (!empty($include)) {
158
            $results += glsr(Database::class)->users([
159
                'include' => $include,
160
            ]);
161
        }
162
        return [
163
            'user_id' => esc_html_x('The Logged In User', 'admin-text', 'site-reviews'),
164
            'author_id' => esc_html_x('The Page Author', 'admin-text', 'site-reviews'),
165
            'profile_id' => esc_html_x('The Profile User', 'admin-text', 'site-reviews'),
166
        ] + $results;
167
    }
168
169
    public function getDisplayOptions(): array
170
    {
171
        $options = $this->displayOptions();
172
        return glsr()->filterArray('shortcode/display-options', $options, $this->shortcode, $this);
173
    }
174
175
    public function getHideOptions(): array
176
    {
177
        $options = $this->hideOptions();
178
        return glsr()->filterArray('shortcode/hide-options', $options, $this->shortcode, $this);
179
    }
180
181
    public function getPaginationOptions(): array
182
    {
183
        return [
184
            'loadmore' => _x('Load More Button', 'admin-text', 'site-reviews'),
185
            'ajax' => _x('Pagination Links (AJAX)', 'admin-text', 'site-reviews'),
186
            '1' => _x('Pagination Links (with page reload)', 'admin-text', 'site-reviews'),
187
        ];
188
    }
189
190
    public function getPostIdOptions(Arguments $args): array
191
    {
192
        glsr_log($args);
193
        $results = [];
194
        if (!empty($args->search)) {
195
            $results += glsr(Database::class)->posts([
196
                'post_type' => glsr()->post_type,
197
                'posts_per_page' => 50,
198
                's' => $args->search,
199
            ]);
200
        }
201
        $include = array_filter($args->include, fn ($id) => !array_key_exists($id, $results));
202
        if (!empty($include)) {
203
            $results += glsr(Database::class)->posts([
204
                'post_type' => glsr()->post_type,
205
                'post__in' => $include,
206
            ]);
207
        }
208
        return $results;
209
    }
210
211
    public function getTermsOptions(): array
212
    {
213
        return [
214
            '1' => _x('Terms were accepted', 'admin-text', 'site-reviews'),
215
            '0' => _x('Terms were not accepted', 'admin-text', 'site-reviews'),
216
        ];
217 8
    }
218
219 8
    public function getTypeOptions(): array
220 8
    {
221 8
        $types = glsr()->retrieveAs('array', 'review_types', []);
222
        return 1 < count($types) ? $types : [];
223
    }
224
225
    public function hasVisibleFields(array $args = []): bool
226
    {
227
        if (!empty($args)) {
228
            $this->normalize($args);
229
        }
230
        $defaults = $this->getHideOptions();
231
        $hide = $this->args['hide'] ?? [];
232
        $hide = array_flip(Arr::consolidate($hide));
233
        unset($defaults['if_empty'], $hide['if_empty']);
234
        return !empty(array_diff_key($defaults, $hide));
235
    }
236
237
    /**
238
     * @return static
239
     */
240
    public function normalize(array $args, string $type = '')
241
    {
242
        if (!empty($type)) {
243
            $this->type = $type;
244
        }
245
        $args = glsr()->filterArray('shortcode/args', $args, $this->shortcode);
246
        $args = $this->defaults()->unguardedRestrict($args);
247
        foreach ($args as $key => &$value) {
248
            $method = Helper::buildMethodName('normalize', $key);
249
            if (method_exists($this, $method)) {
250
                $value = call_user_func([$this, $method], $value, $args);
251
            }
252
        }
253
        $this->args = $args;
254
        return $this;
255
    }
256
257
    public function register(): void
258
    {
259
        if (!function_exists('add_shortcode')) {
260
            return;
261
        }
262
        $shortcode = (new \ReflectionClass($this))->getShortName();
263
        $shortcode = Str::snakeCase($shortcode);
264
        $shortcode = str_replace('_shortcode', '', $shortcode);
265
        add_shortcode($shortcode, [$this, 'buildShortcode']);
266
        glsr()->append('shortcodes', get_class($this), $shortcode);
267
    }
268
269
    protected function config(): array
270
    {
271
        return [];
272
    }
273
274
    protected function debug(array $data = []): void
275
    {
276
        if (empty($this->args['debug']) || 'shortcode' !== $this->type) {
277
            return;
278
        }
279
        $data = wp_parse_args($data, [
280
            'args' => $this->args,
281
            'shortcode' => $this->shortcode,
282
        ]);
283
        ksort($data);
284
        ob_start();
285
        glsr_debug($data);
286
        $this->debug = ob_get_clean();
287
    }
288
289
    protected function displayOptions(): array
290
    {
291
        return [];
292
    }
293
294
    protected function hideOptions(): array
295
    {
296
        return [];
297
    }
298
299
    protected function maxRating(): int
300
    {
301
        return Cast::toInt(glsr()->constant('MAX_RATING', Rating::class));
302
    }
303
304
    protected function minRating(): int
305
    {
306
        return Cast::toInt(glsr()->constant('MIN_RATING', Rating::class));
307
    }
308
309
    /**
310
     * @param string $value
311
     */
312
    protected function normalizeAssignedPosts($value): string
313
    {
314
        $values = Cast::toArray($value);
315
        $postTypes = [];
316
        foreach ($values as $postType) {
317
            if (!is_numeric($postType) && post_type_exists((string) $postType)) {
318
                $postTypes[] = $postType;
319
            }
320
        }
321
        $values = glsr(Sanitizer::class)->sanitizePostIds($values);
322
        $values = glsr(Multilingual::class)->getPostIdsForAllLanguages($values);
323
        $values = array_merge($values, $postTypes);
324
        return implode(',', $values);
325
    }
326
327
    /**
328
     * @param string $value
329
     */
330
    protected function normalizeAssignedTerms($value): string
331
    {
332
        $values = glsr(Sanitizer::class)->sanitizeTermIds($value);
333
        $values = glsr(Multilingual::class)->getTermIdsForAllLanguages($values);
334
        return implode(',', $values);
335
    }
336
337
    /**
338
     * @param string $value
339
     */
340
    protected function normalizeAssignedUsers($value): string
341
    {
342
        $values = glsr(Sanitizer::class)->sanitizeUserIds($value);
343
        return implode(',', $values);
344
    }
345
346
    /**
347
     * @param string|array $value
348
     */
349
    protected function normalizeHide($value): array
350
    {
351
        $hideKeys = array_keys($this->getHideOptions());
352
        return array_filter(Cast::toArray($value),
353
            fn ($value) => in_array($value, $hideKeys)
354
        );
355
    }
356
357
    /**
358
     * @param string $value
359
     */
360
    protected function normalizeLabels($value): array
361
    {
362
        $defaults = [
363
            __('Excellent', 'site-reviews'),
364
            __('Very good', 'site-reviews'),
365
            __('Average', 'site-reviews'),
366
            __('Poor', 'site-reviews'),
367
            __('Terrible', 'site-reviews'),
368
        ];
369
        $maxRating = $this->maxRating();
370
        $defaults = array_pad(array_slice($defaults, 0, $maxRating), $maxRating, '');
371
        $labels = array_map('trim', explode(',', $value));
372
        foreach ($defaults as $i => $label) {
373
            if (!empty($labels[$i])) {
374
                $defaults[$i] = $labels[$i];
375
            }
376
        }
377
        return array_combine(range($maxRating, 1), $defaults);
378
    }
379
380
    /**
381
     * @todo make this an abstract method in v8
382
     */
383
    protected function shortcodeDescription(): string
384
    {
385
        return '';
386
    }
387
388
    /**
389
     * @todo make this an abstract method in v8
390
     */
391
    protected function shortcodeName(): string
392
    {
393
        return '';
394
    }
395
396
    protected function shortcodeTag(): string
397
    {
398
        return Str::snakeCase(
399
            str_replace('Shortcode', '', (new \ReflectionClass($this))->getShortName())
400
        );
401
    }
402
}
403