Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
75.00% covered (warning)
75.00%
6 / 8
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Widget_Type
75.00% covered (warning)
75.00%
6 / 8
33.33% covered (danger)
33.33%
1 / 3
5.39
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 is_renderable
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 set_props
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
3.07
1<?php
2/**
3 * Widget Types API: Widget_Type class.
4 *
5 * Premium Analytics ships its own copy of the dashboard widget-type registry
6 * (the core/Gutenberg version lives behind an experimental flag and is not
7 * available in stable WordPress). PA-namespaced so it never collides with a
8 * future core API.
9 *
10 * @package automattic/jetpack-premium-analytics
11 */
12
13namespace Automattic\Jetpack\PremiumAnalytics;
14
15/**
16 * Represents a single dashboard widget type.
17 *
18 * Holds the metadata for a widget discovered by the build pipeline. Stored
19 * inside Widget_Type_Registry once registered, and consumed by host code that
20 * needs to enumerate or look up widget types.
21 *
22 * The shape is intentionally minimal: identity (`name`) plus the script-module
23 * handles the build pipeline produced for the widget. Placement and host
24 * concerns (which page or sidebar uses the widget) live with the consumer, not
25 * on the type definition.
26 */
27#[\AllowDynamicProperties]
28class Widget_Type {
29
30    /**
31     * Allowed values for the `presentation` field. Treated as the single
32     * source of truth across the registry, REST response, and any consumer
33     * that needs to validate or enumerate the set.
34     */
35    const PRESENTATION_VALUES = array( 'framed', 'content-bleed', 'full-bleed' );
36
37    /**
38     * Widget type key. Namespaced identifier, e.g. `jpa/hello-world`.
39     *
40     * @var string
41     */
42    public $name;
43
44    /**
45     * Script-module handle for the widget render module.
46     *
47     * Null when the widget folder did not ship a render entry point at build
48     * time.
49     *
50     * @var string|null
51     */
52    public $render_module = null;
53
54    /**
55     * Script-module handle for the widget metadata module.
56     *
57     * Null when the widget folder did not ship a widget entry point at build
58     * time.
59     *
60     * @var string|null
61     */
62    public $widget_module = null;
63
64    /**
65     * Authoring intent about how the widget wants to render. Static and
66     * declarative; not a user-editable attribute.
67     *
68     * One of {@see self::PRESENTATION_VALUES} (first entry is the default).
69     * Null when the widget did not declare the field.
70     *
71     * @var string|null
72     */
73    public $presentation = null;
74
75    /**
76     * Widget types are grouped into categories to help users browse and
77     * discover them. Static and declarative; not a user-editable attribute.
78     *
79     * Null when the widget did not declare the field.
80     *
81     * @var string|null
82     */
83    public $category = null;
84
85    /**
86     * Human-readable title that names the widget type. Translated
87     * at registration time using the widget's text domain.
88     *
89     * Null when the widget did not declare the field.
90     *
91     * @var string|null
92     */
93    public $title = null;
94
95    /**
96     * Human-readable description of what the widget type does.
97     * Translated at registration time using the widget's text domain.
98     *
99     * Null when the widget did not declare the field.
100     *
101     * @var string|null
102     */
103    public $description = null;
104
105    /**
106     * Contextual help note: `content` plus optional `links`.
107     * Translated at registration time using the widget's text domain.
108     *
109     * Null when the widget did not declare the field.
110     *
111     * @var array|null
112     */
113    public $help = null;
114
115    /**
116     * Registered icon name (`collection/icon-name`), resolved on the client
117     * through the application's icon resolver.
118     *
119     * Null when the widget did not declare the field.
120     *
121     * @var string|null
122     */
123    public $icon = null;
124
125    /**
126     * Declarative actions the widget exposes. Each entry carries `id`,
127     * `label`, `href`, and optional `download`/`openInNewTab`/`icon`/
128     * `relevance`. Labels are translated at registration time using the
129     * widget's text domain.
130     *
131     * Null when the widget did not declare the field.
132     *
133     * @var array|null
134     */
135    public $actions = null;
136
137    /**
138     * Attribute schema, one entry per setting of a widget instance: a DataViews
139     * field in its JSON form, plus the keys the dashboard reads on top of a
140     * field (`relevance`, so far). User-facing strings are translated at
141     * registration time using the widget's text domain.
142     *
143     * Null when the widget did not declare the field.
144     *
145     * @since 0.13.0
146     *
147     * @var array|null
148     */
149    public $attributes = null;
150
151    /**
152     * Alternative terms used to match the widget type when searching,
153     * e.g. "calendar" for an events widget. Translated at registration
154     * time using the widget's text domain.
155     *
156     * Null when the widget did not declare the field.
157     *
158     * @var string[]|null
159     */
160    public $keywords = null;
161
162    /**
163     * Text domain the widget's metadata strings and built bundles are registered under.
164     *
165     * @since 0.9.0
166     *
167     * @var string|null
168     */
169    public $textdomain = null;
170
171    /**
172     * URL of the i18n manifest of the build that serves the widget's modules, for the client to
173     * load their translation catalogs from. Empty for a build whose init module runs on the
174     * dashboard page, which is the package's own.
175     *
176     * @since 0.9.0
177     *
178     * @var string|null
179     */
180    public $i18n_manifest = null;
181
182    /**
183     * Names this widget type registered under before the current one, so a layout persisted
184     * with an old name keeps rendering it. Null when the type was never renamed.
185     *
186     * @since 0.11.0
187     *
188     * @var string[]|null
189     */
190    public $former_names = null;
191
192    /**
193     * Plan feature the widget cannot show anything without, such as `videos`. A plan that lacks
194     * it shows the widget locked. Null when every plan includes the widget.
195     *
196     * @since 0.13.0
197     *
198     * @var string|null
199     */
200    public $plan_feature = null;
201
202    /**
203     * Constructor.
204     *
205     * @param string $name Widget type name including namespace.
206     * @param array  $args Optional. Widget type arguments. Each key is copied
207     *                     onto the corresponding object property. Default empty
208     *                     array.
209     */
210    public function __construct( $name, $args = array() ) {
211        $this->name = $name;
212        $this->set_props( $args );
213    }
214
215    /**
216     * Returns whether this widget type ships a renderable script module.
217     *
218     * @return bool
219     */
220    public function is_renderable() {
221        return ! empty( $this->render_module );
222    }
223
224    /**
225     * Hydrates the widget type properties from the args array.
226     *
227     * @param array $args Widget type arguments.
228     */
229    public function set_props( $args ) {
230        if ( ! is_array( $args ) ) {
231            return;
232        }
233
234        unset( $args['name'] );
235
236        foreach ( $args as $property_name => $property_value ) {
237            $this->$property_name = $property_value;
238        }
239    }
240}