Test Failed
Push — develop ( c74868...df43c9 )
by Paul
09:13
created

Transformer::processConfig()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 35
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 26
c 1
b 0
f 1
dl 0
loc 35
rs 8.8817
cc 6
nc 7
nop 1
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Integrations\Breakdance;
4
5
use GeminiLabs\SiteReviews\Helper;
6
use GeminiLabs\SiteReviews\Helpers\Arr;
7
use GeminiLabs\SiteReviews\Helpers\Str;
8
use GeminiLabs\SiteReviews\Integrations\Breakdance\Defaults\ControlDefaults;
9
10
use function Breakdance\Elements\c;
0 ignored issues
show
introduced by
The function Breakdance\Elements\c was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
11
12
class Transformer extends \ArrayObject
13
{
14
    public array $alerts;
15
    public array $popouts;
16
    public array $sections;
17
    public string $shortcode;
18
19
    public function __construct(array $config, string $shortcode = '')
20
    {
21
        $this->alerts = $this->controlAlerts();
22
        $this->popouts = $this->controlPopouts();
23
        $this->sections = $this->controlSections();
24
        $this->shortcode = $shortcode;
25
        parent::__construct($this->processConfig($config),
26
            \ArrayObject::STD_PROP_LIST | \ArrayObject::ARRAY_AS_PROPS
27
        );
28
    }
29
30
    public function control(array $args): array
31
    {
32
        $control = glsr(ControlDefaults::class)->restrict($args);
33
        return c(
0 ignored issues
show
Bug Best Practice introduced by
The expression return c($control['slug'..., $control['keywords']) returns the type string which is incompatible with the type-hinted return array.
Loading history...
34
            $control['slug'],
35
            $control['label'],
0 ignored issues
show
Unused Code introduced by
The call to c() has too many arguments starting with $control['label']. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

35
        return /** @scrutinizer ignore-call */ c(

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
36
            $control['children'],
37
            $control['options'],
38
            $control['enableMediaQueries'],
39
            $control['enableHover'],
40
            $control['keywords']
41
        );
42
    }
43
44
    public function description(array $args, string $style = 'default'): array
45
    {
46
        if (empty($args['description'])) {
47
            return [];
48
        }
49
        return $this->control([
50
            'options' => [
51
                'alertBoxOptions' => [
52
                    'style' => $style,
53
                    'content' => $args['description'],
54
                ],
55
                'layout' => 'vertical',
56
                'type' => 'alert_box',
57
            ],
58
            'slug' => "{$args['slug']}_description_alert",
59
        ]);
60
    }
61
62
    public function popout(string $slug, array $children = []): array
63
    {
64
        return $this->control([
65
            'children' => $children,
66
            'label' => $this->popouts[$slug] ?? Str::titleCase($slug),
67
            'slug' => $slug,
68
            'options' => [
69
                'type' => 'section',
70
                'sectionOptions' => [
71
                    'type' => 'popout',
72
                ],
73
            ],
74
        ]);
75
    }
76
77
    public function section(string $slug, array $children = []): array
78
    {
79
        return $this->control([
80
            'children' => $children,
81
            'label' => $this->sections[$slug] ?? Str::titleCase($slug),
82
            'slug' => $slug,
83
            'options' => [
84
                'layout' => 'vertical',
85
                'type' => 'section',
86
            ],
87
        ]);
88
    }
89
90
    protected function controlAlerts(): array
91
    {
92
        $alerts = [
93
            'schema' => 'warning',
94
        ];
95
        return glsr()->filterArray('breakdance/controls/alerts', $alerts, $this->shortcode);
96
    }
97
98
    protected function controlPopouts(): array
99
    {
100
        $popouts = [
101
            'display' => esc_html_x('Display', 'admin-text', 'site-reviews'),
102
            'filters' => esc_html_x('Filters', 'admin-text', 'site-reviews'),
103
            'hide' => esc_html_x('Hide', 'admin-text', 'site-reviews'),
104
            'schema' => esc_html_x('Schema', 'admin-text', 'site-reviews'),
105
            'text' => esc_html_x('Text', 'admin-text', 'site-reviews'),
106
        ];
107
        return glsr()->filterArray('breakdance/controls/popouts', $popouts, $this->shortcode);
108
    }
109
110
    protected function controlSections(): array
111
    {
112
        $sections = [ // order is intentional
113
            'general' => esc_html_x('General', 'admin-text', 'site-reviews'),
114
            'advanced' => esc_html_x('Advanced', 'admin-text', 'site-reviews'),
115
        ];
116
        return glsr()->filterArray('breakdance/controls/sections', $sections, $this->shortcode);
117
    }
118
119
    protected function pathPrefix(string $group): string
120
    {
121
        if (array_key_exists($group, $this->sections)) {
122
            return $group;
123
        }
124
        if (array_key_exists($group, $this->popouts)) {
125
            return "general.popout_{$group}";
126
        }
127
        return 'general';
128
    }
129
130
    /**
131
     * @return array[] Each array has a "path" and "control" key
132
     */
133
    protected function processConfig(array $config): array
134
    {
135
        $controls = [];
136
        foreach ($config as $slug => $args) {
137
            $args = wp_parse_args($args, [
138
                'description' => '',
139
                'group' => 'general',
140
                'label' => '',
141
                'slug' => $slug,
142
                'type' => 'text',
143
            ]);
144
            $path = $this->pathPrefix($slug);
145
            $method = Helper::buildMethodName('transform', $args['type']);
146
            if (method_exists($this, $method)) {
147
                $control = call_user_func([$this, $method], $args);
148
            } else {
149
                if (!isset($args['options']['type'])) {
150
                    $args['options'] = ['type' => $args['type']];
151
                }
152
                $control = $this->control($args);
153
            }
154
            $controls[$slug] = [
155
                'control' => $control,
156
                'path' => "{$path}.{$slug}",
157
            ];
158
            if (!empty($args['description']) && !empty($control)) {
159
                $control = $this->description($args, $this->alerts[$slug] ?? 'default');
160
                $slug = "{$slug}_description_alert";
161
                $controls[$slug] = [
162
                    'control' => $control,
163
                    'path' => "{$path}.{$slug}",
164
                ];
165
            }
166
        }
167
        return glsr()->filterArray('breakdance/controls', $controls, $this->shortcode);
168
    }
169
170
    protected function transformCheckbox(array $args): array
171
    {
172
        $control = $this->control([
173
            'label' => $args['label'],
174
            'slug' => $args['slug'],
175
            'options' => [
176
                'layout' => 'inline',
177
                'type' => 'toggle',
178
            ],
179
        ]);
180
        if (!empty($args['options'])) {
181
            $control['options']['type'] = 'section';
182
            foreach ($args['options'] as $slug => $label) {
183
                $control['children'][] = $this->control([
184
                    'label' => $label,
185
                    'slug' => $slug,
186
                    'options' => [
187
                        'layout' => 'inline',
188
                        'type' => 'toggle',
189
                    ],
190
                ]);
191
            }
192
        }
193
        return $control;
194
    }
195
196
    protected function transformNumber(array $args): array
197
    {
198
        return $this->control([
199
            'slug' => $args['slug'],
200
            'label' => $args['label'],
201
            'options' => [
202
                'layout' => 'inline',
203
                'type' => 'number',
204
                'rangeOptions' => [
205
                    'min' => Arr::getAs('int', $args, 'min', 0),
206
                    'max' => Arr::getAs('int', $args, 'max', 1),
207
                    'step' => Arr::getAs('int', $args, 'step', 1),
208
                ],
209
            ],
210
        ]);
211
    }
212
213
    protected function transformSelect(array $args): array
214
    {
215
        $control = $this->control([
216
            'label' => $args['label'],
217
            'slug' => $args['slug'],
218
            'options' => [
219
                'layout' => 'vertical',
220
                'placeholder' => $args['placeholder'] ?? esc_html_x('Select...', 'admin-text', 'site-reviews'),
221
                'type' => 'dropdown',
222
            ],
223
        ]);
224
        if (!isset($args['options'])) {
225
            // Unfortunately we can't use this yet because Breakdance does not support
226
            // AJAX searching in multiselect controls.
227
            // $control['options']['type'] = 'multiselect';
228
            // $control['options']['searchable'] = true;
229
            // $control['options']['multiselectOptions']['populate'] = [
230
            //     'fetchDataAction' => glsr()->prefix.'breakdance_'.$args['slug'],
231
            //     'fetchContextPath' => 'content.general.'.$args['slug'],
232
            // ];
233
            $control['options']['type'] = 'post_chooser';
234
            $control['options']['postChooserOptions'] = [
235
                'multiple' => $args['multiple'] ?? false,
236
                'postType' => glsr()->prefix.$args['slug'],
237
                'showThumbnails' => in_array($args['slug'], [
238
                    'assigned_posts',
239
                    'assigned_users',
240
                    'author',
241
                ]),
242
            ];
243
            return $control;
244
        }
245
        if (!empty($args['options'])) {
246
            $callback = fn ($value, $text) => compact('text', 'value');
247
            $items = array_map($callback, array_keys($args['options']), $args['options']);
248
            $control['options']['items'] = $items;
249
            return $control;
250
        }
251
        return [];
252
    }
253
254
    protected function transformText(array $args): array
255
    {
256
        return $this->control([
257
            'label' => $args['label'],
258
            'slug' => $args['slug'],
259
            'options' => [
260
                'layout' => 'vertical',
261
                'type' => 'text',
262
            ],
263
        ]);
264
    }
265
}
266