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