PluginProbe
Stream – Activity Log & Audit Trail / 3.6.0
Stream – Activity Log & Audit Trail v3.6.0
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-plugin.php +9 -370 trunk3.6.0 View file →
@@ -6,10 +6,8 @@
6 6 */
7 7
8 8 namespace WP_Stream;
9 9
10 -use RuntimeException;
11 -
12 10 /**
13 11 * Class Plugin
14 12 */
15 13 class Plugin {
@@ -19,9 +17,9 @@
19 17 * TODO Maybe pass this as a constructor dependency?
20 18 *
21 19 * @const string
22 20 */
23 - const VERSION = '4.4.0';
21 + const VERSION = '3.6.0';
24 22
25 23 /**
26 24 * WP-CLI command
27 25 *
@@ -28,31 +26,9 @@
28 26 * @const string
29 27 */
30 28 const WP_CLI_COMMAND = 'stream';
31 29
32 -
33 30 /**
34 - * Used to check if it's a single site, not multisite.
35 - *
36 - * @const string
37 - */
38 - const SINGLE_SITE = 'single';
39 -
40 - /**
41 - * Used to check if it's a multisite with the plugin network enabled.
42 - *
43 - * @const string
44 - */
45 - const MULTI_NETWORK = 'multisite-network';
46 -
47 - /**
48 - * Used to check if it's a multisite with the plugin not network enabled.
49 - *
50 - * @const string
51 - */
52 - const MULTI_NOT_NETWORK = 'multisite-not-network';
53 -
54 - /**
55 31 * Holds and manages WordPress Admin configurations.
56 32 *
57 33 * @var Admin
58 34 */
@@ -72,15 +48,8 @@
72 48 */
73 49 public $alerts_list;
74 50
75 51 /**
76 - * Holds and manages WordPress Abilities API integration.
77 - *
78 - * @var Abilities
79 - */
80 - public $abilities;
81 -
82 - /**
83 52 * Holds and manages connectors
84 53 *
85 54 * @var Connectors
86 55 */
@@ -114,30 +83,8 @@
114 83 */
115 84 public $install;
116 85
117 86 /**
118 - * Backend used to schedule Stream's deferred work (purge / reset).
119 - *
120 - * Either an {@see AS_Scheduler} (Action Scheduler, default) or a
121 - * {@see Cron_Scheduler} (WP-Cron fallback), selected at construction via
122 - * the `wp_stream_use_action_scheduler` filter.
123 - *
124 - * @var Scheduler
125 - */
126 - public $scheduler;
127 -
128 - /**
129 - * Whether the bundled Action Scheduler library was loaded.
130 - *
131 - * Set from a file_exists() check at construction (see __construct), so it
132 - * is reliable on `plugins_loaded` even though AS only declares its as_*()
133 - * API later on `init`.
134 - *
135 - * @var bool
136 - */
137 - protected $action_scheduler_available = false;
138 -
139 - /**
140 87 * URLs and Paths used by the plugin
141 88 *
142 89 * @var array
143 90 */
@@ -143,15 +90,8 @@
143 90 */
144 91 public $locations = array();
145 92
146 93 /**
147 - * IP address for the current request to be associated with the log entry.
148 - *
149 - * @var null|false|string Valid IP address, null if not set, false if invalid.
150 - */
151 - protected $client_ip_address;
152 -
153 - /**
154 94 * Class constructor
155 95 */
156 96 public function __construct() {
157 97 $locate = $this->locate_plugin();
@@ -165,27 +105,8 @@
165 105 );
166 106
167 107 spl_autoload_register( array( $this, 'autoload' ) );
168 108
169 - // Determine the scheduler backend, then load Action Scheduler only if
170 - // it is the selected backend. AS remains a hard, bundled dependency
171 - // for the WordPress.org build (see issue #1907), but integrators who
172 - // opt into the WP-Cron fallback via `wp_stream_use_action_scheduler`
173 - // pay neither the require_once nor AS's own `init` bootstrap.
174 - //
175 - // Availability is tracked from a file_exists() check rather than
176 - // function_exists(): AS only declares its as_*() API on `init`, but
177 - // this constructor runs at plugin-file inclusion time (before the
178 - // `plugins_loaded` action fires), so the functions are not defined
179 - // yet. Scheduler methods are only ever called on/after `init`
180 - // (wp_loaded, AJAX, cron), by which point the API is loaded.
181 - $action_scheduler = $this->locations['dir'] . '/vendor/woocommerce/action-scheduler/action-scheduler.php';
182 - $this->action_scheduler_available = file_exists( $action_scheduler );
183 -
184 - // Select the scheduler backend for Stream's deferred work, loading the
185 - // bundled AS library only if it is the chosen backend.
186 - $this->scheduler = $this->create_scheduler();
187 -
188 109 // Load helper functions.
189 110 require_once $this->locations['inc_dir'] . 'functions.php';
190 111
191 112 // Load DB helper interface/class.
@@ -216,11 +137,8 @@
216 137
217 138 // Load logger class.
218 139 $this->log = apply_filters( 'wp_stream_log_handler', new Log( $this ) );
219 140
220 - // Set the IP address for the current request.
221 - $this->client_ip_address = wp_stream_filter_input( INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP );
222 -
223 141 // Load settings and connectors after widgets_init and before the default init priority.
224 142 add_action( 'init', array( $this, 'init' ), 9 );
225 143
226 144 // Add frontend indicator.
@@ -243,71 +161,14 @@
243 161 }
244 162 }
245 163
246 164 /**
247 - * Build the scheduler backend for Stream's deferred work (purge / reset).
248 - *
249 - * Defaults to Action Scheduler when its bundled library is present.
250 - * Integrators that bundle Stream and run reliable cron (e.g. Cavalcade)
251 - * can force the WP-Cron fallback by returning false from
252 - * `wp_stream_use_action_scheduler`. When the fallback is chosen, the
253 - * bundled AS library is not loaded at all (no require_once, no AS `init`
254 - * bootstrap). See issue #1907.
255 - *
256 - * @return Scheduler
257 - */
258 - public function create_scheduler() {
259 - /**
260 - * Filter whether Stream uses Action Scheduler for its deferred work.
261 - *
262 - * IMPORTANT — timing: this filter is applied in Plugin::__construct(),
263 - * which runs when the Stream plugin file is included, i.e. BEFORE the
264 - * `plugins_loaded` action. Callbacks must therefore be registered from
265 - * code that loads before Stream: an mu-plugin, wp-config.php, or a
266 - * plugin guaranteed to load earlier. Registering it from a regular
267 - * plugin's `plugins_loaded` hook is too late and will be ignored.
268 - *
269 - * @param bool $use_action_scheduler Whether to use Action Scheduler.
270 - * Defaults to true when the bundled
271 - * AS library is present. Return a
272 - * real boolean: the value is cast
273 - * with (bool), so PHP string
274 - * truthiness applies to strings
275 - * (e.g. 'false' is truthy).
276 - */
277 - $use_action_scheduler = (bool) apply_filters(
278 - 'wp_stream_use_action_scheduler',
279 - $this->action_scheduler_available
280 - );
281 -
282 - if ( ! $use_action_scheduler ) {
283 - return new Cron_Scheduler();
284 - }
285 -
286 - // Guard a forced `__return_true` override when the bundled AS library
287 - // is absent: returning AS_Scheduler without loading AS would fatal on
288 - // the first unguarded as_*() call. Fall back to the cron scheduler
289 - // instead. The default path never hits this — the filter defaults to
290 - // $this->action_scheduler_available.
291 - if ( ! $this->action_scheduler_available ) {
292 - return new Cron_Scheduler();
293 - }
294 -
295 - // Load the bundled AS library before instantiating its scheduler.
296 - // AS's own ActionScheduler_Versions arbitration handles a host that
297 - // already provides its own copy.
298 - require_once $this->locations['dir'] . '/vendor/woocommerce/action-scheduler/action-scheduler.php';
299 -
300 - return new AS_Scheduler();
301 - }
302 -
303 - /**
304 165 * Autoloader for classes
305 166 *
306 - * @param string $class_name Fully qualified classname to be loaded.
167 + * @param string $class Fully qualified classname to be loaded.
307 168 */
308 - public function autoload( $class_name ) {
309 - if ( ! preg_match( '/^(?P<namespace>.+)\\\\(?P<autoload>[^\\\\]+)$/', $class_name, $matches ) ) {
169 + public function autoload( $class ) {
170 + if ( ! preg_match( '/^(?P<namespace>.+)\\\\(?P<autoload>[^\\\\]+)$/', $class, $matches ) ) {
310 171 return;
311 172 }
312 173
313 174 static $reflection;
@@ -347,9 +208,9 @@
347 208 $this->settings = new Settings( $this );
348 209 $this->connectors = new Connectors( $this );
349 210 $this->alerts = new Alerts( $this );
350 211 $this->alerts_list = new Alerts_List( $this );
351 - $this->abilities = new Abilities( $this );
212 +
352 213 }
353 214
354 215 /**
355 216 * Displays an HTML comment in the frontend head to indicate that Stream is activated,
@@ -371,9 +232,9 @@
371 232 */
372 233 $comment = apply_filters( 'wp_stream_frontend_indicator', $comment );
373 234
374 235 if ( ! empty( $comment ) ) {
375 - printf( "<!-- %s -->\n", esc_html( $comment ) );
236 + echo sprintf( "<!-- %s -->\n", esc_html( $comment ) ); // xss ok.
376 237 }
377 238 }
378 239
379 240 /**
@@ -382,12 +243,12 @@
382 243 *
383 244 * @return array
384 245 */
385 246 private function locate_plugin() {
386 - $dir_url = trailingslashit( plugins_url( '', __DIR__ ) );
387 - $dir_path = plugin_dir_path( __DIR__ );
247 + $dir_url = trailingslashit( plugins_url( '', dirname( __FILE__ ) ) );
248 + $dir_path = plugin_dir_path( dirname( __FILE__ ) );
388 249 $dir_basename = basename( $dir_path );
389 - $plugin_basename = trailingslashit( $dir_basename ) . 'stream.php';
250 + $plugin_basename = trailingslashit( $dir_basename ) . $dir_basename . '.php';
390 251
391 252 return compact( 'dir_url', 'dir_path', 'dir_basename', 'plugin_basename' );
392 253 }
393 254
@@ -452,228 +313,6 @@
452 313 return true;
453 314 }
454 315
455 316 return false;
456 - }
457 -
458 - /**
459 - * Get the IP address for the current request.
460 - *
461 - * @return false|null|string Valid IP address, null if not set, false if invalid.
462 - */
463 - public function get_client_ip_address() {
464 - return apply_filters( 'wp_stream_client_ip_address', $this->client_ip_address );
465 - }
466 -
467 - /**
468 - * Get the site type.
469 - *
470 - * This function determines the type of site based on whether it is a single site or a multisite.
471 - * If it is a multisite, it also checks if it is network activated or not.
472 - *
473 - * @return string The site type
474 - */
475 - public function get_site_type(): string {
476 -
477 - // If it's a multisite, is it network activated or not?
478 - if ( is_multisite() ) {
479 - return $this->is_network_activated() ? self::MULTI_NETWORK : self::MULTI_NOT_NETWORK;
480 - }
481 -
482 - return self::SINGLE_SITE;
483 - }
484 -
485 - /**
486 - * Should the number of records which need to be processed be considered "large"?
487 - *
488 - * @param int $record_number The number of rows in the {$wpdb->prefix}_stream table to be processed.
489 - * @return bool Whether or not this should be considered large.
490 - */
491 - public function is_large_records_table( int $record_number ): bool {
492 - /**
493 - * Filters whether or not the number of records should be considered a large table.
494 - *
495 - * @since 4.1.0
496 - *
497 - * @param bool $is_large_table Whether or not the number of records should be considered large.
498 - * @param int $record_number The number of records being checked.
499 - */
500 - return apply_filters( 'wp_stream_is_large_records_table', $record_number > 1000000, $record_number );
501 - }
502 -
503 - /**
504 - * Checks if the plugin is running on a single site installation.
505 - *
506 - * @return bool True if the plugin is running on a single site installation, false otherwise.
507 - */
508 - public function is_single_site() {
509 - return self::SINGLE_SITE === $this->get_site_type();
510 - }
511 -
512 - /**
513 - * Check if the plugin is activated on a multisite installation but not network activated.
514 - *
515 - * @return bool True if the plugin is activated on a multisite installation but not network activated, false otherwise.
516 - */
517 - public function is_multisite_not_network_activated() {
518 - return self::MULTI_NOT_NETWORK === $this->get_site_type();
519 - }
520 -
521 - /**
522 - * Check if the plugin is activated on a multisite network.
523 - *
524 - * @return bool True if the plugin is network activated on a multisite, false otherwise.
525 - */
526 - public function is_multisite_network_activated() {
527 - return self::MULTI_NETWORK === $this->get_site_type();
528 - }
529 -
530 - /**
531 - * Enqueue a script along with a stylesheet if it exists.
532 - *
533 - * @param string $handle Script handle.
534 - * @param array $additional_dependencies Additional dependencies.
535 - * @param array $data Data to pass to the script.
536 - *
537 - * @throws RuntimeException If built JavaScript assets are not found.
538 - * @return void
539 - */
540 - public function enqueue_asset( $handle, $additional_dependencies = array(), $data = array() ) {
541 - // If is enqueued already, bail out.
542 - if ( wp_script_is( $handle ) ) {
543 - return;
544 - }
545 -
546 - $path = untrailingslashit( $this->locations['dir'] );
547 - $url = untrailingslashit( $this->locations['url'] );
548 -
549 - $script_asset_path = "$path/build/$handle.asset.php";
550 -
551 - if ( ! file_exists( $script_asset_path ) ) {
552 - throw new RuntimeException( 'Built JavaScript assets not found. Please run `npm run build`' );
553 - }
554 -
555 - $script_asset = require $script_asset_path; // phpcs:disable WPThemeReview.CoreFunctionality.FileInclude.FileIncludeFound
556 -
557 - wp_enqueue_script(
558 - "wp-stream-$handle",
559 - "$url/build/$handle.js",
560 - array_merge(
561 - $script_asset['dependencies'],
562 - (array) $additional_dependencies
563 - ),
564 - $script_asset['version'],
565 - true
566 - );
567 -
568 - if ( file_exists( "$path/build/$handle.css" ) ) {
569 - wp_enqueue_style(
570 - "wp-stream-$handle",
571 - "$url/build/$handle.css",
572 - array(),
573 - $script_asset['version']
574 - );
575 - }
576 -
577 - if ( ! empty( $data ) ) {
578 - wp_add_inline_script(
579 - "wp-stream-$handle",
580 - sprintf( 'window["%s"] = %s;', esc_attr( "wp-stream-$handle" ), wp_json_encode( $data ) ),
581 - 'before'
582 - );
583 - }
584 - }
585 -
586 - /**
587 - * Enqueue select2 script and locale file if exists.
588 - *
589 - * @return string Script handle.
590 - */
591 - public function with_select2() {
592 - $handle = 'wp-stream-select2';
593 -
594 - // If is enqueued already, bail out.
595 - if ( wp_script_is( $handle ) ) {
596 - return $handle;
597 - }
598 -
599 - $path = untrailingslashit( $this->locations['dir'] );
600 - $url = untrailingslashit( $this->locations['url'] );
601 -
602 - wp_enqueue_script(
603 - $handle,
604 - "$url/build/select2/js/select2.full.min.js",
605 - array( 'jquery' ),
606 - filemtime( "$path/build/select2/js/select2.full.min.js" ),
607 - true
608 - );
609 - wp_enqueue_style(
610 - $handle,
611 - "$url/build/select2/css/select2.min.css",
612 - array(),
613 - filemtime( "$path/build/select2/css/select2.min.css" )
614 - );
615 -
616 - $locale = get_locale();
617 - $lang = substr( $locale, 0, 2 );
618 - $search_files = array( $locale, $lang, 'en' );
619 -
620 - foreach ( $search_files as $search_file ) {
621 - if ( file_exists( "$path/build/select2/js/i18n/$search_file.js" ) ) {
622 - wp_enqueue_script(
623 - sanitize_title( "$handle-$search_file" ),
624 - "$url/build/select2/js/i18n/$search_file.js",
625 - array( $handle ),
626 - filemtime( "$path/build/select2/js/i18n/$search_file.js" ),
627 - true
628 - );
629 - break;
630 - }
631 - }
632 -
633 - return $handle;
634 - }
635 -
636 - /**
637 - * Enqueue jquery.timeago script and locale file if exists.
638 - *
639 - * @return string Script handle.
640 - */
641 - public function with_jquery_timeago() {
642 - $handle = 'wp-stream-jquery-timeago';
643 -
644 - // If is enqueued already, bail out.
645 - if ( wp_script_is( $handle ) ) {
646 - return $handle;
647 - }
648 -
649 - $path = untrailingslashit( $this->locations['dir'] );
650 - $url = untrailingslashit( $this->locations['url'] );
651 -
652 - wp_enqueue_script(
653 - $handle,
654 - "$url/build/timeago/js/jquery.timeago.js",
655 - array( 'jquery' ),
656 - filemtime( "$path/build/timeago/js/jquery.timeago.js" ),
657 - true
658 - );
659 -
660 - $locale = get_locale();
661 - $lang = substr( $locale, 0, 2 );
662 - $search_files = array( $locale, $lang, 'en' );
663 -
664 - foreach ( $search_files as $search_file ) {
665 - if ( file_exists( "$path/build/timeago/js/locales/jquery.timeago.$search_file.js" ) ) {
666 - wp_enqueue_script(
667 - sanitize_title( "$handle-$search_file" ),
668 - "$url/build/timeago/js/locales/jquery.timeago.$search_file.js",
669 - array( $handle ),
670 - filemtime( "$path/build/timeago/js/locales/jquery.timeago.$search_file.js" ),
671 - true
672 - );
673 - break;
674 - }
675 - }
676 -
677 - return $handle;
678 317 }
679 318 }