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 +338 -248 3.0.14.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,16 +594,17 @@
501 594 *
502 595 * @action admin_enqueue_scripts
503 596 */
504 597 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() );
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() );
506 600 wp_register_style( 'wp-stream-icons', $this->plugin->locations['url'] . 'ui/stream-icons/style.css', array(), $this->plugin->get_version() );
507 601
508 - // Make sure we're working off a clean version
602 + // Make sure we're working off a clean version.
509 603 if ( ! file_exists( ABSPATH . WPINC . '/version.php' ) ) {
510 604 return;
511 605 }
512 - include( ABSPATH . WPINC . '/version.php' );
606 + include ABSPATH . WPINC . '/version.php';
513 607
514 608 if ( ! isset( $wp_version ) ) {
515 609 return;
516 610 }
@@ -537,9 +631,9 @@
537 631 #adminmenu #menu-posts-feedback div.wp-menu-image {
538 632 background: none !important;
539 633 background-repeat: no-repeat;
540 634 }
541 - body.{$body_class} #wpbody-content .wrap h2:nth-child(1):before {
635 + body.{$body_class} #wpbody-content .wrap h1:nth-child(1):before {
542 636 font-family: 'WP Stream' !important;
543 637 content: '\\73';
544 638 padding: 0 8px 0 0;
545 639 }
@@ -569,10 +663,15 @@
569 663
570 664 \wp_add_inline_style( 'wp-admin', $css );
571 665 }
572 666
667 + /**
668 + * Handle the reset AJAX request to reset logs.
669 + *
670 + * @return bool
671 + */
573 672 public function wp_ajax_reset() {
574 - check_ajax_referer( 'stream_nonce', 'wp_stream_nonce' );
673 + check_ajax_referer( 'stream_nonce_reset', 'wp_stream_nonce_reset' );
575 674
576 675 if ( ! current_user_can( $this->settings_cap ) ) {
577 676 wp_die(
578 677 esc_html__( "You don't have sufficient privileges to do this action.", 'stream' )
@@ -584,9 +683,9 @@
584 683 if ( defined( 'WP_STREAM_TESTS' ) && WP_STREAM_TESTS ) {
585 684 return true;
586 685 }
587 686
588 - wp_redirect(
687 + wp_safe_redirect(
589 688 add_query_arg(
590 689 array(
591 690 'page' => is_network_admin() ? $this->network->network_settings_page_slug : $this->settings_page_slug,
592 691 'message' => 'data_erased',
@@ -597,14 +696,19 @@
597 696
598 697 exit;
599 698 }
600 699
700 + /**
701 + * Clears stream records from the database.
702 + *
703 + * @return void
704 + */
601 705 private function erase_stream_records() {
602 706 global $wpdb;
603 707
604 708 $where = '';
605 709
606 - if ( is_multisite() && ! is_plugin_active_for_network( $this->plugin->locations['plugin'] ) ) {
710 + if ( is_multisite() && ! $this->plugin->is_network_activated() ) {
607 711 $where .= $wpdb->prepare( ' AND `blog_id` = %d', get_current_blog_id() );
608 712 }
609 713
610 714 $wpdb->query(
@@ -611,12 +715,17 @@
611 715 "DELETE `stream`, `meta`
612 716 FROM {$wpdb->stream} AS `stream`
613 717 LEFT JOIN {$wpdb->streammeta} AS `meta`
614 718 ON `meta`.`record_id` = `stream`.`ID`
615 - WHERE 1=1 {$where};"
719 + WHERE 1=1 {$where};" // @codingStandardsIgnoreLine $where already prepared
616 720 );
617 721 }
618 722
723 + /**
724 + * Schedules a purge of records.
725 + *
726 + * @return void
727 + */
619 728 public function purge_schedule_setup() {
620 729 if ( ! wp_next_scheduled( 'wp_stream_auto_purge' ) ) {
621 730 wp_schedule_event( time(), 'twicedaily', 'wp_stream_auto_purge' );
622 731 }
@@ -621,41 +730,48 @@
621 730 wp_schedule_event( time(), 'twicedaily', 'wp_stream_auto_purge' );
622 731 }
623 732 }
624 733
734 + /**
735 + * Executes a scheduled purge
736 + *
737 + * @return void
738 + */
625 739 public function purge_scheduled_action() {
626 740 global $wpdb;
627 741
628 - // 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.
629 743 if (
630 744 is_multisite()
631 745 &&
632 746 is_network_admin()
633 747 &&
634 - ! is_plugin_active_for_network( $this->plugin->locations['plugin'] )
748 + ! $this->plugin->is_network_activated()
635 749 ) {
636 750 return;
637 751 }
638 752
639 - if ( is_multisite() && is_plugin_active_for_network( $this->plugin->locations['plugin'] ) ) {
640 - $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 );
641 756 } else {
642 - $options = (array) get_option( 'wp_stream', array() );
757 + $options = (array) get_option( 'wp_stream', $defaults );
643 758 }
644 759
645 - 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'] ) ) {
646 761 return;
647 762 }
648 763
649 - $days = $options['general_records_ttl'];
650 - $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 );
651 767
652 768 $date->sub( DateInterval::createFromDateString( "$days days" ) );
653 769
654 770 $where = $wpdb->prepare( ' AND `stream`.`created` < %s', $date->format( 'Y-m-d H:i:s' ) );
655 771
656 - // Multisite but NOT network activated, only purge the current blog
657 - 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() ) {
658 774 $where .= $wpdb->prepare( ' AND `blog_id` = %d', get_current_blog_id() );
659 775 }
660 776
661 777 $wpdb->query(
@@ -662,18 +778,20 @@
662 778 "DELETE `stream`, `meta`
663 779 FROM {$wpdb->stream} AS `stream`
664 780 LEFT JOIN {$wpdb->streammeta} AS `meta`
665 781 ON `meta`.`record_id` = `stream`.`ID`
666 - WHERE 1=1 {$where};"
782 + WHERE 1=1 {$where};" // @codingStandardsIgnoreLine $where already prepared
667 783 );
668 784 }
669 785
670 786 /**
671 - * @param array $links
672 - * @param string $file
787 + * Returns the admin action links.
673 788 *
674 789 * @filter plugin_action_links
675 790 *
791 + * @param array $links Action links.
792 + * @param string $file Plugin file.
793 + *
676 794 * @return array
677 795 */
678 796 public function plugin_action_links( $links, $file ) {
679 797 if ( plugin_basename( $this->plugin->locations['dir'] . 'stream.php' ) !== $file ) {
@@ -679,31 +797,31 @@
679 797 if ( plugin_basename( $this->plugin->locations['dir'] . 'stream.php' ) !== $file ) {
680 798 return $links;
681 799 }
682 800
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'] ) ) {
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() ) {
685 803 return $links;
686 804 }
687 805
688 806 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 ) );
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 + );
690 813 } else {
691 - $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 + );
692 820 }
693 821
694 822 $links[] = sprintf( '<a href="%s">%s</a>', esc_url( $admin_page_url ), esc_html__( 'Settings', 'default' ) );
695 823
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 - );
703 -
704 - $links[] = sprintf( '<span id="wp_stream_uninstall" class="delete"><a href="%s">%s</a></span>', esc_url( $url ), esc_html__( 'Uninstall', 'stream' ) );
705 -
706 824 return $links;
707 825 }
708 826
709 827 /**
@@ -712,12 +830,12 @@
712 830 public function render_list_table() {
713 831 $this->list_table->prepare_items();
714 832 ?>
715 833 <div class="wrap">
716 - <h2><?php echo esc_html( get_admin_page_title() ) ?></h2>
717 - <?php $this->list_table->display() ?>
834 + <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
835 + <?php $this->list_table->display(); ?>
718 836 </div>
719 - <?php
837 + <?php
720 838 }
721 839
722 840 /**
723 841 * Render settings page
@@ -729,28 +847,28 @@
729 847 $page_description = apply_filters( 'wp_stream_settings_form_description', '' );
730 848
731 849 $sections = $this->plugin->settings->get_fields();
732 850 $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 );
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 );
735 853 ?>
736 854 <div class="wrap">
737 - <h2><?php echo esc_html( get_admin_page_title() ) ?></h2>
855 + <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
738 856
739 857 <?php if ( ! empty( $page_description ) ) : ?>
740 - <p><?php echo esc_html( $page_description ) ?></p>
858 + <p><?php echo esc_html( $page_description ); ?></p>
741 859 <?php endif; ?>
742 860
743 - <?php settings_errors() ?>
861 + <?php settings_errors(); ?>
744 862
745 863 <?php if ( count( $sections ) > 1 ) : ?>
746 864 <h2 class="nav-tab-wrapper">
747 - <?php $i = 0 ?>
865 + <?php $i = 0; ?>
748 866 <?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'] ) ?>
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'] ); ?>
753 871 </a>
754 872 <?php endforeach; ?>
755 873 </h2>
756 874 <?php endif; ?>
@@ -755,29 +873,29 @@
755 873 </h2>
756 874 <?php endif; ?>
757 875
758 876 <div class="nav-tab-content" id="tab-content-settings">
759 - <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">
760 878 <div class="settings-sections">
761 - <?php
762 - $i = 0;
763 - foreach ( $sections as $section => $data ) {
764 - $i++;
879 + <?php
880 + $i = 0;
881 + foreach ( $sections as $section => $data ) {
882 + ++$i;
765 883
766 - $is_active = ( ( 1 === $i && ! $active_tab ) || $active_tab === $section );
884 + $is_active = ( ( 1 === $i && ! $active_tab ) || $active_tab === $section );
767 885
768 - if ( $is_active ) {
769 - settings_fields( $option_key );
770 - do_settings_sections( $option_key );
771 - }
772 - }
773 - ?>
886 + if ( $is_active ) {
887 + settings_fields( $option_key );
888 + do_settings_sections( $option_key );
889 + }
890 + }
891 + ?>
774 892 </div>
775 - <?php submit_button() ?>
893 + <?php submit_button(); ?>
776 894 </form>
777 895 </div>
778 896 </div>
779 - <?php
897 + <?php
780 898 }
781 899
782 900 /**
783 901 * Instantiate the list table
@@ -782,20 +900,25 @@
782 900 /**
783 901 * Instantiate the list table
784 902 */
785 903 public function register_list_table() {
786 - $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 + );
787 910 }
788 911
789 912 /**
790 913 * Check if a particular role has access
791 914 *
792 - * @param string $role
915 + * @param string $role User role.
793 916 *
794 917 * @return bool
795 918 */
796 919 private function role_can_view( $role ) {
797 - if ( in_array( $role, $this->plugin->settings->options['general_role_access'] ) ) {
920 + if ( in_array( $role, $this->plugin->settings->options['general_role_access'], true ) ) {
798 921 return true;
799 922 }
800 923
801 924 return false;
@@ -803,12 +926,12 @@
803 926
804 927 /**
805 928 * Filter user caps to dynamically grant our view cap based on allowed roles
806 929 *
807 - * @param $allcaps
808 - * @param $caps
809 - * @param $args
810 - * @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.
811 934 *
812 935 * @filter user_has_cap
813 936 *
814 937 * @return array
@@ -834,9 +957,9 @@
834 957
835 958 $stream_view_caps = array( $this->view_cap );
836 959
837 960 foreach ( $caps as $cap ) {
838 - if ( in_array( $cap, $stream_view_caps ) ) {
961 + if ( in_array( $cap, $stream_view_caps, true ) ) {
839 962 foreach ( $roles as $role ) {
840 963 if ( $this->role_can_view( $role ) ) {
841 964 $allcaps[ $cap ] = true;
842 965
@@ -853,11 +976,11 @@
853 976 * Filter role caps to dynamically grant our view cap based on allowed roles
854 977 *
855 978 * @filter role_has_cap
856 979 *
857 - * @param $allcaps
858 - * @param $cap
859 - * @param $role
980 + * @param array $allcaps All capabilities.
981 + * @param string $cap Require cap.
982 + * @param string $role User role.
860 983 *
861 984 * @return array
862 985 */
863 986 public function filter_role_caps( $allcaps, $cap, $role ) {
@@ -862,9 +985,9 @@
862 985 */
863 986 public function filter_role_caps( $allcaps, $cap, $role ) {
864 987 $stream_view_caps = array( $this->view_cap );
865 988
866 - 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 ) ) {
867 990 $allcaps[ $cap ] = true;
868 991 }
869 992
870 993 return $allcaps;
@@ -870,15 +993,27 @@
870 993 return $allcaps;
871 994 }
872 995
873 996 /**
997 + * Ajax callback for return a user list.
998 + *
874 999 * @action wp_ajax_wp_stream_filters
875 1000 */
876 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 +
877 1008 switch ( wp_stream_filter_input( INPUT_GET, 'filter' ) ) {
878 1009 case 'user_id':
879 1010 $users = array_merge(
880 - array( 0 => (object) array( 'display_name' => 'WP-CLI' ) ),
1011 + array(
1012 + 0 => (object) array(
1013 + 'display_name' => 'WP-CLI',
1014 + ),
1015 + ),
881 1016 get_users()
882 1017 );
883 1018
884 1019 $search = wp_stream_filter_input( INPUT_GET, 'q' );
@@ -885,9 +1020,9 @@
885 1020 if ( $search ) {
886 1021 // `search` arg for get_users() is not enough
887 1022 $users = array_filter(
888 1023 $users,
889 - function( $user ) use ( $search ) {
1024 + function ( $user ) use ( $search ) {
890 1025 return false !== mb_strpos( mb_strtolower( $user->display_name ), mb_strtolower( $search ) );
891 1026 }
892 1027 );
893 1028 }
@@ -895,9 +1030,9 @@
895 1030 if ( count( $users ) > $this->preload_users_max ) {
896 1031 $users = array_slice( $users, 0, $this->preload_users_max );
897 1032 }
898 1033
899 - // Get gravatar / roles for final result set
1034 + // Get gravatar / roles for final result set.
900 1035 $results = $this->get_users_record_meta( $users );
901 1036
902 1037 break;
903 1038 }
@@ -902,68 +1037,32 @@
902 1037 break;
903 1038 }
904 1039
905 1040 if ( isset( $results ) ) {
906 - echo wp_stream_json_encode( array_values( $results ) ); // xss ok
1041 + echo wp_json_encode( $results );
907 1042 }
908 1043
909 - if ( defined( 'WP_STREAM_TESTS' ) && WP_STREAM_TESTS ) {
910 - return;
911 - }
912 -
913 1044 die();
914 1045 }
915 1046
916 1047 /**
917 - * @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
918 1052 */
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 1053 public function get_users_record_meta( $authors ) {
955 1054 $authors_records = array();
956 1055
957 1056 foreach ( $authors as $user_id => $args ) {
958 - $author = new Author( $user_id );
1057 + $author = new Author( $args->ID );
959 1058
960 1059 $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' => '',
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' => '',
966 1065 );
967 1066 }
968 1067
969 1068 return $authors_records;
@@ -971,18 +1070,15 @@
971 1070
972 1071 /**
973 1072 * Get user meta in a way that is also safe for VIP
974 1073 *
975 - * @param int $user_id
976 - * @param string $meta_key
977 - * @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).
978 1077 *
979 1078 * @return mixed
980 1079 */
981 - function get_user_meta( $user_id, $meta_key, $single = true ) {
982 - if ( wp_stream_is_vip() && function_exists( 'get_user_attribute' ) ) {
983 - return get_user_attribute( $user_id, $meta_key );
984 - }
1080 + public function get_user_meta( $user_id, $meta_key, $single = true ) {
985 1081 return get_user_meta( $user_id, $meta_key, $single );
986 1082 }
987 1083
988 1084 /**
@@ -987,19 +1083,16 @@
987 1083
988 1084 /**
989 1085 * Update user meta in a way that is also safe for VIP
990 1086 *
991 - * @param int $user_id
992 - * @param string $meta_key
993 - * @param mixed $meta_value
994 - * @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).
995 1091 *
996 1092 * @return int|bool
997 1093 */
998 - function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
999 - if ( wp_stream_is_vip() && function_exists( 'update_user_attribute' ) ) {
1000 - return update_user_attribute( $user_id, $meta_key, $meta_value );
1001 - }
1094 + public function update_user_meta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
1002 1095 return update_user_meta( $user_id, $meta_key, $meta_value, $prev_value );
1003 1096 }
1004 1097
1005 1098 /**
@@ -1004,17 +1097,14 @@
1004 1097
1005 1098 /**
1006 1099 * Delete user meta in a way that is also safe for VIP
1007 1100 *
1008 - * @param int $user_id
1009 - * @param string $meta_key
1010 - * @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).
1011 1104 *
1012 1105 * @return bool
1013 1106 */
1014 - function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) {
1015 - if ( wp_stream_is_vip() && function_exists( 'delete_user_attribute' ) ) {
1016 - return delete_user_attribute( $user_id, $meta_key, $meta_value );
1017 - }
1107 + public function delete_user_meta( $user_id, $meta_key, $meta_value = '' ) {
1018 1108 return delete_user_meta( $user_id, $meta_key, $meta_value );
1019 1109 }
1020 1110 }