PluginProbe
Stream – Activity Log & Audit Trail / 4.0.2
Stream – Activity Log & Audit Trail v4.0.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-admin.php +337 -215 3.0.44.0.2 View file →
@@ -1,31 +1,53 @@
1 1 <?php
2 +/**
3 + * Centralized manager for WordPress backend functionality.
4 + *
5 + * @package WP_Stream
6 + */
7 +
2 8 namespace WP_Stream;
3 9
4 10 use DateTime;
5 11 use DateTimeZone;
6 12 use DateInterval;
7 -use \WP_CLI;
8 -use \WP_Roles;
13 +use WP_CLI;
14 +use WP_Roles;
9 15
16 +/**
17 + * Class - Admin
18 + */
10 19 class Admin {
20 +
11 21 /**
12 - * Hold Plugin class
22 + * Holds Instance of plugin object
23 + *
13 24 * @var Plugin
14 25 */
15 26 public $plugin;
16 27
17 28 /**
29 + * Holds Network class
30 + *
18 31 * @var Network
19 32 */
20 33 public $network;
21 34
22 35 /**
36 + * Holds Live Update class
37 + *
23 38 * @var Live_Update
24 39 */
25 40 public $live_update;
26 41
27 42 /**
43 + * Holds Export class
44 + *
45 + * @var Export
46 + */
47 + public $export;
48 +
49 + /**
28 50 * Menu page screen id
29 51 *
30 52 * @var string
31 53 */
@@ -103,9 +125,9 @@
103 125
104 126 /**
105 127 * Class constructor.
106 128 *
107 - * @param Plugin $plugin The main Plugin class.
129 + * @param Plugin $plugin Instance of plugin object.
108 130 */
109 131 public function __construct( $plugin ) {
110 132 $this->plugin = $plugin;
111 133
@@ -110,18 +132,18 @@
110 132 $this->plugin = $plugin;
111 133
112 134 add_action( 'init', array( $this, 'init' ) );
113 135
114 - // Ensure function used in various methods is pre-loaded
136 + // Ensure function used in various methods is pre-loaded.
115 137 if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
116 - require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
138 + require_once ABSPATH . '/wp-admin/includes/plugin.php';
117 139 }
118 140
119 - // User and role caps
141 + // User and role caps.
120 142 add_filter( 'user_has_cap', array( $this, 'filter_user_caps' ), 10, 4 );
121 143 add_filter( 'role_has_cap', array( $this, 'filter_role_caps' ), 10, 3 );
122 144
123 - if ( is_multisite() && is_plugin_active_for_network( $this->plugin->locations['plugin'] ) && ! is_network_admin() ) {
145 + if ( is_multisite() && $plugin->is_network_activated() && ! is_network_admin() ) {
124 146 $options = (array) get_site_option( 'wp_stream_network', array() );
125 147 $option = isset( $options['general_site_access'] ) ? absint( $options['general_site_access'] ) : 1;
126 148
127 149 $this->disable_access = ( $option ) ? false : true;
@@ -126,49 +148,68 @@
126 148
127 149 $this->disable_access = ( $option ) ? false : true;
128 150 }
129 151
130 - // Register settings page
152 + // Register settings page.
131 153 if ( ! $this->disable_access ) {
132 154 add_action( 'admin_menu', array( $this, 'register_menu' ) );
133 155 }
134 156
135 - // Admin notices
157 + // Admin notices.
136 158 add_action( 'admin_notices', array( $this, 'prepare_admin_notices' ) );
137 159 add_action( 'shutdown', array( $this, 'admin_notices' ) );
138 160
139 - // Add admin body class
161 + // Add admin body class.
140 162 add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
141 163
142 - // Plugin action links
143 - add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2 );
164 + // Plugin action links.
165 + add_filter(
166 + 'plugin_action_links',
167 + array(
168 + $this,
169 + 'plugin_action_links',
170 + ),
171 + 10,
172 + 2
173 + );
144 174
145 - // Load admin scripts and styles
146 - add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
175 + // Load admin scripts and styles.
176 + add_action(
177 + 'admin_enqueue_scripts',
178 + array(
179 + $this,
180 + 'admin_enqueue_scripts',
181 + )
182 + );
147 183 add_action( 'admin_enqueue_scripts', array( $this, 'admin_menu_css' ) );
148 184
149 - // Reset Streams database
150 - add_action( 'wp_ajax_wp_stream_reset', array( $this, 'wp_ajax_reset' ) );
185 + // Reset Streams database.
186 + add_action(
187 + 'wp_ajax_wp_stream_reset',
188 + array(
189 + $this,
190 + 'wp_ajax_reset',
191 + )
192 + );
151 193
152 - // Uninstall Streams and Deactivate plugin
153 - $uninstall = new Uninstall( $this->plugin );
154 - add_action( 'wp_ajax_wp_stream_uninstall', array( $uninstall, 'uninstall' ) );
155 -
156 - // Auto purge setup
194 + // Auto purge setup.
157 195 add_action( 'wp_loaded', array( $this, 'purge_schedule_setup' ) );
158 - add_action( 'wp_stream_auto_purge', array( $this, 'purge_scheduled_action' ) );
196 + add_action(
197 + 'wp_stream_auto_purge',
198 + array(
199 + $this,
200 + 'purge_scheduled_action',
201 + )
202 + );
159 203
160 - // Ajax users list
161 - add_action( 'wp_ajax_wp_stream_filters', array( $this, 'ajax_filters' ) );
162 -
163 - // Ajax user's name by ID
164 - add_action( 'wp_ajax_wp_stream_get_filter_value_by_id', array( $this, 'get_filter_value_by_id' ) );
165 -
166 - // Ajax users list
167 - add_action( 'wp_ajax_wp_stream_filters', array( $this, 'ajax_filters' ) );
168 -
169 - // Ajax user's name by ID
170 - add_action( 'wp_ajax_wp_stream_get_filter_value_by_id', array( $this, 'get_filter_value_by_id' ) );
204 + // Ajax users list.
205 + add_action(
206 + 'wp_ajax_wp_stream_filters',
207 + array(
208 + $this,
209 + 'ajax_filters',
210 + )
211 + );
171 212 }
172 213
173 214 /**
174 215 * Load admin classes
@@ -177,16 +218,23 @@
177 218 */
178 219 public function init() {
179 220 $this->network = new Network( $this->plugin );
180 221 $this->live_update = new Live_Update( $this->plugin );
222 + $this->export = new Export( $this->plugin );
223 +
224 + // Check if the host has configured the `REMOTE_ADDR` correctly.
225 + $client_ip = $this->plugin->get_client_ip_address();
226 + if ( empty( $client_ip ) && $this->is_stream_screen() ) {
227 + $this->notice( __( 'Stream plugin can\'t determine a reliable client IP address! Please update the hosting environment to set the $_SERVER[\'REMOTE_ADDR\'] variable or use the wp_stream_client_ip_address filter to specify the verified client IP address!', 'stream' ) );
228 + }
181 229 }
182 230
183 231 /**
184 - * Output specific updates passed as URL parameters
232 + * Output specific updates passed as URL parameters.
185 233 *
186 234 * @action admin_notices
187 235 *
188 - * @return string
236 + * @return void
189 237 */
190 238 public function prepare_admin_notices() {
191 239 $message = wp_stream_filter_input( INPUT_GET, 'message' );
192 240
@@ -199,14 +247,14 @@
199 247
200 248 /**
201 249 * Handle notice messages according to the appropriate context (WP-CLI or the WP Admin)
202 250 *
203 - * @param string $message
204 - * @param bool $is_error
251 + * @param string $message Message to output.
252 + * @param bool $is_error If the message is error_level (true) or warning (false).
205 253 */
206 254 public function notice( $message, $is_error = true ) {
207 255 if ( defined( 'WP_CLI' ) && WP_CLI ) {
208 - $message = strip_tags( $message );
256 + $message = wp_strip_all_tags( $message );
209 257
210 258 if ( $is_error ) {
211 259 WP_CLI::warning( $message );
212 260 } else {
@@ -212,14 +260,14 @@
212 260 } else {
213 261 WP_CLI::success( $message );
214 262 }
215 263 } else {
216 - // Trigger admin notices late, so that any notices which occur during page load are displayed
264 + // Trigger admin notices late, so that any notices which occur during page load are displayed.
217 265 add_action( 'shutdown', array( $this, 'admin_notices' ) );
218 266
219 267 $notice = compact( 'message', 'is_error' );
220 268
221 - if ( ! in_array( $notice, $this->notices ) ) {
269 + if ( ! in_array( $notice, $this->notices, true ) ) {
222 270 $this->notices[] = $notice;
223 271 }
224 272 }
225 273 }
@@ -258,9 +306,9 @@
258 306 * Register menu page
259 307 *
260 308 * @action admin_menu
261 309 *
262 - * @return bool|void
310 + * @return void
263 311 */
264 312 public function register_menu() {
265 313 /**
266 314 * Filter the main admin menu title
@@ -295,8 +343,16 @@
295 343 $main_menu_position
296 344 );
297 345
298 346 /**
347 + * Fires before submenu items are added to the Stream menu
348 + * allowing plugins to add menu items before Settings
349 + *
350 + * @return void
351 + */
352 + do_action( 'wp_stream_admin_menu' );
353 +
354 + /**
299 355 * Filter the Settings admin page title
300 356 *
301 357 * @return string
302 358 */
@@ -318,10 +374,16 @@
318 374 * @return void
319 375 */
320 376 do_action( 'wp_stream_admin_menu_screens' );
321 377
322 - // Register the list table early, so it associates the column headers with 'Screen settings'
323 - add_action( 'load-' . $this->screen_id['main'], array( $this, 'register_list_table' ) );
378 + // Register the list table early, so it associates the column headers with 'Screen settings'.
379 + add_action(
380 + 'load-' . $this->screen_id['main'],
381 + array(
382 + $this,
383 + 'register_list_table',
384 + )
385 + );
324 386 }
325 387 }
326 388
327 389 /**
@@ -328,39 +390,80 @@
328 390 * Enqueue scripts/styles for admin screen
329 391 *
330 392 * @action admin_enqueue_scripts
331 393 *
332 - * @param string $hook
394 + * @param string $hook Current hook.
333 395 *
334 396 * @return void
335 397 */
336 398 public function admin_enqueue_scripts( $hook ) {
337 - wp_register_script( 'select2', $this->plugin->locations['url'] . 'ui/lib/select2/select2.js', array( 'jquery' ), '3.5.2', true );
338 - wp_register_style( 'select2', $this->plugin->locations['url'] . 'ui/lib/select2/select2.css', array(), '3.5.2' );
339 - wp_register_script( 'timeago', $this->plugin->locations['url'] . 'ui/lib/timeago/jquery.timeago.js', array(), '1.4.1', true );
399 + wp_register_script( 'wp-stream-select2', $this->plugin->locations['url'] . 'ui/lib/select2/js/select2.full.min.js', array( 'jquery' ), '4.0.13', true );
400 + wp_register_style( 'wp-stream-select2', $this->plugin->locations['url'] . 'ui/lib/select2/css/select2.min.css', array(), '4.0.13' );
401 + wp_register_script( 'wp-stream-timeago', $this->plugin->locations['url'] . 'ui/lib/timeago/jquery.timeago.js', array(), '1.4.1', true );
340 402
341 403 $locale = strtolower( substr( get_locale(), 0, 2 ) );
342 404 $file_tmpl = 'ui/lib/timeago/locales/jquery.timeago.%s.js';
343 405
344 406 if ( file_exists( $this->plugin->locations['dir'] . sprintf( $file_tmpl, $locale ) ) ) {
345 - wp_register_script( 'timeago-locale', $this->plugin->locations['url'] . sprintf( $file_tmpl, $locale ), array( 'timeago' ), '1' );
407 + wp_register_script(
408 + 'wp-stream-timeago-locale',
409 + $this->plugin->locations['url'] . sprintf( $file_tmpl, $locale ),
410 + array( 'wp-stream-timeago' ),
411 + '1',
412 + false
413 + );
346 414 } else {
347 - wp_register_script( 'timeago-locale', $this->plugin->locations['url'] . sprintf( $file_tmpl, 'en' ), array( 'timeago' ), '1' );
415 + wp_register_script(
416 + 'wp-stream-timeago-locale',
417 + $this->plugin->locations['url'] . sprintf( $file_tmpl, 'en' ),
418 + array( 'wp-stream-timeago' ),
419 + '1',
420 + false
421 + );
348 422 }
349 423
350 - wp_enqueue_style( 'wp-stream-admin', $this->plugin->locations['url'] . 'ui/css/admin.css', array(), $this->plugin->get_version() );
424 + $min = wp_stream_min_suffix();
425 + wp_enqueue_style( 'wp-stream-admin', $this->plugin->locations['url'] . 'ui/css/admin.' . $min . 'css', array(), $this->plugin->get_version() );
351 426
352 427 $script_screens = array( 'plugins.php' );
353 428
354 - if ( in_array( $hook, $this->screen_id ) || in_array( $hook, $script_screens ) ) {
355 - wp_enqueue_script( 'select2' );
356 - wp_enqueue_style( 'select2' );
429 + if ( in_array( $hook, $this->screen_id, true ) || in_array( $hook, $script_screens, true ) ) {
430 + wp_enqueue_script( 'wp-stream-select2' );
431 + wp_enqueue_style( 'wp-stream-select2' );
357 432
358 - wp_enqueue_script( 'timeago' );
359 - wp_enqueue_script( 'timeago-locale' );
433 + wp_enqueue_script( 'wp-stream-timeago' );
434 + wp_enqueue_script( 'wp-stream-timeago-locale' );
360 435
361 - wp_enqueue_script( 'wp-stream-admin', $this->plugin->locations['url'] . 'ui/js/admin.js', array( 'jquery', 'select2' ), $this->plugin->get_version() );
362 - wp_enqueue_script( 'wp-stream-live-updates', $this->plugin->locations['url'] . 'ui/js/live-updates.js', array( 'jquery', 'heartbeat' ), $this->plugin->get_version() );
436 + wp_enqueue_script(
437 + 'wp-stream-admin',
438 + $this->plugin->locations['url'] . 'ui/js/admin.' . $min . 'js',
439 + array(
440 + 'jquery',
441 + 'wp-stream-select2',
442 + ),
443 + $this->plugin->get_version(),
444 + false
445 + );
446 + wp_enqueue_script(
447 + 'wp-stream-admin-exclude',
448 + $this->plugin->locations['url'] . 'ui/js/exclude.' . $min . 'js',
449 + array(
450 + 'jquery',
451 + 'wp-stream-select2',
452 + ),
453 + $this->plugin->get_version(),
454 + false
455 + );
456 + wp_enqueue_script(
457 + 'wp-stream-live-updates',
458 + $this->plugin->locations['url'] . 'ui/js/live-updates.' . $min . 'js',
459 + array(
460 + 'jquery',
461 + 'heartbeat',
462 + ),
463 + $this->plugin->get_version(),
464 + false
465 + );
363 466
364 467 wp_localize_script(
365 468 'wp-stream-admin',
366 469 'wp_stream',
@@ -365,11 +468,10 @@
365 468 'wp-stream-admin',
366 469 'wp_stream',
367 470 array(
368 471 'i18n' => array(
369 - 'confirm_purge' => esc_html__( 'Are you sure you want to delete all Stream activity records from the database? This cannot be undone.', 'stream' ),
370 - 'confirm_defaults' => esc_html__( 'Are you sure you want to reset all site settings to default? This cannot be undone.', 'stream' ),
371 - 'confirm_uninstall' => esc_html__( 'Are you sure you want to uninstall and deactivate Stream? This will delete all Stream tables from the database and cannot be undone.', 'stream' ),
472 + 'confirm_purge' => esc_html__( 'Are you sure you want to delete all Stream activity records from the database? This cannot be undone.', 'stream' ),
473 + 'confirm_defaults' => esc_html__( 'Are you sure you want to reset all site settings to default? This cannot be undone.', 'stream' ),
372 474 ),
373 475 'locale' => esc_js( $locale ),
374 476 'gmt_offset' => get_option( 'gmt_offset' ),
375 477 )
@@ -374,17 +476,21 @@
374 476 'gmt_offset' => get_option( 'gmt_offset' ),
375 477 )
376 478 );
377 479
480 + $order_types = array( 'asc', 'desc' );
481 +
378 482 wp_localize_script(
379 483 'wp-stream-live-updates',
380 484 'wp_stream_live_updates',
381 485 array(
382 486 'current_screen' => $hook,
383 - 'current_page' => isset( $_GET['paged'] ) ? esc_js( $_GET['paged'] ) : '1', // input var okay
384 - 'current_order' => isset( $_GET['order'] ) ? esc_js( $_GET['order'] ) : 'desc', // input var okay
385 - 'current_query' => wp_stream_json_encode( $_GET ), // input var okay
386 - 'current_query_count' => count( $_GET ), // input var okay
487 + 'current_page' => isset( $_GET['paged'] ) ? absint( wp_unslash( $_GET['paged'] ) ) : '1', // phpcs:ignore WordPress.Security.NonceVerification.Recommended
488 + 'current_order' => isset( $_GET['order'] ) && in_array( strtolower( $_GET['order'] ), $order_types, true ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
489 + ? esc_js( $_GET['order'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
490 + : 'desc',
491 + 'current_query' => wp_json_encode( $_GET ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended
492 + 'current_query_count' => count( $_GET ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended
387 493 )
388 494 );
389 495 }
390 496
@@ -401,15 +507,23 @@
401 507 * @return int
402 508 */
403 509 $bulk_actions_threshold = apply_filters( 'wp_stream_bulk_actions_threshold', 100 );
404 510
405 - wp_enqueue_script( 'wp-stream-global', $this->plugin->locations['url'] . 'ui/js/global.js', array( 'jquery' ), $this->plugin->get_version() );
511 + wp_enqueue_script(
512 + 'wp-stream-global',
513 + $this->plugin->locations['url'] . 'ui/js/global.' . $min . 'js',
514 + array( 'jquery' ),
515 + $this->plugin->get_version(),
516 + false
517 + );
518 +
406 519 wp_localize_script(
407 520 'wp-stream-global',
408 521 'wp_stream_global',
409 522 array(
410 - 'bulk_actions' => array(
411 - 'i18n' => array(
523 + 'bulk_actions' => array(
524 + 'i18n' => array(
525 + /* translators: %s: a number of items (e.g. "1,742") */
412 526 'confirm_action' => sprintf( esc_html__( 'Are you sure you want to perform bulk actions on over %s items? This process could take a while to complete.', 'stream' ), number_format( absint( $bulk_actions_threshold ) ) ),
413 527 ),
414 528 'threshold' => absint( $bulk_actions_threshold ),
415 529 ),
@@ -423,12 +537,23 @@
423 537 *
424 538 * @return bool
425 539 */
426 540 public function is_stream_screen() {
427 - if ( is_admin() && false !== strpos( wp_stream_filter_input( INPUT_GET, 'page' ), $this->records_page_slug ) ) {
541 + if ( ! is_admin() ) {
542 + return false;
543 + }
544 +
545 + $page = wp_stream_filter_input( INPUT_GET, 'page' );
546 + if ( is_string( $page ) && false !== strpos( $page, $this->records_page_slug ) ) {
428 547 return true;
429 548 }
430 549
550 + if ( is_admin() && function_exists( 'get_current_screen' ) ) {
551 + $screen = get_current_screen();
552 +
553 + return ( Alerts::POST_TYPE === $screen->post_type );
554 + }
555 +
431 556 return false;
432 557 }
433 558
434 559 /**
@@ -433,9 +558,9 @@
433 558
434 559 /**
435 560 * Add a specific body class to all Stream admin screens
436 561 *
437 - * @param string $classes
562 + * @param string $classes CSS classes to output to body.
438 563 *
439 564 * @filter admin_body_class
440 565 *
441 566 * @return string
@@ -445,10 +570,10 @@
445 570
446 571 if ( $this->is_stream_screen() ) {
447 572 $stream_classes[] = $this->admin_body_class;
448 573
449 - if ( isset( $_GET['page'] ) ) {
450 - $stream_classes[] = sanitize_key( $_GET['page'] ); // input var okay
574 + if ( isset( $_GET['page'] ) ) { // // phpcs:ignore WordPress.Security.NonceVerification.Recommended
575 + $stream_classes[] = sanitize_key( $_GET['page'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
451 576 }
452 577 }
453 578
454 579 /**
@@ -469,16 +594,17 @@
469 594 *
470 595 * @action admin_enqueue_scripts
471 596 */
472 597 public function admin_menu_css() {
473 - wp_register_style( 'wp-stream-datepicker', $this->plugin->locations['url'] . 'ui/css/datepicker.css', array(), $this->plugin->get_version() );
598 + $min = wp_stream_min_suffix();
599 + wp_register_style( 'wp-stream-datepicker', $this->plugin->locations['url'] . 'ui/css/datepicker.' . $min . 'css', array(), $this->plugin->get_version() );
474 600 wp_register_style( 'wp-stream-icons', $this->plugin->locations['url'] . 'ui/stream-icons/style.css', array(), $this->plugin->get_version() );
475 601
476 - // Make sure we're working off a clean version
602 + // Make sure we're working off a clean version.
477 603 if ( ! file_exists( ABSPATH . WPINC . '/version.php' ) ) {
478 604 return;
479 605 }
480 - include( ABSPATH . WPINC . '/version.php' );
606 + include ABSPATH . WPINC . '/version.php';
481 607
482 608 if ( ! isset( $wp_version ) ) {
483 609 return;
484 610 }
@@ -537,10 +663,15 @@
537 663
538 664 \wp_add_inline_style( 'wp-admin', $css );
539 665 }
540 666
667 + /**
668 + * Handle the reset AJAX request to reset logs.
669 + *
670 + * @return bool
671 + */
541 672 public function wp_ajax_reset() {
542 - check_ajax_referer( 'stream_nonce', 'wp_stream_nonce' );
673 + check_ajax_referer( 'stream_nonce_reset', 'wp_stream_nonce_reset' );
543 674
544 675 if ( ! current_user_can( $this->settings_cap ) ) {
545 676 wp_die(
546 677 esc_html__( "You don't have sufficient privileges to do this action.", 'stream' )
@@ -552,9 +683,9 @@
552 683 if ( defined( 'WP_STREAM_TESTS' ) && WP_STREAM_TESTS ) {
553 684 return true;
554 685 }
555 686
556 - wp_redirect(
687 + wp_safe_redirect(
557 688 add_query_arg(
558 689 array(
559 690 'page' => is_network_admin() ? $this->network->network_settings_page_slug : $this->settings_page_slug,
560 691 'message' => 'data_erased',
@@ -565,14 +696,19 @@
565 696
566 697 exit;
567 698 }
568 699
700 + /**
701 + * Clears stream records from the database.
702 + *
703 + * @return void
704 + */
569 705 private function erase_stream_records() {
570 706 global $wpdb;
571 707
572 708 $where = '';
573 709
574 - if ( is_multisite() && ! is_plugin_active_for_network( $this->plugin->locations['plugin'] ) ) {
710 + if ( is_multisite() && ! $this->plugin->is_network_activated() ) {
575 711 $where .= $wpdb->prepare( ' AND `blog_id` = %d', get_current_blog_id() );
576 712 }
577 713
578 714 $wpdb->query(
@@ -583,8 +719,13 @@
583 719 WHERE 1=1 {$where};" // @codingStandardsIgnoreLine $where already prepared
584 720 );
585 721 }
586 722
723 + /**
724 + * Schedules a purge of records.
725 + *
726 + * @return void
727 + */
587 728 public function purge_schedule_setup() {
588 729 if ( ! wp_next_scheduled( 'wp_stream_auto_purge' ) ) {
589 730 wp_schedule_event( time(), 'twicedaily', 'wp_stream_auto_purge' );
590 731 }
@@ -589,41 +730,48 @@
589 730 wp_schedule_event( time(), 'twicedaily', 'wp_stream_auto_purge' );
590 731 }
591 732 }
592 733
734 + /**
735 + * Executes a scheduled purge
736 + *
737 + * @return void
738 + */
593 739 public function purge_scheduled_action() {
594 740 global $wpdb;
595 741
596 - // Don't purge when in Network Admin unless Stream is network activated
742 + // Don't purge when in Network Admin unless Stream is network activated.
597 743 if (
598 744 is_multisite()
599 745 &&
600 746 is_network_admin()
601 747 &&
602 - ! is_plugin_active_for_network( $this->plugin->locations['plugin'] )
748 + ! $this->plugin->is_network_activated()
603 749 ) {
604 750 return;
605 751 }
606 752
607 - if ( is_multisite() && is_plugin_active_for_network( $this->plugin->locations['plugin'] ) ) {
608 - $options = (array) get_site_option( 'wp_stream_network', array() );
753 + $defaults = $this->plugin->settings->get_defaults();
754 + if ( is_multisite() && $this->plugin->is_network_activated() ) {
755 + $options = (array) get_site_option( 'wp_stream_network', $defaults );
609 756 } else {
610 - $options = (array) get_option( 'wp_stream', array() );
757 + $options = (array) get_option( 'wp_stream', $defaults );
611 758 }
612 759
613 - if ( isset( $options['general_keep_records_indefinitely'] ) || ! isset( $options['general_records_ttl'] ) ) {
760 + if ( ! empty( $options['general_keep_records_indefinitely'] ) || ! isset( $options['general_records_ttl'] ) ) {
614 761 return;
615 762 }
616 763
617 - $days = $options['general_records_ttl'];
618 - $date = new DateTime( 'now', $timezone = new DateTimeZone( 'UTC' ) );
764 + $days = $options['general_records_ttl'];
765 + $timezone = new DateTimeZone( 'UTC' );
766 + $date = new DateTime( 'now', $timezone );
619 767
620 768 $date->sub( DateInterval::createFromDateString( "$days days" ) );
621 769
622 770 $where = $wpdb->prepare( ' AND `stream`.`created` < %s', $date->format( 'Y-m-d H:i:s' ) );
623 771
624 - // Multisite but NOT network activated, only purge the current blog
625 - if ( is_multisite() && ! is_plugin_active_for_network( $this->plugin->locations['plugin'] ) ) {
772 + // Multisite but NOT network activated, only purge the current blog.
773 + if ( is_multisite() && ! $this->plugin->is_network_activated() ) {
626 774 $where .= $wpdb->prepare( ' AND `blog_id` = %d', get_current_blog_id() );
627 775 }
628 776
629 777 $wpdb->query(
@@ -635,13 +783,15 @@
635 783 );
636 784 }
637 785
638 786 /**
639 - * @param array $links
640 - * @param string $file
787 + * Returns the admin action links.
641 788 *
642 789 * @filter plugin_action_links
643 790 *
791 + * @param array $links Action links.
792 + * @param string $file Plugin file.
793 + *
644 794 * @return array
645 795 */
646 796 public function plugin_action_links( $links, $file ) {
647 797 if ( plugin_basename( $this->plugin->locations['dir'] . 'stream.php' ) !== $file ) {
@@ -647,31 +797,31 @@
647 797 if ( plugin_basename( $this->plugin->locations['dir'] . 'stream.php' ) !== $file ) {
648 798 return $links;
649 799 }
650 800
651 - // Also don't show links in Network Admin if Stream isn't network enabled
652 - if ( is_network_admin() && is_multisite() && ! is_plugin_active_for_network( $this->plugin->locations['plugin'] ) ) {
801 + // Also don't show links in Network Admin if Stream isn't network enabled.
802 + if ( is_network_admin() && is_multisite() && ! $this->plugin->is_network_activated() ) {
653 803 return $links;
654 804 }
655 805
656 806 if ( is_network_admin() ) {
657 - $admin_page_url = add_query_arg( array( 'page' => $this->network->network_settings_page_slug ), network_admin_url( $this->admin_parent_page ) );
807 + $admin_page_url = add_query_arg(
808 + array(
809 + 'page' => $this->network->network_settings_page_slug,
810 + ),
811 + network_admin_url( $this->admin_parent_page )
812 + );
658 813 } else {
659 - $admin_page_url = add_query_arg( array( 'page' => $this->settings_page_slug ), admin_url( $this->admin_parent_page ) );
814 + $admin_page_url = add_query_arg(
815 + array(
816 + 'page' => $this->settings_page_slug,
817 + ),
818 + admin_url( $this->admin_parent_page )
819 + );
660 820 }
661 821
662 822 $links[] = sprintf( '<a href="%s">%s</a>', esc_url( $admin_page_url ), esc_html__( 'Settings', 'default' ) );
663 823
664 - $url = add_query_arg(
665 - array(
666 - 'action' => 'wp_stream_uninstall',
667 - 'wp_stream_nonce' => wp_create_nonce( 'stream_nonce' ),
668 - ),
669 - admin_url( 'admin-ajax.php' )
670 - );
671 -
672 - $links[] = sprintf( '<span id="wp_stream_uninstall" class="delete"><a href="%s">%s</a></span>', esc_url( $url ), esc_html__( 'Uninstall', 'stream' ) );
673 -
674 824 return $links;
675 825 }
676 826
677 827 /**
@@ -680,12 +830,12 @@
680 830 public function render_list_table() {
681 831 $this->list_table->prepare_items();
682 832 ?>
683 833 <div class="wrap">
684 - <h1><?php echo esc_html( get_admin_page_title() ) ?></h1>
685 - <?php $this->list_table->display() ?>
834 + <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
835 + <?php $this->list_table->display(); ?>
686 836 </div>
687 - <?php
837 + <?php
688 838 }
689 839
690 840 /**
691 841 * Render settings page
@@ -697,28 +847,28 @@
697 847 $page_description = apply_filters( 'wp_stream_settings_form_description', '' );
698 848
699 849 $sections = $this->plugin->settings->get_fields();
700 850 $active_tab = wp_stream_filter_input( INPUT_GET, 'tab' );
701 -
702 - wp_enqueue_script( 'wp-stream-settings', $this->plugin->locations['url'] . 'ui/js/settings.js', array( 'jquery' ), $this->plugin->get_version(), true );
851 + $min = wp_stream_min_suffix();
852 + wp_enqueue_script( 'wp-stream-settings', $this->plugin->locations['url'] . 'ui/js/settings.' . $min . 'js', array( 'jquery' ), $this->plugin->get_version(), true );
703 853 ?>
704 854 <div class="wrap">
705 - <h1><?php echo esc_html( get_admin_page_title() ) ?></h1>
855 + <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
706 856
707 857 <?php if ( ! empty( $page_description ) ) : ?>
708 - <p><?php echo esc_html( $page_description ) ?></p>
858 + <p><?php echo esc_html( $page_description ); ?></p>
709 859 <?php endif; ?>
710 860
711 - <?php settings_errors() ?>
861 + <?php settings_errors(); ?>
712 862
713 863 <?php if ( count( $sections ) > 1 ) : ?>
714 864 <h2 class="nav-tab-wrapper">
715 - <?php $i = 0 ?>
865 + <?php $i = 0; ?>
716 866 <?php foreach ( $sections as $section => $data ) : ?>
717 - <?php $i ++ ?>
718 - <?php $is_active = ( ( 1 === $i && ! $active_tab ) || $active_tab === $section ) ?>
719 - <a href="<?php echo esc_url( add_query_arg( 'tab', $section ) ) ?>" class="nav-tab<?php if ( $is_active ) { echo esc_attr( ' nav-tab-active' ); } ?>">
720 - <?php echo esc_html( $data['title'] ) ?>
867 + <?php ++$i; ?>
868 + <?php $is_active = ( ( 1 === $i && ! $active_tab ) || $active_tab === $section ); ?>
869 + <a href="<?php echo esc_url( add_query_arg( 'tab', $section ) ); ?>" class="nav-tab <?php echo $is_active ? esc_attr( ' nav-tab-active' ) : ''; ?>">
870 + <?php echo esc_html( $data['title'] ); ?>
721 871 </a>
722 872 <?php endforeach; ?>
723 873 </h2>
724 874 <?php endif; ?>
@@ -723,29 +873,29 @@
723 873 </h2>
724 874 <?php endif; ?>
725 875
726 876 <div class="nav-tab-content" id="tab-content-settings">
727 - <form method="post" action="<?php echo esc_attr( $form_action ) ?>" enctype="multipart/form-data">
877 + <form method="post" action="<?php echo esc_attr( $form_action ); ?>" enctype="multipart/form-data">
728 878 <div class="settings-sections">
729 - <?php
730 - $i = 0;
731 - foreach ( $sections as $section => $data ) {
732 - $i++;
879 + <?php
880 + $i = 0;
881 + foreach ( $sections as $section => $data ) {
882 + ++$i;
733 883
734 - $is_active = ( ( 1 === $i && ! $active_tab ) || $active_tab === $section );
884 + $is_active = ( ( 1 === $i && ! $active_tab ) || $active_tab === $section );
735 885
736 - if ( $is_active ) {
737 - settings_fields( $option_key );
738 - do_settings_sections( $option_key );
739 - }
740 - }
741 - ?>
886 + if ( $is_active ) {
887 + settings_fields( $option_key );
888 + do_settings_sections( $option_key );
889 + }
890 + }
891 + ?>
742 892 </div>
743 - <?php submit_button() ?>
893 + <?php submit_button(); ?>
744 894 </form>
745 895 </div>
746 896 </div>
747 - <?php
897 + <?php
748 898 }
749 899
750 900 /**
751 901 * Instantiate the list table
@@ -750,20 +900,25 @@
750 900 /**
751 901 * Instantiate the list table
752 902 */
753 903 public function register_list_table() {
754 - $this->list_table = new List_Table( $this->plugin, array( 'screen' => $this->screen_id['main'] ) );
904 + $this->list_table = new List_Table(
905 + $this->plugin,
906 + array(
907 + 'screen' => $this->screen_id['main'],
908 + )
909 + );
755 910 }
756 911
757 912 /**
758 913 * Check if a particular role has access
759 914 *
760 - * @param string $role
915 + * @param string $role User role.
761 916 *
762 917 * @return bool
763 918 */
764 919 private function role_can_view( $role ) {
765 - if ( in_array( $role, $this->plugin->settings->options['general_role_access'] ) ) {
920 + if ( in_array( $role, $this->plugin->settings->options['general_role_access'], true ) ) {
766 921 return true;
767 922 }
768 923
769 924 return false;
@@ -771,12 +926,12 @@
771 926
772 927 /**
773 928 * Filter user caps to dynamically grant our view cap based on allowed roles
774 929 *
775 - * @param $allcaps
776 - * @param $caps
777 - * @param $args
778 - * @param $user
930 + * @param array $allcaps All capabilities.
931 + * @param array $caps Required caps.
932 + * @param array $args Unused.
933 + * @param WP_User $user User.
779 934 *
780 935 * @filter user_has_cap
781 936 *
782 937 * @return array
@@ -802,9 +957,9 @@
802 957
803 958 $stream_view_caps = array( $this->view_cap );
804 959
805 960 foreach ( $caps as $cap ) {
806 - if ( in_array( $cap, $stream_view_caps ) ) {
961 + if ( in_array( $cap, $stream_view_caps, true ) ) {
807 962 foreach ( $roles as $role ) {
808 963 if ( $this->role_can_view( $role ) ) {
809 964 $allcaps[ $cap ] = true;
810 965
@@ -821,11 +976,11 @@
821 976 * Filter role caps to dynamically grant our view cap based on allowed roles
822 977 *
823 978 * @filter role_has_cap
824 979 *
825 - * @param $allcaps
826 - * @param $cap
827 - * @param $role
980 + * @param array $allcaps All capabilities.
981 + * @param string $cap Require cap.
982 + * @param string $role User role.
828 983 *
829 984 * @return array
830 985 */
831 986 public function filter_role_caps( $allcaps, $cap, $role ) {
@@ -830,9 +985,9 @@
830 985 */
831 986 public function filter_role_caps( $allcaps, $cap, $role ) {
832 987 $stream_view_caps = array( $this->view_cap );
833 988
834 - if ( in_array( $cap, $stream_view_caps ) && $this->role_can_view( $role ) ) {
989 + if ( in_array( $cap, $stream_view_caps, true ) && $this->role_can_view( $role ) ) {
835 990 $allcaps[ $cap ] = true;
836 991 }
837 992
838 993 return $allcaps;
@@ -838,15 +993,27 @@
838 993 return $allcaps;
839 994 }
840 995
841 996 /**
997 + * Ajax callback for return a user list.
998 + *
842 999 * @action wp_ajax_wp_stream_filters
843 1000 */
844 1001 public function ajax_filters() {
1002 + if ( ! defined( 'DOING_AJAX' ) || ! current_user_can( $this->plugin->admin->settings_cap ) ) {
1003 + wp_die( '-1' );
1004 + }
1005 +
1006 + check_ajax_referer( 'stream_filters_user_search_nonce', 'nonce' );
1007 +
845 1008 switch ( wp_stream_filter_input( INPUT_GET, 'filter' ) ) {
846 1009 case 'user_id':
847 1010 $users = array_merge(
848 - array( 0 => (object) array( 'display_name' => 'WP-CLI' ) ),
1011 + array(
1012 + 0 => (object) array(
1013 + 'display_name' => 'WP-CLI',
1014 + ),
1015 + ),
849 1016 get_users()
850 1017 );
851 1018
852 1019 $search = wp_stream_filter_input( INPUT_GET, 'q' );
@@ -853,9 +1020,9 @@
853 1020 if ( $search ) {
854 1021 // `search` arg for get_users() is not enough
855 1022 $users = array_filter(
856 1023 $users,
857 - function( $user ) use ( $search ) {
1024 + function ( $user ) use ( $search ) {
858 1025 return false !== mb_strpos( mb_strtolower( $user->display_name ), mb_strtolower( $search ) );
859 1026 }
860 1027 );
861 1028 }
@@ -863,9 +1030,9 @@
863 1030 if ( count( $users ) > $this->preload_users_max ) {
864 1031 $users = array_slice( $users, 0, $this->preload_users_max );
865 1032 }
866 1033
867 - // Get gravatar / roles for final result set
1034 + // Get gravatar / roles for final result set.
868 1035 $results = $this->get_users_record_meta( $users );
869 1036
870 1037 break;
871 1038 }
@@ -870,68 +1037,32 @@
870 1037 break;
871 1038 }
872 1039
873 1040 if ( isset( $results ) ) {
874 - echo wp_stream_json_encode( array_values( $results ) ); // xss ok
1041 + echo wp_json_encode( $results );
875 1042 }
876 1043
877 - if ( defined( 'WP_STREAM_TESTS' ) && WP_STREAM_TESTS ) {
878 - return;
879 - }
880 -
881 1044 die();
882 1045 }
883 1046
884 1047 /**
885 - * @action wp_ajax_wp_stream_get_filter_value_by_id
1048 + * Return relevant user meta data.
1049 + *
1050 + * @param array $authors Author data.
1051 + * @return array
886 1052 */
887 - public function get_filter_value_by_id() {
888 - $filter = wp_stream_filter_input( INPUT_POST, 'filter' );
889 -
890 - switch ( $filter ) {
891 - case 'user_id':
892 - $id = wp_stream_filter_input( INPUT_POST, 'id' );
893 -
894 - if ( '0' === $id ) {
895 - $value = 'WP-CLI';
896 -
897 - break;
898 - }
899 -
900 - $user = get_userdata( $id );
901 -
902 - if ( ! $user || is_wp_error( $user ) ) {
903 - $value = '';
904 - } else {
905 - $value = $user->display_name;
906 - }
907 -
908 - break;
909 - default:
910 - $value = '';
911 - }
912 -
913 - echo wp_stream_json_encode( $value ); // xss ok
914 -
915 - if ( defined( 'WP_STREAM_TESTS' ) && WP_STREAM_TESTS ) {
916 - return;
917 - }
918 -
919 - die();
920 - }
921 -
922 1053 public function get_users_record_meta( $authors ) {
923 1054 $authors_records = array();
924 1055
925 1056 foreach ( $authors as $user_id => $args ) {
926 - $author = new Author( $user_id );
1057 + $author = new Author( $args->ID );
927 1058
928 1059 $authors_records[ $user_id ] = array(
929 - 'text' => $author->get_display_name(),
930 - 'id' => $user_id,
931 - 'label' => $author->get_display_name(),
932 - 'icon' => $author->get_avatar_src( 32 ),
933 - 'title' => '',
1060 + 'text' => $author->get_display_name(),
1061 + 'id' => $author->id,
1062 + 'label' => $author->get_display_name(),
1063 + 'icon' => $author->get_avatar_src( 32 ),
1064 + 'title' => '',
934 1065 );
935 1066 }
936 1067
937 1068 return $authors_records;
@@ -939,18 +1070,15 @@
939 1070
940 1071 /**
941 1072 * Get user meta in a way that is also safe for VIP
942 1073 *
943 - * @param int $user_id
944 - * @param string $meta_key
945 - * @param bool $single (optional)
1074 + * @param int $user_id User ID.
1075 + * @param string $meta_key Meta key.
1076 + * @param bool $single Return first found meta value connected to the meta key (optional).
946 1077 *
947 1078 * @return mixed
948 1079 */
949 - function get_user_meta( $user_id, $meta_key, $single = true ) {
950 - if ( wp_stream_is_vip() && function_exists( 'get_user_attribute' ) ) {
951 - return get_user_attribute( $user_id, $meta_key );
952 - }
1080 + public function get_user_meta( $user_id, $meta_key, $single = true ) {
953 1081 return get_user_meta( $user_id, $meta_key, $single );
954 1082 }
955 1083
956 1084 /**
@@ -955,19 +1083,16 @@
955 1083
956 1084 /**
957 1085 * Update user meta in a way that is also safe for VIP
958 1086 *
959 - * @param int $user_id
960 - * @param string $meta_key
961 - * @param mixed $meta_value
962 - * @param mixed $prev_value (optional)
1087 + * @param int $user_id User ID.
1088 + * @param string $meta_key Meta key.
1089 + * @param mixed $meta_value Meta value.
1090 + * @param mixed $prev_value Previous meta value being overwritten (optional).
963 1091 *
964 1092 * @return int|bool
965 1093 */
966 - function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
967 - if ( wp_stream_is_vip() && function_exists( 'update_user_attribute' ) ) {
968 - return update_user_attribute( $user_id, $meta_key, $meta_value );
969 - }
1094 + public function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
970 1095 return update_user_meta( $user_id, $meta_key, $meta_value, $prev_value );
971 1096 }
972 1097
973 1098 /**
@@ -972,17 +1097,14 @@
972 1097
973 1098 /**
974 1099 * Delete user meta in a way that is also safe for VIP
975 1100 *
976 - * @param int $user_id
977 - * @param string $meta_key
978 - * @param mixed $meta_value (optional)
1101 + * @param int $user_id User ID.
1102 + * @param string $meta_key Meta key.
1103 + * @param mixed $meta_value Meta value (optional).
979 1104 *
980 1105 * @return bool
981 1106 */
982 - function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) {
983 - if ( wp_stream_is_vip() && function_exists( 'delete_user_attribute' ) ) {
984 - return delete_user_attribute( $user_id, $meta_key, $meta_value );
985 - }
1107 + public function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) {
986 1108 return delete_user_meta( $user_id, $meta_key, $meta_value );
987 1109 }
988 1110 }