Test Failed
Push — develop ( 11959d...0f24e8 )
by Paul
09:06
created

ElementorWidget::get_settings_for_display()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 7
c 1
b 1
f 0
dl 0
loc 10
rs 10
cc 2
nc 2
nop 1
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Integrations\Elementor\Widgets;
4
5
use Elementor\Controls_Manager;
6
use Elementor\Widget_Base;
7
use GeminiLabs\SiteReviews\Helpers\Arr;
8
use GeminiLabs\SiteReviews\Integrations\Elementor\Defaults\ControlDefaults;
9
use GeminiLabs\SiteReviews\Integrations\IntegrationShortcode;
10
11
abstract class ElementorWidget extends Widget_Base
12
{
13
    use IntegrationShortcode;
14
15
    protected bool $hide_if_all_fields_hidden = true;
16
17
    public function get_categories(): array
18
    {
19
        return [glsr()->id];
20
    }
21
22
    public function get_icon(): string
23
    {
24
        return 'eicon-star-o';
25
    }
26
27
    public function get_name(): string
28
    {
29
        return $this->shortcodeInstance()->tag;
0 ignored issues
show
Bug introduced by
Accessing tag on the interface GeminiLabs\SiteReviews\Contracts\ShortcodeContract suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
30
    }
31
32
    /**
33
     * Elementor throws a JS error when removing a widget from the page if it
34
     * has a control with "id" as the name. To fix this, we transformed "id"
35
     * to "shortcode_id" and "class" to "shortcode_class" (just in case).
36
     * 
37
     * When the widget is displayed, we need to convert the setting keys back
38
     * to their original names.
39
     * 
40
     * @param string $settingKey
41
     *
42
     * @return mixed
43
     */
44
    public function get_settings_for_display($settingKey = null)
45
    {
46
        $settings = parent::get_settings_for_display();
47
        $settings['class'] = $settings['shortcode_class']; // because Elementor throws a JS error for these
48
        $settings['id'] = $settings['shortcode_id']; // because Elementor throws a JS error for these
49
        $settings = glsr()->filterArray('elementor/display/settings', $settings, $this);
50
        if ($settingKey) {
51
            return Arr::get($settings, $settingKey);
52
        }
53
        return $settings;
54
    }
55
56
    public function get_title(): string
57
    {
58
        return $this->shortcodeInstance()->name;
59
    }
60
61
    protected function controlGroups(): array
62
    {
63
        return [
64
            'general' => [
65
                'controls' => [],
66
                'label' => _x('General', 'admin-text', 'site-reviews'),
67
                'tab' => Controls_Manager::TAB_CONTENT,
68
            ],
69
            'advanced' => [
70
                'controls' => [],
71
                'label' => _x('Advanced', 'admin-text', 'site-reviews'),
72
                'tab' => Controls_Manager::TAB_CONTENT,
73
            ],
74
            'design' => [
75
                'controls' => [],
76
                'label' => _x('Design', 'admin-text', 'site-reviews'),
77
                'tab' => Controls_Manager::TAB_STYLE,
78
            ],
79
        ];
80
    }
81
82
    protected function controlHeadings(): array
83
    {
84
        return [
85
            'display' => esc_html_x('Display', 'admin-text', 'site-reviews'),
86
            'hide' => esc_html_x('Hide', 'admin-text', 'site-reviews'),
87
            'schema' => esc_html_x('Schema', 'admin-text', 'site-reviews'),
88
            'text' => esc_html_x('Text', 'admin-text', 'site-reviews'),
89
        ];
90
    }
91
92
    protected function controlSections(): array
93
    {
94
        $controls = array_merge(
95
            array_map(fn ($control) => wp_parse_args($control, ['group' => 'general']), $this->settingsConfig()),
96
            array_map(fn ($control) => wp_parse_args($control, ['group' => 'design']), $this->styleConfig()),
97
        );
98
        $groups = $this->controlGroups();
99
        $headings = $this->controlHeadings();
100
        foreach ($controls as $key => $control) {
101
            $group = $control['group'] ?? '';
102
            $heading = $group;
103
            if (!array_key_exists($group, $groups)) {
104
                $group = 'general';
105
            }
106
            $control = $this->transformControl($key, $control);
107
            if (!array_key_exists($heading, $headings)) {
108
                $groups[$group]['controls'][$control['name']] = $control;
109
                continue;
110
            }
111
            if (!array_key_exists("separator_{$heading}", $groups[$group]['controls'])) {
112
                $groups[$group]['controls']["separator_{$heading}"] = [
113
                    'type' => Controls_Manager::HEADING,
114
                    'label' => $headings[$heading],
115
                    'separator' => 'before',
116
                ];
117
            }
118
            $groups[$group]['controls'][$control['name']] = $control;
119
        }
120
        return $groups;
121
    }
122
123
    protected function register_controls(): void
124
    {
125
        $sections = $this->controlSections();
126
        $sections = glsr()->filterArray('elementor/register/controls', $sections, $this);
127
        foreach ($sections as $sectionId => $args) {
128
            $controls = array_filter($args['controls'] ?? []);
129
            if (empty($controls)) {
130
                continue;
131
            }
132
            unset($args['controls']);
133
            $this->start_controls_section($sectionId, $args);
134
            $this->registerControlsForSection($controls);
135
            $this->end_controls_section();
136
        }
137
    }
138
139
    protected function registerControlsForSection(array $controls): void
140
    {
141
        $groupTypes = Controls_Manager::get_groups_names();
142
        foreach ($controls as $controlId => $args) {
143
            if (!isset($args['type'])) {
144
                continue;
145
            }
146
            if (Controls_Manager::SELECT2 === $args['type'] && empty($args['options'])) {
147
                continue; // skip select controls with empty options
148
            }
149
            if (in_array($args['type'], $groupTypes)) {
150
                $this->add_group_control($args['type'], $args);
151
                continue;
152
            }
153
            if ($args['is_responsive'] ?? false) { // for responsive controls
154
                $this->add_responsive_control($controlId, $args);
155
                continue;
156
            }
157
            $this->add_control($controlId, $args);
158
        }
159
    }
160
161
    protected function render(): void
162
    {
163
        $args = $this->get_settings_for_display();
164
        if ($this->hide_if_all_fields_hidden && !$this->shortcodeInstance()->hasVisibleFields($args)) {
165
            return;
166
        }
167
        $html = $this->shortcodeInstance()->build($args, 'elementor');
168
        $html = str_replace('class="glsr-fallback">', 'class="glsr-fallback" style="display:none;">', $html);
169
        echo $html;
170
    }
171
172
    protected function settingsConfig(): array
173
    {
174
        return $this->shortcodeInstance()->settings();
175
    }
176
177
    protected function styleConfig(): array
178
    {
179
        return [];
180
    }
181
182
    protected function transformControl(string $name, array $args): array
183
    {
184
        return glsr(ControlDefaults::class)->merge(
185
            wp_parse_args(compact('name'), $args)
186
        );
187
    }
188
}
189