Widget   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 3
Bugs 1 Features 0
Metric Value
wmc 16
eloc 61
dl 0
loc 123
ccs 0
cts 48
cp 0
rs 10
c 3
b 1
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A normalizeArgs() 0 10 1
A update() 0 3 1
A normalizeInstance() 0 5 1
A form() 0 34 4
A widget() 0 8 2
A __construct() 0 9 2
A renderField() 0 16 5
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Widgets;
4
5
use GeminiLabs\SiteReviews\Arguments;
6
use GeminiLabs\SiteReviews\Contracts\ShortcodeContract;
7
use GeminiLabs\SiteReviews\Helpers\Arr;
8
use GeminiLabs\SiteReviews\Helpers\Str;
9
use GeminiLabs\SiteReviews\Modules\Html\WidgetBuilder;
10
use GeminiLabs\SiteReviews\Modules\Html\WidgetField;
11
12
abstract class Widget extends \WP_Widget
13
{
14
    public ShortcodeContract $shortcode;
15
16
    public function __construct()
17
    {
18
        $this->shortcode = $this->widgetShortcode();
19
        $baseId = glsr()->prefix.Str::dashCase($this->shortcode->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...
20
        $description = $this->shortcode->description ?: $this->shortcode->name;
21
        parent::__construct($baseId, $this->shortcode->name, [
22
            'description' => sprintf('%s: %s', glsr()->name, $description),
23
            'name' => $this->shortcode->name,
24
            'show_instance_in_rest' => true,
25
        ]);
26
    }
27
28
    /**
29
     * @param array $instance
30
     *
31
     * @return string
32
     */
33
    public function form($instance)
34
    {
35
        $instance = $this->normalizeInstance(wp_parse_args($instance));
36
        $notice = _x('This is a legacy widget with limited options, consider switching to the shortcode or block.', 'admin-text', 'site-reviews');
37
        echo glsr(WidgetBuilder::class)->div([
38
            'class' => 'notice notice-alt notice-warning inline',
39
            'style' => 'margin:1em 0;',
40
            'text' => glsr(WidgetBuilder::class)->p($notice),
41
        ]);
42
        $config = wp_parse_args($this->widgetConfig(), [ // prepend
43
            'title' => [
44
                'label' => _x('Widget Title', 'admin-text', 'site-reviews'),
45
                'type' => 'text',
46
            ],
47
        ]);
48
        $config = array_merge($config, [ // append
49
            'id' => [
50
                'description' => esc_html_x('This should be a unique value.', 'admin-text', 'site-reviews'),
51
                'label' => esc_html_x('Custom ID', 'admin-text', 'site-reviews'),
52
                'type' => 'text',
53
            ],
54
            'class' => [
55
                'description' => esc_html_x('Separate multiple classes with spaces.', 'admin-text', 'site-reviews'),
56
                'label' => esc_html_x('Additional CSS classes', 'admin-text', 'site-reviews'),
57
                'type' => 'text',
58
            ],
59
        ]);
60
        foreach ($config as $name => $args) {
61
            if ('type' === $name && empty($args['options'])) {
62
                continue;
63
            }
64
            $this->renderField($name, $args, $instance);
65
        }
66
        return '';
67
    }
68
69
    /**
70
     * @param array $oldInstance
71
     *
72
     * @return array
73
     */
74
    public function update($instance, $oldInstance)
75
    {
76
        return $this->normalizeInstance(wp_parse_args($instance));
77
    }
78
79
    /**
80
     * @param array $args
81
     * @param array $instance
82
     *
83
     * @return void
84
     */
85
    public function widget($args, $instance)
86
    {
87
        $args = $this->normalizeArgs(wp_parse_args($args));
88
        $html = $this->shortcode->build($instance, 'widget');
89
        $title = !empty($this->shortcode->args['title'])
90
            ? $args->before_title.$this->shortcode->args['title'].$args->after_title
91
            : '';
92
        echo $args->before_widget.$title.$html.$args->after_widget;
93
    }
94
95
    protected function normalizeArgs(array $args): Arguments
96
    {
97
        $args = wp_parse_args($args, [
98
            'before_widget' => '',
99
            'after_widget' => '',
100
            'before_title' => '<h2 class="glsr-title">',
101
            'after_title' => '</h2>',
102
        ]);
103
        $args = glsr()->filterArray('widget/args', $args, $this->shortcode->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...
104
        return glsr()->args($args);
105
    }
106
107
    protected function normalizeInstance(array $instance): array
108
    {
109
        $atts = $this->shortcode->defaults()->unguardedMerge($instance);
110
        $pairs = array_fill_keys(array_keys($instance), '');
111
        return shortcode_atts($pairs, $atts);
112
    }
113
114
    protected function renderField(string $name, array $args, array $instance = []): void
115
    {
116
        if (isset($args['name']) && !isset($args['type'])) {
117
            $args['type'] = $name; // @todo remove in v8.0
118
        }
119
        $field = new WidgetField(wp_parse_args($args, compact('name')));
120
        if (!$field->isValid()) {
121
            return;
122
        }
123
        $value = Arr::get($instance, $field->original_name); // @phpstan-ignore-line
124
        if ('' !== $value) {
125
            $field->value = $value; // @phpstan-ignore-line
126
        }
127
        $field->id = $this->get_field_id($field->name); // @phpstan-ignore-line
128
        $field->name = $this->get_field_name($field->name); // @phpstan-ignore-line
129
        $field->render();
130
    }
131
132
    abstract protected function widgetConfig(): array;
133
134
    abstract protected function widgetShortcode(): ShortcodeContract;
135
}
136