PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-premium-analytics / src / widget-availability.php
jetpack / jetpack_vendor / automattic / jetpack-premium-analytics / src Last commit date
REST 2 weeks ago Reports 1 week ago Sync 2 weeks ago class-analytics.php 3 days ago class-capabilities.php 2 weeks ago class-connection-configuration.php 2 weeks ago class-dashboard-section-registry.php 2 weeks ago class-dashboard-section.php 3 days ago class-dashboard-support-routes.php 1 week ago class-jetpack-stats-tracker.php 2 weeks ago class-notices.php 2 weeks ago class-widget-type-registry.php 2 weeks ago class-widget-type.php 2 weeks ago class-woocommerce-analytics-tracker.php 2 weeks ago csv-exports.php 2 weeks ago dashboard-grammar.php 2 weeks ago dashboard-layout.php 3 days ago dashboard-sections.php 3 days ago rest-namespace.php 2 weeks ago videopress-availability.php 3 days ago widget-availability.php 3 days ago widget-i18n.json 2 weeks ago widget-modules.php 3 days ago widget-type-support.php 3 days ago widget-types.php 2 weeks ago
widget-availability.php
219 lines
1 <?php
2 /**
3 * Widget availability policy (consumer layer).
4 *
5 * Premium Analytics' policy over the neutral filters in widget-types.php:
6 * availability is the consumer's job, core only offers the hooks.
7 *
8 * Policies are hooked on the registry-time filter (a hard hide, which keeps
9 * every registry consumer correct without a filtered accessor): developer-only
10 * widget types are never registered in production, Simple-only types are only
11 * registered on WPCOM Simple, and commerce categories require their plugins.
12 *
13 * @package automattic/jetpack-premium-analytics
14 */
15
16 namespace Automattic\Jetpack\PremiumAnalytics;
17
18 require_once __DIR__ . '/widget-types.php';
19 require_once __DIR__ . '/widget-type-support.php';
20
21 /**
22 * Widget categories that are only meaningful with WooCommerce active.
23 */
24 const WOOCOMMERCE_WIDGET_CATEGORIES = array( 'store', 'orders', 'coupons' );
25
26 /**
27 * Widget categories that are only meaningful with WooCommerce Bookings active.
28 *
29 * Checked independently of WOOCOMMERCE_WIDGET_CATEGORIES: the Bookings
30 * extension cannot run without WooCommerce, so its presence implies both.
31 */
32 const WOOCOMMERCE_BOOKINGS_WIDGET_CATEGORIES = array( 'bookings' );
33
34 /**
35 * Widget categories whose data counts as a store report.
36 *
37 * The membership rule is the data source, not the subject matter: every
38 * category here reaches WPCOM through the proxy's `analytics` prefix, which
39 * {@see \Automattic\Jetpack\PremiumAnalytics\REST\Api_Proxy_Controller} gates
40 * on `view_woocommerce_reports`. That is why `visitors` is in the list: its
41 * widgets read `sessions/…` from the same prefix.
42 */
43 const STORE_REPORT_WIDGET_CATEGORIES = array( 'store', 'orders', 'coupons', 'bookings', 'visitors' );
44
45 /**
46 * Removes developer-only candidates in production.
47 *
48 * Split from the hook callback so both branches are testable without touching
49 * the global environment.
50 *
51 * @param array $widget_candidates Manifest candidates, each with a `name` and `category`.
52 * @param string $environment Site environment type.
53 * @return array The candidates, minus developer-only types in production.
54 */
55 function remove_dev_only_widget_types( $widget_candidates, $environment ) {
56 if ( 'production' !== $environment ) {
57 return $widget_candidates;
58 }
59
60 return array_values(
61 array_filter(
62 $widget_candidates,
63 static function ( $widget ) {
64 return 'developer' !== ( $widget['category'] ?? '' );
65 }
66 )
67 );
68 }
69
70 /**
71 * Registry-time callback: hides developer-only types in production.
72 *
73 * Defaults to `production`; a site opts in via `WP_ENVIRONMENT_TYPE`
74 * (`local`, `development`, `staging`).
75 *
76 * @param array $widget_candidates Manifest candidates.
77 * @return array The candidates, minus developer-only types in production.
78 */
79 function filter_registrable_widget_types_by_environment( $widget_candidates ) {
80 return remove_dev_only_widget_types( $widget_candidates, wp_get_environment_type() );
81 }
82
83 add_filter( REGISTRABLE_WIDGET_TYPES_FILTER, __NAMESPACE__ . '\\filter_registrable_widget_types_by_environment' );
84
85 /**
86 * Applies shared type-level availability at registry time.
87 *
88 * @param array $widget_candidates Manifest candidates.
89 * @return array Filtered candidates.
90 */
91 function filter_registrable_widget_types_by_availability( $widget_candidates ) {
92 return remove_unsupported_widget_items(
93 $widget_candidates,
94 'name',
95 get_widget_support_context()
96 );
97 }
98
99 add_filter( REGISTRABLE_WIDGET_TYPES_FILTER, __NAMESPACE__ . '\\filter_registrable_widget_types_by_availability' );
100
101 /**
102 * Removes candidates whose commerce category lacks its backing plugin.
103 *
104 * Split from the hook callback so the branches are testable without touching
105 * global plugin state.
106 *
107 * @param array $widget_candidates Manifest candidates, each with a `category`.
108 * @param bool $woocommerce_available Whether WooCommerce is available.
109 * @param bool $bookings_available Whether WooCommerce Bookings is available.
110 * @return array The candidates, minus commerce categories missing their plugin.
111 */
112 function remove_plugin_gated_widget_types( $widget_candidates, $woocommerce_available, $bookings_available ) {
113 return array_values(
114 array_filter(
115 $widget_candidates,
116 static function ( $widget ) use ( $woocommerce_available, $bookings_available ) {
117 $category = $widget['category'] ?? '';
118
119 if ( ! $woocommerce_available && in_array( $category, WOOCOMMERCE_WIDGET_CATEGORIES, true ) ) {
120 return false;
121 }
122
123 if ( ! $bookings_available && in_array( $category, WOOCOMMERCE_BOOKINGS_WIDGET_CATEGORIES, true ) ) {
124 return false;
125 }
126
127 return true;
128 }
129 )
130 );
131 }
132
133 /**
134 * Whether the WooCommerce Bookings extension is active.
135 *
136 * Mirrors the detection in woocommerce-analytics' Bookings sync module;
137 * `is_plugin_active()` only exists in admin contexts, hence the guard.
138 *
139 * @return bool Whether WooCommerce Bookings was detected in the current request.
140 */
141 function is_bookings_plugin_active() {
142 return class_exists( 'WC_Bookings' )
143 || ( function_exists( 'is_plugin_active' ) && \is_plugin_active( 'woocommerce-bookings/woocommerce-bookings.php' ) );
144 }
145
146 /**
147 * Registry-time callback: hides commerce widget categories without their plugin.
148 *
149 * WooCommerce availability is read through the store section's signal
150 * (dashboard-sections.php, including its availability filter) so section and
151 * widgets can't disagree — a consumer overriding the section filter gets
152 * matching widget types. Both dashboard entry points load
153 * dashboard-sections.php before the widget registry can hydrate, so the
154 * function is always defined by the time this callback runs.
155 *
156 * @param array $widget_candidates Manifest candidates.
157 * @return array The candidates, minus commerce categories missing their plugin.
158 */
159 function filter_registrable_widget_types_by_plugin( $widget_candidates ) {
160 return remove_plugin_gated_widget_types(
161 $widget_candidates,
162 is_woocommerce_dashboard_section_available(),
163 is_bookings_plugin_active()
164 );
165 }
166
167 add_filter( REGISTRABLE_WIDGET_TYPES_FILTER, __NAMESPACE__ . '\\filter_registrable_widget_types_by_plugin' );
168
169 // Subscriber widgets remain available when their section is hidden because
170 // their data does not depend on the local module. Unregistering them would also
171 // break instances placed in other sections.
172
173 /**
174 * Removes candidates the reader could not load data for anyway.
175 *
176 * Split from the hook callback so both branches are testable without a user.
177 *
178 * @since 0.1.0
179 *
180 * @param array $widget_candidates Manifest candidates, each with a `category`.
181 * @param bool $can_view_store_reports Whether the reader may see the store reports.
182 * @return array The candidates, minus the store-report categories for readers who can't.
183 */
184 function remove_capability_gated_widget_types( $widget_candidates, $can_view_store_reports ) {
185 if ( $can_view_store_reports ) {
186 return $widget_candidates;
187 }
188
189 return array_values(
190 array_filter(
191 $widget_candidates,
192 static function ( $widget ) {
193 return ! in_array( $widget['category'] ?? '', STORE_REPORT_WIDGET_CATEGORIES, true );
194 }
195 )
196 );
197 }
198
199 /**
200 * Registry-time callback: hides widgets whose data the reader cannot fetch.
201 *
202 * A `view_stats` reader reaching one of them would only collect 403s from the
203 * proxy's `analytics` prefix, so the types are never registered for them. The
204 * registry is request-scoped, so filtering on the current user is safe here.
205 *
206 * @since 0.1.0
207 *
208 * @param array $widget_candidates Manifest candidates.
209 * @return array The candidates, minus the store-report categories for readers who can't see them.
210 */
211 function filter_registrable_widget_types_by_capability( $widget_candidates ) {
212 return remove_capability_gated_widget_types(
213 $widget_candidates,
214 Capabilities::current_user_can_view_store_reports()
215 );
216 }
217
218 add_filter( REGISTRABLE_WIDGET_TYPES_FILTER, __NAMESPACE__ . '\\filter_registrable_widget_types_by_capability' );
219