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