PluginProbe
Stream – Activity Log & Audit Trail / 3.4.2
Stream – Activity Log & Audit Trail v3.4.2
4.4.0 4.3.0 4.2.2 4.2.1 trunk 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.1 3.1.1 3.10.0 3.2.0 3.2.1 3.2.2 3.2.3 All 50 releases
← All changes | classes/class-connectors.php +59 -277 trunk3.4.2 View file →
@@ -1,20 +1,10 @@
1 1 <?php
2 -/**
3 - * Validates and loads core connectors, integrated connectors, and
4 - * connectors registered using the "wp_stream_connectors" hook.
5 - *
6 - * @package WP_Stream
7 - */
8 -
9 2 namespace WP_Stream;
10 3
11 -/**
12 - * Class - Connectors
13 - */
14 4 class Connectors {
15 5 /**
16 - * Holds instance of plugin object
6 + * Hold Plugin class
17 7 *
18 8 * @var Plugin
19 9 */
20 10 public $plugin;
@@ -19,9 +9,9 @@
19 9 */
20 10 public $plugin;
21 11
22 12 /**
23 - * Registered connectors.
13 + * Connectors registered
24 14 *
25 15 * @var array
26 16 */
27 17 public $connectors = array();
@@ -34,9 +24,8 @@
34 24 public $contexts = array();
35 25
36 26 /**
37 27 * Action taxonomy terms
38 - *
39 28 * Holds slug to localized label association
40 29 *
41 30 * @var array
42 31 */
@@ -55,9 +44,9 @@
55 44
56 45 /**
57 46 * Class constructor.
58 47 *
59 - * @param Plugin $plugin Instance of plugin object.
48 + * @param Plugin $plugin The main Plugin class.
60 49 */
61 50 public function __construct( $plugin ) {
62 51 $this->plugin = $plugin;
63 52 $this->load_connectors();
@@ -67,11 +56,9 @@
67 56 * Load built-in connectors
68 57 */
69 58 public function load_connectors() {
70 59 $connectors = array(
71 - /**
72 - * Core Connectors
73 - */
60 + // Core
74 61 'blogs',
75 62 'comments',
76 63 'editor',
77 64 'installer',
@@ -82,11 +69,9 @@
82 69 'taxonomies',
83 70 'users',
84 71 'widgets',
85 72
86 - /**
87 - * Integrated Connectors
88 - */
73 + // Extras
89 74 'acf',
90 75 'bbpress',
91 76 'buddypress',
92 77 'edd',
@@ -92,33 +77,40 @@
92 77 'edd',
93 78 'gravityforms',
94 79 'jetpack',
95 80 'mercator',
96 - 'two-factor',
97 81 'user-switching',
98 82 'woocommerce',
99 83 'wordpress-seo',
100 84 );
101 85
102 - // Get excluded connectors.
103 - $excluded_connectors = array();
104 -
105 86 $classes = array();
106 87 foreach ( $connectors as $connector ) {
107 - // Load connector class file.
108 88 include_once $this->plugin->locations['dir'] . '/connectors/class-connector-' . $connector . '.php';
89 + $class_name = sprintf( '\WP_Stream\Connector_%s', str_replace( '-', '_', $connector ) );
90 + if ( ! class_exists( $class_name ) ) {
91 + continue;
92 + }
93 + $class = new $class_name( $this->plugin->log );
109 94
110 - // Set fully qualified class name.
111 - $class_name = sprintf( '\WP_Stream\Connector_%s', str_replace( '-', '_', $connector ) );
95 + // Check if the Connector extends WP_Stream\Connector
96 + if ( ! is_subclass_of( $class, 'WP_Stream\Connector' ) ) {
97 + continue;
98 + }
112 99
113 - // Bail if no class loaded.
114 - if ( ! class_exists( $class_name ) ) {
100 + // Check if the Connector is allowed to be registered in the WP Admin
101 + if ( is_admin() && ! $class->register_admin ) {
115 102 continue;
116 103 }
117 104
118 - // Initialize connector.
119 - $class = new $class_name();
120 - $classes[ $class->name ] = $class;
105 + // Check if the Connector is allowed to be registered in the WP Frontend
106 + if ( ! is_admin() && ! $class->register_frontend ) {
107 + continue;
108 + }
109 +
110 + if ( $class->is_dependency_satisfied() ) {
111 + $classes[ $class->name ] = $class;
112 + }
121 113 }
122 114
123 115 /**
124 116 * Allows for adding additional connectors via classes that extend Connector.
@@ -124,53 +116,61 @@
124 116 * Allows for adding additional connectors via classes that extend Connector.
125 117 *
126 118 * @param array $classes An array of Connector objects.
127 119 */
128 - $connector_classes = apply_filters( 'wp_stream_connectors', $classes );
120 + $this->connectors = apply_filters( 'wp_stream_connectors', $classes );
129 121
130 - foreach ( $connector_classes as $connector ) {
131 - // Check if the connector class extends WP_Stream\Connector.
132 - if ( ! is_subclass_of( $connector, 'WP_Stream\Connector' ) ) {
133 - continue;
134 - }
122 + if ( empty( $this->connectors ) ) {
123 + return;
124 + }
135 125
136 - // Check if the connector events are allowed to be registered in the WP Admin.
137 - if ( is_admin() && ! $connector->register_admin ) {
126 + foreach ( $this->connectors as $connector ) {
127 + if ( ! method_exists( $connector, 'get_label' ) ) {
138 128 continue;
139 129 }
130 + $this->term_labels['stream_connector'][ $connector->name ] = $connector->get_label();
131 + }
140 132
141 - // Check if the connector events are allowed to be registered in the WP Frontend.
142 - if ( ! is_admin() && ! $connector->register_frontend ) {
143 - continue;
144 - }
133 + // Get excluded connectors
134 + $excluded_connectors = array();
145 135
146 - // Run any final validations the connector may have before used.
147 - if ( ! $connector->is_dependency_satisfied() ) {
148 - continue;
149 - }
150 -
151 - // Register error for invalid any connector class.
136 + foreach ( $this->connectors as $connector ) {
152 137 if ( ! method_exists( $connector, 'get_label' ) ) {
153 - /* translators: %s: connector class name, intended to provide help to developers (e.g. "Connector_BuddyPress") */
138 + // translators: Placeholder refers to a Connector class name, intended to provide help to developers (e.g. "Connector_BuddyPress")
154 139 $this->plugin->admin->notice( sprintf( __( '%s class wasn\'t loaded because it doesn\'t implement the get_label method.', 'stream' ), $connector->name, 'Connector' ), true );
155 140 continue;
156 141 }
157 142 if ( ! method_exists( $connector, 'register' ) ) {
158 - /* translators: %s: connector class name, intended to provide help to developers (e.g. "Connector_BuddyPress") */
143 + // translators: Placeholder refers to a Connector class name, intended to provide help to developers (e.g. "Connector_BuddyPress")
159 144 $this->plugin->admin->notice( sprintf( __( '%s class wasn\'t loaded because it doesn\'t implement the register method.', 'stream' ), $connector->name, 'Connector' ), true );
160 145 continue;
161 146 }
162 147 if ( ! method_exists( $connector, 'get_context_labels' ) ) {
163 - /* translators: %s: connector class name, intended to provide help to developers (e.g. "Connector_BuddyPress") */
148 + // translators: Placeholder refers to a Connector class name, intended to provide help to developers (e.g. "Connector_BuddyPress")
164 149 $this->plugin->admin->notice( sprintf( __( '%s class wasn\'t loaded because it doesn\'t implement the get_context_labels method.', 'stream' ), $connector->name, 'Connector' ), true );
165 150 continue;
166 151 }
167 152 if ( ! method_exists( $connector, 'get_action_labels' ) ) {
168 - /* translators: %s: connector class name, intended to provide help to developers (e.g. "Connector_BuddyPress") */
153 + // translators: Placeholder refers to a Connector class name, intended to provide help to developers (e.g. "Connector_BuddyPress")
169 154 $this->plugin->admin->notice( sprintf( __( '%s class wasn\'t loaded because it doesn\'t implement the get_action_labels method.', 'stream' ), $connector->name, 'Connector' ), true );
170 155 continue;
171 156 }
172 157
158 + // Check if the connectors extends the Connector class, if not skip it.
159 + if ( ! is_subclass_of( $connector, '\WP_Stream\Connector' ) ) {
160 + // translators: Placeholder refers to a Connector class name, intended to provide help to developers (e.g. "Connector_BuddyPress")
161 + $this->plugin->admin->notice( sprintf( __( '%1$s class wasn\'t loaded because it doesn\'t extends the %2$s class.', 'stream' ), $connector->name, 'Connector' ), true );
162 + continue;
163 + }
164 +
165 + // Store connector label
166 + if ( ! in_array( $connector->name, $this->term_labels['stream_connector'], true ) ) {
167 + $this->term_labels['stream_connector'][ $connector->name ] = $connector->get_label();
168 + }
169 +
170 + $connector_name = $connector->name;
171 + $is_excluded = in_array( $connector_name, $excluded_connectors, true );
172 +
173 173 /**
174 174 * Allows excluded connectors to be overridden and registered.
175 175 *
176 176 * @param bool $is_excluded True if excluded, otherwise false.
@@ -176,32 +176,20 @@
176 176 * @param bool $is_excluded True if excluded, otherwise false.
177 177 * @param string $connector The current connector's slug.
178 178 * @param array $excluded_connectors An array of all excluded connector slugs.
179 179 */
180 - $is_excluded_connector = apply_filters(
181 - 'wp_stream_check_connector_is_excluded',
182 - in_array( $connector->name, $excluded_connectors, true ),
183 - $connector->name,
184 - $excluded_connectors
185 - );
180 + $is_excluded_connector = apply_filters( 'wp_stream_check_connector_is_excluded', $is_excluded, $connector_name, $excluded_connectors );
186 181
187 182 if ( $is_excluded_connector ) {
188 183 continue;
189 184 }
190 185
191 - // Add connector to the registry.
192 - $this->connectors[ $connector->name ] = $connector;
193 -
194 - // Register the connector.
195 186 $connector->register();
196 187
197 - // Link context labels to their connector.
188 + // Link context labels to their connector
198 189 $this->contexts[ $connector->name ] = $connector->get_context_labels();
199 190
200 - // Store connector label.
201 - $this->term_labels['stream_connector'][ $connector->name ] = $connector->get_label();
202 -
203 - // Add new terms to our label lookup array.
191 + // Add new terms to our label lookup array
204 192 $this->term_labels['stream_action'] = array_merge(
205 193 $this->term_labels['stream_action'],
206 194 $connector->get_action_labels()
207 195 );
@@ -215,216 +203,10 @@
215 203
216 204 /**
217 205 * Fires after all connectors have been registered.
218 206 *
219 - * @param array $labels All register connectors labels array
220 - * @param Connectors $connector_classes The Connectors object
207 + * @param array $labels All register connectors labels array
208 + * @param Connectors $connectors The Connectors object
221 209 */
222 210 do_action( 'wp_stream_after_connectors_registration', $labels, $this );
223 - }
224 -
225 - /**
226 - * Return the slugs of all registered connectors.
227 - *
228 - * @return string[]
229 - */
230 - public function get_slugs() {
231 - return array_keys( (array) $this->connectors );
232 - }
233 -
234 - /**
235 - * Return a normalized list of all registered connectors and their
236 - * context/action labels.
237 - *
238 - * @return array<int, array{slug:string,label:string,contexts:array<string,string>,actions:array<string,string>}>
239 - */
240 - public function get_all() {
241 - $out = array();
242 -
243 - foreach ( (array) $this->connectors as $slug => $connector ) {
244 - $out[] = array(
245 - 'slug' => (string) $slug,
246 - 'label' => method_exists( $connector, 'get_label' ) ? (string) $connector->get_label() : (string) $slug,
247 - 'contexts' => method_exists( $connector, 'get_context_labels' ) ? (array) $connector->get_context_labels() : array(),
248 - 'actions' => method_exists( $connector, 'get_action_labels' ) ? (array) $connector->get_action_labels() : array(),
249 - );
250 - }
251 -
252 - return $out;
253 - }
254 -
255 - /**
256 - * Return metadata for every Stream connector, including ones that
257 - * load_connectors() skipped because their `register_frontend` is false
258 - * and the current request isn't wp-admin (REST is `! is_admin()`, so
259 - * connectors like "settings", "editor", "menus" are otherwise invisible
260 - * to abilities). Walks the connector class list once and asks each
261 - * instance for its identity, never calling register() — so no hooks
262 - * fire and the live $this->connectors registry stays exactly as
263 - * load_connectors() built it.
264 - *
265 - * Intended for the abilities layer (stream/get-connectors,
266 - * stream/create-exclusion-rule validation) where the answer should
267 - * reflect "what connectors exist on this site" rather than "what
268 - * connectors loaded their hooks for this specific request".
269 - *
270 - * @return array<int, array{slug:string,label:string,contexts:array<string,string>,actions:array<string,string>}>
271 - */
272 - public function get_all_including_admin_only() {
273 - $out = array();
274 -
275 - foreach ( $this->build_full_connector_classes() as $connector ) {
276 - $out[] = array(
277 - 'slug' => (string) $connector->name,
278 - 'label' => method_exists( $connector, 'get_label' ) ? (string) $connector->get_label() : (string) $connector->name,
279 - 'contexts' => method_exists( $connector, 'get_context_labels' ) ? (array) $connector->get_context_labels() : array(),
280 - 'actions' => method_exists( $connector, 'get_action_labels' ) ? (array) $connector->get_action_labels() : array(),
281 - );
282 - }
283 -
284 - /**
285 - * Filter the connector list surfaced to the Abilities API.
286 - *
287 - * Mirrors `wp_stream_connectors` for the abilities-facing list so
288 - * third parties can add/remove entries shown to REST/MCP callers
289 - * without affecting which connectors actually register hooks.
290 - *
291 - * @param array $out Connector metadata entries.
292 - */
293 - return apply_filters( 'wp_stream_abilities_connectors', $out );
294 - }
295 -
296 - /**
297 - * Return slugs of every Stream connector, including admin-only ones.
298 - * Companion to get_all_including_admin_only(); used by abilities that
299 - * need to validate an incoming connector slug (e.g. stream/create-
300 - * exclusion-rule) against the full site-wide list rather than the
301 - * request-context-gated $this->connectors registry.
302 - *
303 - * @return string[]
304 - */
305 - public function get_all_slugs_including_admin_only() {
306 - $slugs = array();
307 -
308 - foreach ( $this->build_full_connector_classes() as $connector ) {
309 - $slugs[] = (string) $connector->name;
310 - }
311 -
312 - return $slugs;
313 - }
314 -
315 - /**
316 - * Instantiate every built-in and integrated connector class and return
317 - * the ones whose dependencies are satisfied, regardless of the
318 - * `register_admin` / `register_frontend` gates that load_connectors()
319 - * applies. Helper for the metadata-only accessors above; does not
320 - * register hooks and does not mutate $this->connectors.
321 - *
322 - * @return Connector[]
323 - */
324 - protected function build_full_connector_classes() {
325 - // Same canonical slug list load_connectors() uses. Keep in sync.
326 - $connectors = array(
327 - // Core Connectors.
328 - 'blogs',
329 - 'comments',
330 - 'editor',
331 - 'installer',
332 - 'media',
333 - 'menus',
334 - 'posts',
335 - 'settings',
336 - 'taxonomies',
337 - 'users',
338 - 'widgets',
339 -
340 - // Integrated Connectors.
341 - 'acf',
342 - 'bbpress',
343 - 'buddypress',
344 - 'edd',
345 - 'gravityforms',
346 - 'jetpack',
347 - 'mercator',
348 - 'two-factor',
349 - 'user-switching',
350 - 'woocommerce',
351 - 'wordpress-seo',
352 - );
353 -
354 - $classes = array();
355 - foreach ( $connectors as $connector ) {
356 - include_once $this->plugin->locations['dir'] . '/connectors/class-connector-' . $connector . '.php';
357 -
358 - $class_name = sprintf( '\WP_Stream\Connector_%s', str_replace( '-', '_', $connector ) );
359 - if ( ! class_exists( $class_name ) ) {
360 - continue;
361 - }
362 -
363 - $class = new $class_name();
364 - $classes[ $class->name ] = $class;
365 - }
366 -
367 - /** This filter is documented in classes/class-connectors.php */
368 - $connector_classes = apply_filters( 'wp_stream_connectors', $classes );
369 -
370 - $out = array();
371 - foreach ( $connector_classes as $connector ) {
372 - if ( ! is_subclass_of( $connector, 'WP_Stream\Connector' ) ) {
373 - continue;
374 - }
375 - if ( ! $connector->is_dependency_satisfied() ) {
376 - continue;
377 - }
378 - if (
379 - ! method_exists( $connector, 'get_label' )
380 - || ! method_exists( $connector, 'get_context_labels' )
381 - || ! method_exists( $connector, 'get_action_labels' )
382 - ) {
383 - continue;
384 - }
385 - $out[] = $connector;
386 - }
387 -
388 - return $out;
389 - }
390 -
391 - /**
392 - * Unregisters the context hooks for all connectors.
393 - */
394 - public function unload_connectors() {
395 - foreach ( $this->connectors as $connector ) {
396 - $connector->unregister();
397 - }
398 - }
399 -
400 - /**
401 - * Reregisters the context hooks for all connectors.
402 - */
403 - public function reload_connectors() {
404 - foreach ( $this->connectors as $connector ) {
405 - $connector->register();
406 - }
407 - }
408 -
409 - /**
410 - * Unregisters the context hooks for a connectors.
411 - *
412 - * @param string $name Name of the connector.
413 - */
414 - public function unload_connector( $name ) {
415 - if ( ! empty( $this->connectors[ $name ] ) ) {
416 - $this->connectors[ $name ]->unregister();
417 - }
418 - }
419 -
420 - /**
421 - * Reregisters the context hooks for a connector.
422 - *
423 - * @param string $name Name of the connector.
424 - */
425 - public function reload_connector( $name ) {
426 - if ( ! empty( $this->connectors[ $name ] ) ) {
427 - $this->connectors[ $name ]->register();
428 - }
429 211 }
430 212 }