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 +340 -248 3.0.04.0.2 View file →
@@ -1,34 +1,51 @@
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 /**
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,68 @@
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' ) );
160 -
161 - // Auto purge setup
194 + // Auto purge setup.
162 195 add_action( 'wp_loaded', array( $this, 'purge_schedule_setup' ) );
163 - 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 + );
164 203
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' ) );
204 + // Ajax users list.
205 + add_action(
206 + 'wp_ajax_wp_stream_filters',
207 + array(
208 + $this,
209 + 'ajax_filters',
210 + )
211 + );
176 212 }
177 213
178 214 /**
179 215 * Load admin classes
@@ -182,17 +218,23 @@
182 218 */
183 219 public function init() {
184 220 $this->network = new Network( $this->plugin );
185 221 $this->live_update = new Live_Update( $this->plugin );
186 - $this->migrate = new Migrate( $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 + }
187 229 }
188 230
189 231 /**
190 - * Output specific updates passed as URL parameters
232 + * Output specific updates passed as URL parameters.
191 233 *
192 234 * @action admin_notices
193 235 *
194 - * @return string
236 + * @return void
195 237 */
196 238 public function prepare_admin_notices() {
197 239 $message = wp_stream_filter_input( INPUT_GET, 'message' );
198 240
@@ -205,14 +247,14 @@
205 247
206 248 /**
207 249 * Handle notice messages according to the appropriate context (WP-CLI or the WP Admin)
208 250 *
209 - * @param string $message
210 - * @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).
211 253 */
212 254 public function notice( $message, $is_error = true ) {
213 255 if ( defined( 'WP_CLI' ) && WP_CLI ) {
214 - $message = strip_tags( $message );
256 + $message = wp_strip_all_tags( $message );
215 257
216 258 if ( $is_error ) {
217 259 WP_CLI::warning( $message );
218 260 } else {
@@ -218,14 +260,14 @@
218 260 } else {
219 261 WP_CLI::success( $message );
220 262 }
221 263 } else {
222 - // 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.
223 265 add_action( 'shutdown', array( $this, 'admin_notices' ) );
224 266
225 267 $notice = compact( 'message', 'is_error' );
226 268
227 - if ( ! in_array( $notice, $this->notices ) ) {
269 + if ( ! in_array( $notice, $this->notices, true ) ) {
228 270 $this->notices[] = $notice;
229 271 }
230 272 }
231 273 }
@@ -264,9 +306,9 @@
264 306 * Register menu page
265 307 *
266 308 * @action admin_menu
267 309 *
268 - * @return bool|void
310 + * @return void
269 311 */
270 312 public function register_menu() {
271 313 /**
272 314 * Filter the main admin menu title
@@ -301,8 +343,16 @@
301 343 $main_menu_position
302 344 );
303 345
304 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 + /**
305 355 * Filter the Settings admin page title
306 356 *
307 357 * @return string
308 358 */
@@ -324,10 +374,16 @@
324 374 * @return void
325 375 */
326 376 do_action( 'wp_stream_admin_menu_screens' );
327 377
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' ) );
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 + );
330 386 }
331 387 }
332 388
333 389 /**
@@ -334,39 +390,80 @@
334 390 * Enqueue scripts/styles for admin screen
335 391 *
336 392 * @action admin_enqueue_scripts
337 393 *
338 - * @param string $hook
394 + * @param string $hook Current hook.
339 395 *
340 396 * @return void
341 397 */
342 398 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 );
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 );
346 402
347 403 $locale = strtolower( substr( get_locale(), 0, 2 ) );
348 404 $file_tmpl = 'ui/lib/timeago/locales/jquery.timeago.%s.js';
349 405
350 406 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' );
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 + );
352 414 } else {
353 - 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 + );
354 422 }
355 423
356 - 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() );
357 426
358 - $script_screens = array( 'plugins.php', 'user-edit.php', 'user-new.php', 'profile.php' );
427 + $script_screens = array( 'plugins.php' );
359 428
360 - if ( in_array( $hook, $this->screen_id ) || in_array( $hook, $script_screens ) ) {
361 - wp_enqueue_script( 'select2' );
362 - 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' );
363 432
364 - wp_enqueue_script( 'timeago' );
365 - wp_enqueue_script( 'timeago-locale' );
433 + wp_enqueue_script( 'wp-stream-timeago' );
434 + wp_enqueue_script( 'wp-stream-timeago-locale' );
366 435
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() );
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 + );
369 466
370 467 wp_localize_script(
371 468 'wp-stream-admin',
372 469 'wp_stream',
@@ -371,11 +468,10 @@
371 468 'wp-stream-admin',
372 469 'wp_stream',
373 470 array(
374 471 'i18n' => array(
375 - 'confirm_purge' => esc_html__( 'Are you sure you want to delete all Stream activity records from the database? This cannot be undone.', 'stream' ),
376 - 'confirm_defaults' => esc_html__( 'Are you sure you want to reset all site settings to default? This cannot be undone.', 'stream' ),
377 - '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' ),
378 474 ),
379 475 'locale' => esc_js( $locale ),
380 476 'gmt_offset' => get_option( 'gmt_offset' ),
381 477 )
@@ -380,47 +476,25 @@
380 476 'gmt_offset' => get_option( 'gmt_offset' ),
381 477 )
382 478 );
383 479
480 + $order_types = array( 'asc', 'desc' );
481 +
384 482 wp_localize_script(
385 483 'wp-stream-live-updates',
386 484 'wp_stream_live_updates',
387 485 array(
388 486 '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
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
393 493 )
394 494 );
395 495 }
396 496
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 497 /**
424 498 * The maximum number of items that can be updated in bulk without receiving a warning.
425 499 *
426 500 * Stream watches for bulk actions performed in the WordPress Admin (such as updating
@@ -433,15 +507,23 @@
433 507 * @return int
434 508 */
435 509 $bulk_actions_threshold = apply_filters( 'wp_stream_bulk_actions_threshold', 100 );
436 510
437 - 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 +
438 519 wp_localize_script(
439 520 'wp-stream-global',
440 521 'wp_stream_global',
441 522 array(
442 - 'bulk_actions' => array(
443 - 'i18n' => array(
523 + 'bulk_actions' => array(
524 + 'i18n' => array(
525 + /* translators: %s: a number of items (e.g. "1,742") */
444 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 ) ) ),
445 527 ),
446 528 'threshold' => absint( $bulk_actions_threshold ),
447 529 ),
@@ -455,12 +537,23 @@
455 537 *
456 538 * @return bool
457 539 */
458 540 public function is_stream_screen() {
459 - 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 ) ) {
460 547 return true;
461 548 }
462 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 +
463 556 return false;
464 557 }
465 558
466 559 /**
@@ -465,9 +558,9 @@
465 558
466 559 /**
467 560 * Add a specific body class to all Stream admin screens
468 561 *
469 - * @param string $classes
562 + * @param string $classes CSS classes to output to body.
470 563 *
471 564 * @filter admin_body_class
472 565 *
473 566 * @return string
@@ -477,10 +570,10 @@
477 570
478 571 if ( $this->is_stream_screen() ) {
479 572 $stream_classes[] = $this->admin_body_class;
480 573
481 - if ( isset( $_GET['page'] ) ) {
482 - $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
483 576 }
484 577 }
485 578
486 579 /**
@@ -501,17 +594,17 @@
501 594 *
502 595 * @action admin_enqueue_scripts
503 596 */
504 597 public function admin_menu_css() {
505 - wp_register_style( 'jquery-ui', '//ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/themes/base/jquery-ui.css', array(), '1.10.1' );
506 - wp_register_style( 'wp-stream-datepicker', $this->plugin->locations['url'] . 'ui/css/datepicker.css', array( 'jquery-ui' ), $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() );
507 600 wp_register_style( 'wp-stream-icons', $this->plugin->locations['url'] . 'ui/stream-icons/style.css', array(), $this->plugin->get_version() );
508 601
509 - // Make sure we're working off a clean version
602 + // Make sure we're working off a clean version.
510 603 if ( ! file_exists( ABSPATH . WPINC . '/version.php' ) ) {
511 604 return;
512 605 }
513 - include( ABSPATH . WPINC . '/version.php' );
606 + include ABSPATH . WPINC . '/version.php';
514 607
515 608 if ( ! isset( $wp_version ) ) {
516 609 return;
517 610 }
@@ -538,9 +631,9 @@
538 631 #adminmenu #menu-posts-feedback div.wp-menu-image {
539 632 background: none !important;
540 633 background-repeat: no-repeat;
541 634 }
542 - body.{$body_class} #wpbody-content .wrap h2:nth-child(1):before {
635 + body.{$body_class} #wpbody-content .wrap h1:nth-child(1):before {
543 636 font-family: 'WP Stream' !important;
544 637 content: '\\73';
545 638 padding: 0 8px 0 0;
546 639 }
@@ -570,10 +663,15 @@
570 663
571 664 \wp_add_inline_style( 'wp-admin', $css );
572 665 }
573 666
667 + /**
668 + * Handle the reset AJAX request to reset logs.
669 + *
670 + * @return bool
671 + */
574 672 public function wp_ajax_reset() {
575 - check_ajax_referer( 'stream_nonce', 'wp_stream_nonce' );
673 + check_ajax_referer( 'stream_nonce_reset', 'wp_stream_nonce_reset' );
576 674
577 675 if ( ! current_user_can( $this->settings_cap ) ) {
578 676 wp_die(
579 677 esc_html__( "You don't have sufficient privileges to do this action.", 'stream' )
@@ -585,9 +683,9 @@
585 683 if ( defined( 'WP_STREAM_TESTS' ) && WP_STREAM_TESTS ) {
586 684 return true;
587 685 }
588 686
589 - wp_redirect(
687 + wp_safe_redirect(
590 688 add_query_arg(
591 689 array(
592 690 'page' => is_network_admin() ? $this->network->network_settings_page_slug : $this->settings_page_slug,
593 691 'message' => 'data_erased',
@@ -598,14 +696,19 @@
598 696
599 697 exit;
600 698 }
601 699
700 + /**
701 + * Clears stream records from the database.
702 + *
703 + * @return void
704 + */
602 705 private function erase_stream_records() {
603 706 global $wpdb;
604 707
605 708 $where = '';
606 709
607 - if ( is_multisite() && ! is_plugin_active_for_network( $this->plugin->locations['plugin'] ) ) {
710 + if ( is_multisite() && ! $this->plugin->is_network_activated() ) {
608 711 $where .= $wpdb->prepare( ' AND `blog_id` = %d', get_current_blog_id() );
609 712 }
610 713
611 714 $wpdb->query(
@@ -612,12 +715,17 @@
612 715 "DELETE `stream`, `meta`
613 716 FROM {$wpdb->stream} AS `stream`
614 717 LEFT JOIN {$wpdb->streammeta} AS `meta`
615 718 ON `meta`.`record_id` = `stream`.`ID`
616 - WHERE 1=1 {$where};"
719 + WHERE 1=1 {$where};" // @codingStandardsIgnoreLine $where already prepared
617 720 );
618 721 }
619 722
723 + /**
724 + * Schedules a purge of records.
725 + *
726 + * @return void
727 + */
620 728 public function purge_schedule_setup() {
621 729 if ( ! wp_next_scheduled( 'wp_stream_auto_purge' ) ) {
622 730 wp_schedule_event( time(), 'twicedaily', 'wp_stream_auto_purge' );
623 731 }
@@ -622,37 +730,48 @@
622 730 wp_schedule_event( time(), 'twicedaily', 'wp_stream_auto_purge' );
623 731 }
624 732 }
625 733
734 + /**
735 + * Executes a scheduled purge
736 + *
737 + * @return void
738 + */
626 739 public function purge_scheduled_action() {
627 740 global $wpdb;
628 741
629 - // 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.
630 743 if (
631 744 is_multisite()
632 745 &&
633 746 is_network_admin()
634 747 &&
635 - ! is_plugin_active_for_network( $this->plugin->locations['plugin'] )
748 + ! $this->plugin->is_network_activated()
636 749 ) {
637 750 return;
638 751 }
639 752
640 - if ( is_multisite() && is_plugin_active_for_network( $this->plugin->locations['plugin'] ) ) {
641 - $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 );
642 756 } else {
643 - $options = (array) get_option( 'wp_stream', array() );
757 + $options = (array) get_option( 'wp_stream', $defaults );
644 758 }
645 759
646 - $days = $options['general_records_ttl'];
647 - $date = new DateTime( 'now', $timezone = new DateTimeZone( 'UTC' ) );
760 + if ( ! empty( $options['general_keep_records_indefinitely'] ) || ! isset( $options['general_records_ttl'] ) ) {
761 + return;
762 + }
648 763
764 + $days = $options['general_records_ttl'];
765 + $timezone = new DateTimeZone( 'UTC' );
766 + $date = new DateTime( 'now', $timezone );
767 +
649 768 $date->sub( DateInterval::createFromDateString( "$days days" ) );
650 769
651 770 $where = $wpdb->prepare( ' AND `stream`.`created` < %s', $date->format( 'Y-m-d H:i:s' ) );
652 771
653 - // Multisite but NOT network activated, only purge the current blog
654 - 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() ) {
655 774 $where .= $wpdb->prepare( ' AND `blog_id` = %d', get_current_blog_id() );
656 775 }
657 776
658 777 $wpdb->query(
@@ -659,18 +778,20 @@
659 778 "DELETE `stream`, `meta`
660 779 FROM {$wpdb->stream} AS `stream`
661 780 LEFT JOIN {$wpdb->streammeta} AS `meta`
662 781 ON `meta`.`record_id` = `stream`.`ID`
663 - WHERE 1=1 {$where};"
782 + WHERE 1=1 {$where};" // @codingStandardsIgnoreLine $where already prepared
664 783 );
665 784 }
666 785
667 786 /**
668 - * @param array $links
669 - * @param string $file
787 + * Returns the admin action links.
670 788 *
671 789 * @filter plugin_action_links
672 790 *
791 + * @param array $links Action links.
792 + * @param string $file Plugin file.
793 + *
673 794 * @return array
674 795 */
675 796 public function plugin_action_links( $links, $file ) {
676 797 if ( plugin_basename( $this->plugin->locations['dir'] . 'stream.php' ) !== $file ) {
@@ -676,31 +797,31 @@
676 797 if ( plugin_basename( $this->plugin->locations['dir'] . 'stream.php' ) !== $file ) {
677 798 return $links;
678 799 }
679 800
680 - // Also don't show links in Network Admin if Stream isn't network enabled
681 - 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() ) {
682 803 return $links;
683 804 }
684 805
685 806 if ( is_network_admin() ) {
686 - $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 + );
687 813 } else {
688 - $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 + );
689 820 }
690 821
691 822 $links[] = sprintf( '<a href="%s">%s</a>', esc_url( $admin_page_url ), esc_html__( 'Settings', 'default' ) );
692 823
693 - $url = add_query_arg(
694 - array(
695 - 'action' => 'wp_stream_uninstall',
696 - 'wp_stream_nonce' => wp_create_nonce( 'stream_nonce' ),
697 - ),
698 - admin_url( 'admin-ajax.php' )
699 - );
700 -
701 - $links[] = sprintf( '<span id="wp_stream_uninstall" class="delete"><a href="%s">%s</a></span>', esc_url( $url ), esc_html__( 'Uninstall', 'stream' ) );
702 -
703 824 return $links;
704 825 }
705 826
706 827 /**
@@ -709,12 +830,12 @@
709 830 public function render_list_table() {
710 831 $this->list_table->prepare_items();
711 832 ?>
712 833 <div class="wrap">
713 - <h2><?php echo esc_html( get_admin_page_title() ) ?></h2>
714 - <?php $this->list_table->display() ?>
834 + <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
835 + <?php $this->list_table->display(); ?>
715 836 </div>
716 - <?php
837 + <?php
717 838 }
718 839
719 840 /**
720 841 * Render settings page
@@ -726,28 +847,28 @@
726 847 $page_description = apply_filters( 'wp_stream_settings_form_description', '' );
727 848
728 849 $sections = $this->plugin->settings->get_fields();
729 850 $active_tab = wp_stream_filter_input( INPUT_GET, 'tab' );
730 -
731 - 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 );
732 853 ?>
733 854 <div class="wrap">
734 - <h2><?php echo esc_html( get_admin_page_title() ) ?></h2>
855 + <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
735 856
736 857 <?php if ( ! empty( $page_description ) ) : ?>
737 - <p><?php echo esc_html( $page_description ) ?></p>
858 + <p><?php echo esc_html( $page_description ); ?></p>
738 859 <?php endif; ?>
739 860
740 - <?php settings_errors() ?>
861 + <?php settings_errors(); ?>
741 862
742 863 <?php if ( count( $sections ) > 1 ) : ?>
743 864 <h2 class="nav-tab-wrapper">
744 - <?php $i = 0 ?>
865 + <?php $i = 0; ?>
745 866 <?php foreach ( $sections as $section => $data ) : ?>
746 - <?php $i ++ ?>
747 - <?php $is_active = ( ( 1 === $i && ! $active_tab ) || $active_tab === $section ) ?>
748 - <a href="<?php echo esc_url( add_query_arg( 'tab', $section ) ) ?>" class="nav-tab<?php if ( $is_active ) { echo esc_attr( ' nav-tab-active' ); } ?>">
749 - <?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'] ); ?>
750 871 </a>
751 872 <?php endforeach; ?>
752 873 </h2>
753 874 <?php endif; ?>
@@ -752,29 +873,29 @@
752 873 </h2>
753 874 <?php endif; ?>
754 875
755 876 <div class="nav-tab-content" id="tab-content-settings">
756 - <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">
757 878 <div class="settings-sections">
758 - <?php
759 - $i = 0;
760 - foreach ( $sections as $section => $data ) {
761 - $i++;
879 + <?php
880 + $i = 0;
881 + foreach ( $sections as $section => $data ) {
882 + ++$i;
762 883
763 - $is_active = ( ( 1 === $i && ! $active_tab ) || $active_tab === $section );
884 + $is_active = ( ( 1 === $i && ! $active_tab ) || $active_tab === $section );
764 885
765 - if ( $is_active ) {
766 - settings_fields( $option_key );
767 - do_settings_sections( $option_key );
768 - }
769 - }
770 - ?>
886 + if ( $is_active ) {
887 + settings_fields( $option_key );
888 + do_settings_sections( $option_key );
889 + }
890 + }
891 + ?>
771 892 </div>
772 - <?php submit_button() ?>
893 + <?php submit_button(); ?>
773 894 </form>
774 895 </div>
775 896 </div>
776 - <?php
897 + <?php
777 898 }
778 899
779 900 /**
780 901 * Instantiate the list table
@@ -779,20 +900,25 @@
779 900 /**
780 901 * Instantiate the list table
781 902 */
782 903 public function register_list_table() {
783 - $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 + );
784 910 }
785 911
786 912 /**
787 913 * Check if a particular role has access
788 914 *
789 - * @param string $role
915 + * @param string $role User role.
790 916 *
791 917 * @return bool
792 918 */
793 919 private function role_can_view( $role ) {
794 - if ( in_array( $role, $this->plugin->settings->options['general_role_access'] ) ) {
920 + if ( in_array( $role, $this->plugin->settings->options['general_role_access'], true ) ) {
795 921 return true;
796 922 }
797 923
798 924 return false;
@@ -800,12 +926,12 @@
800 926
801 927 /**
802 928 * Filter user caps to dynamically grant our view cap based on allowed roles
803 929 *
804 - * @param $allcaps
805 - * @param $caps
806 - * @param $args
807 - * @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.
808 934 *
809 935 * @filter user_has_cap
810 936 *
811 937 * @return array
@@ -831,9 +957,9 @@
831 957
832 958 $stream_view_caps = array( $this->view_cap );
833 959
834 960 foreach ( $caps as $cap ) {
835 - if ( in_array( $cap, $stream_view_caps ) ) {
961 + if ( in_array( $cap, $stream_view_caps, true ) ) {
836 962 foreach ( $roles as $role ) {
837 963 if ( $this->role_can_view( $role ) ) {
838 964 $allcaps[ $cap ] = true;
839 965
@@ -850,11 +976,11 @@
850 976 * Filter role caps to dynamically grant our view cap based on allowed roles
851 977 *
852 978 * @filter role_has_cap
853 979 *
854 - * @param $allcaps
855 - * @param $cap
856 - * @param $role
980 + * @param array $allcaps All capabilities.
981 + * @param string $cap Require cap.
982 + * @param string $role User role.
857 983 *
858 984 * @return array
859 985 */
860 986 public function filter_role_caps( $allcaps, $cap, $role ) {
@@ -859,9 +985,9 @@
859 985 */
860 986 public function filter_role_caps( $allcaps, $cap, $role ) {
861 987 $stream_view_caps = array( $this->view_cap );
862 988
863 - 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 ) ) {
864 990 $allcaps[ $cap ] = true;
865 991 }
866 992
867 993 return $allcaps;
@@ -867,15 +993,27 @@
867 993 return $allcaps;
868 994 }
869 995
870 996 /**
997 + * Ajax callback for return a user list.
998 + *
871 999 * @action wp_ajax_wp_stream_filters
872 1000 */
873 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 +
874 1008 switch ( wp_stream_filter_input( INPUT_GET, 'filter' ) ) {
875 1009 case 'user_id':
876 1010 $users = array_merge(
877 - array( 0 => (object) array( 'display_name' => 'WP-CLI' ) ),
1011 + array(
1012 + 0 => (object) array(
1013 + 'display_name' => 'WP-CLI',
1014 + ),
1015 + ),
878 1016 get_users()
879 1017 );
880 1018
881 1019 $search = wp_stream_filter_input( INPUT_GET, 'q' );
@@ -892,9 +1030,9 @@
892 1030 if ( count( $users ) > $this->preload_users_max ) {
893 1031 $users = array_slice( $users, 0, $this->preload_users_max );
894 1032 }
895 1033
896 - // Get gravatar / roles for final result set
1034 + // Get gravatar / roles for final result set.
897 1035 $results = $this->get_users_record_meta( $users );
898 1036
899 1037 break;
900 1038 }
@@ -899,68 +1037,32 @@
899 1037 break;
900 1038 }
901 1039
902 1040 if ( isset( $results ) ) {
903 - echo wp_stream_json_encode( array_values( $results ) ); // xss ok
1041 + echo wp_json_encode( $results );
904 1042 }
905 1043
906 - if ( defined( 'WP_STREAM_TESTS' ) && WP_STREAM_TESTS ) {
907 - return;
908 - }
909 -
910 1044 die();
911 1045 }
912 1046
913 1047 /**
914 - * @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
915 1052 */
916 - public function get_filter_value_by_id() {
917 - $filter = wp_stream_filter_input( INPUT_POST, 'filter' );
918 -
919 - switch ( $filter ) {
920 - case 'user_id':
921 - $id = wp_stream_filter_input( INPUT_POST, 'id' );
922 -
923 - if ( '0' === $id ) {
924 - $value = 'WP-CLI';
925 -
926 - break;
927 - }
928 -
929 - $user = get_userdata( $id );
930 -
931 - if ( ! $user || is_wp_error( $user ) ) {
932 - $value = '';
933 - } else {
934 - $value = $user->display_name;
935 - }
936 -
937 - break;
938 - default:
939 - $value = '';
940 - }
941 -
942 - echo wp_stream_json_encode( $value ); // xss ok
943 -
944 - if ( defined( 'WP_STREAM_TESTS' ) && WP_STREAM_TESTS ) {
945 - return;
946 - }
947 -
948 - die();
949 - }
950 -
951 1053 public function get_users_record_meta( $authors ) {
952 1054 $authors_records = array();
953 1055
954 1056 foreach ( $authors as $user_id => $args ) {
955 - $author = new Author( $user_id );
1057 + $author = new Author( $args->ID );
956 1058
957 1059 $authors_records[ $user_id ] = array(
958 - 'text' => $author->get_display_name(),
959 - 'id' => $user_id,
960 - 'label' => $author->get_display_name(),
961 - 'icon' => $author->get_avatar_src( 32 ),
962 - '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' => '',
963 1065 );
964 1066 }
965 1067
966 1068 return $authors_records;
@@ -968,18 +1070,15 @@
968 1070
969 1071 /**
970 1072 * Get user meta in a way that is also safe for VIP
971 1073 *
972 - * @param int $user_id
973 - * @param string $meta_key
974 - * @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).
975 1077 *
976 1078 * @return mixed
977 1079 */
978 - function get_user_meta( $user_id, $meta_key, $single = true ) {
979 - if ( wp_stream_is_vip() && function_exists( 'get_user_attribute' ) ) {
980 - return get_user_attribute( $user_id, $meta_key );
981 - }
1080 + public function get_user_meta( $user_id, $meta_key, $single = true ) {
982 1081 return get_user_meta( $user_id, $meta_key, $single );
983 1082 }
984 1083
985 1084 /**
@@ -984,19 +1083,16 @@
984 1083
985 1084 /**
986 1085 * Update user meta in a way that is also safe for VIP
987 1086 *
988 - * @param int $user_id
989 - * @param string $meta_key
990 - * @param mixed $meta_value
991 - * @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).
992 1091 *
993 1092 * @return int|bool
994 1093 */
995 - function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
996 - if ( wp_stream_is_vip() && function_exists( 'update_user_attribute' ) ) {
997 - return update_user_attribute( $user_id, $meta_key, $meta_value );
998 - }
1094 + public function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
999 1095 return update_user_meta( $user_id, $meta_key, $meta_value, $prev_value );
1000 1096 }
1001 1097
1002 1098 /**
@@ -1001,18 +1097,14 @@
1001 1097
1002 1098 /**
1003 1099 * Delete user meta in a way that is also safe for VIP
1004 1100 *
1005 - * @param int $user_id
1006 - * @param string $meta_key
1007 - * @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).
1008 1104 *
1009 1105 * @return bool
1010 1106 */
1011 - function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) {
1012 - if ( wp_stream_is_vip() && function_exists( 'delete_user_attribute' ) ) {
1013 - return delete_user_attribute( $user_id, $meta_key, $meta_value );
1014 - }
1107 + public function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) {
1015 1108 return delete_user_meta( $user_id, $meta_key, $meta_value );
1016 1109 }
1017 -
1018 1110 }