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-list-table.php +353 -157 3.2.13.9.0 View file →
@@ -1,10 +1,20 @@
1 1 <?php
2 +/**
3 + * Generates a filterable list of provided records to be displayed HTML Table.
4 + *
5 + * @package WP_Stream
6 + */
7 +
2 8 namespace WP_Stream;
3 9
10 +/**
11 + * Class - List_Table
12 + */
4 13 class List_Table extends \WP_List_Table {
14 +
5 15 /**
6 - * Hold Plugin class
16 + * Holds Instance of plugin object
7 17 *
8 18 * @var Plugin
9 19 */
10 20 public $plugin;
@@ -11,12 +21,12 @@
11 21
12 22 /**
13 23 * Class constructor.
14 24 *
15 - * @param Plugin $plugin The main Plugin class.
16 - * @param array $args
25 + * @param Plugin $plugin Instance of plugin object.
26 + * @param array $args Argument to filter rows by.
17 27 */
18 - function __construct( $plugin, $args = array() ) {
28 + public function __construct( $plugin, $args = array() ) {
19 29 $this->plugin = $plugin;
20 30
21 31 $screen_id = isset( $args['screen'] ) ? $args['screen'] : null;
22 32
@@ -43,32 +53,64 @@
43 53 'option' => 'edit_stream_per_page',
44 54 )
45 55 );
46 56
47 - // Check for default hidden columns
57 + // Check for default hidden columns.
48 58 $this->get_hidden_columns();
49 59
50 - add_filter( 'screen_settings', array( $this, 'screen_controls' ), 10, 2 );
51 - add_filter( 'set-screen-option', array( $this, 'set_screen_option' ), 10, 3 );
60 + add_filter(
61 + 'screen_settings',
62 + array(
63 + $this,
64 + 'screen_controls',
65 + ),
66 + 10,
67 + 2
68 + );
69 + add_filter(
70 + 'set-screen-option',
71 + array(
72 + $this,
73 + 'set_screen_option',
74 + ),
75 + 10,
76 + 3
77 + );
52 78
53 79 set_screen_options();
54 80 }
55 81
56 - function extra_tablenav( $which ) {
82 + /**
83 + * Renders extra from navigation options.
84 + *
85 + * @param string $which Page location.
86 + * @return void
87 + */
88 + public function extra_tablenav( $which ) {
57 89 if ( 'top' === $which ) {
58 - echo $this->filters_form(); // xss ok
90 + echo $this->filters_form(); // xss ok.
59 91 }
60 92 }
61 93
62 - function no_items() {
94 + /**
95 + * Renders "No items found" message.
96 + *
97 + * @return void
98 + */
99 + public function no_items() {
63 100 ?>
64 101 <div class="stream-list-table-no-items">
65 - <p><?php esc_html_e( 'Sorry, no activity records were found.', 'stream' ) ?></p>
102 + <p><?php esc_html_e( 'No activity records were found.', 'stream' ); ?></p>
66 103 </div>
67 104 <?php
68 105 }
69 106
70 - function get_columns() {
107 + /**
108 + * Returns the table columns to be rendered.
109 + *
110 + * @return array
111 + */
112 + public function get_columns() {
71 113 /**
72 114 * Allows devs to add new columns to table
73 115 *
74 116 * @return array
@@ -85,23 +127,34 @@
85 127 )
86 128 );
87 129 }
88 130
89 - function get_sortable_columns() {
131 + /**
132 + * Returns the columns the items can be sort by.
133 + *
134 + * @return array
135 + */
136 + public function get_sortable_columns() {
90 137 return array(
91 138 'date' => array( 'date', false ),
92 139 );
93 140 }
94 141
95 - function get_hidden_columns() {
96 - if ( ! $user = wp_get_current_user() ) {
142 + /**
143 + * Returns columns hidden from all except specific users.
144 + *
145 + * @return array|bool
146 + */
147 + public function get_hidden_columns() {
148 + $user = wp_get_current_user();
149 + if ( ! $user ) {
97 150 return array();
98 151 }
99 152
100 - // Directly checking the user meta; to check whether user has changed screen option or not
153 + // Directly checking the user meta; to check whether user has changed screen option or not.
101 154 $hidden = $this->plugin->admin->get_user_meta( $user->ID, 'manage' . $this->screen->id . 'columnshidden', true );
102 155
103 - // If user meta is not found; add the default hidden column 'id'
156 + // If user meta is not found; add the default hidden column 'id'.
104 157 if ( ! $hidden ) {
105 158 $hidden = array( 'id' );
106 159 $this->plugin->admin->update_user_meta( $user->ID, 'manage' . $this->screen->id . 'columnshidden', $hidden );
107 160 }
@@ -108,15 +161,25 @@
108 161
109 162 return $hidden;
110 163 }
111 164
112 - function prepare_items() {
165 + /**
166 + * Prepares table columns and data for render
167 + *
168 + * @return void
169 + */
170 + public function prepare_items() {
113 171 $columns = $this->get_columns();
114 172 $sortable = $this->get_sortable_columns();
115 173 $hidden = $this->get_hidden_columns();
116 174 $primary = $columns['summary'];
117 175
118 - $this->_column_headers = array( $columns, $hidden, $sortable, $primary );
176 + $this->_column_headers = array(
177 + $columns,
178 + $hidden,
179 + $sortable,
180 + $primary,
181 + );
119 182
120 183 $this->items = $this->get_records();
121 184
122 185 $total_items = $this->get_total_found_rows();
@@ -128,17 +191,24 @@
128 191 )
129 192 );
130 193 }
131 194
132 - function get_records() {
195 + /**
196 + * Returns records to be displayed
197 + *
198 + * @return array
199 + */
200 + public function get_records() {
133 201 $args = array();
134 202
135 - // Parse sorting params
136 - if ( $order = wp_stream_filter_input( INPUT_GET, 'order' ) ) {
203 + // Parse sorting params.
204 + $order = wp_stream_filter_input( INPUT_GET, 'order' );
205 + if ( $order ) {
137 206 $args['order'] = $order;
138 207 }
139 208
140 - if ( $orderby = wp_stream_filter_input( INPUT_GET, 'orderby' ) ) {
209 + $orderby = wp_stream_filter_input( INPUT_GET, 'orderby' );
210 + if ( $orderby ) {
141 211 $args['orderby'] = $orderby;
142 212 }
143 213
144 214 $params = array(
@@ -157,9 +227,9 @@
157 227 $args[ $param ] = $value;
158 228 }
159 229 }
160 230
161 - // Additional filter properties
231 + // Additional filter properties.
162 232 $properties = array(
163 233 'record',
164 234 'site_id',
165 235 'blog_id',
@@ -171,13 +241,13 @@
171 241 'context',
172 242 'action',
173 243 );
174 244
175 - // Add property fields to defaults, including their __in/__not_in variations
245 + // Add property fields to defaults, including their __in/__not_in variations.
176 246 foreach ( $properties as $property ) {
177 247 $value = wp_stream_filter_input( INPUT_GET, $property );
178 248
179 - // Allow 0 values
249 + // Allow 0 values.
180 250 if ( isset( $value ) && '' !== $value && false !== $value ) {
181 251 $args[ $property ] = $value;
182 252 }
183 253
@@ -206,8 +276,9 @@
206 276 }
207 277 $args['records_per_page'] = apply_filters( 'stream_records_per_page', $args['records_per_page'] );
208 278
209 279 $items = $this->plugin->db->get_records( $args );
280 +
210 281 return $items;
211 282 }
212 283
213 284 /**
@@ -218,28 +289,36 @@
218 289 public function get_total_found_rows() {
219 290 return $this->plugin->db->get_found_records_count();
220 291 }
221 292
222 - function column_default( $item, $column_name ) {
223 - $out = '';
293 + /**
294 + * Returns the column content for the provided item and column.
295 + *
296 + * @param array $item Record data.
297 + * @param string $column_name Column name.
298 + * @return void
299 + */
300 + public function column_default( $item, $column_name ) {
301 + $out = '';
224 302 $record = new Record( $item );
225 303
226 304 switch ( $column_name ) {
227 - case 'date' :
228 - $created = date( 'Y-m-d H:i:s', strtotime( $record->created ) );
305 + case 'date':
306 + $created = gmdate( 'Y-m-d H:i:s', strtotime( $record->created ) );
229 307 $date_string = sprintf(
230 308 '<time datetime="%s" class="relative-time record-created">%s</time>',
231 309 wp_stream_get_iso_8601_extended_date( strtotime( $record->created ) ),
232 310 get_date_from_gmt( $created, 'Y/m/d' )
233 311 );
234 - $out = $this->column_link( $date_string, 'date', get_date_from_gmt( $created, 'Y/m/d' ) );
235 - $out .= '<br />';
236 - $out .= get_date_from_gmt( $created, 'h:i:s A' );
312 + $out = $this->column_link( $date_string, 'date', get_date_from_gmt( $created, 'Y/m/d' ) );
313 + $out .= '<br />';
314 + $out .= get_date_from_gmt( $created, 'h:i:s A' );
237 315 break;
238 316
239 - case 'summary' :
240 - $out = $record->summary;
241 - $object_title = $record->get_object_title();
317 + case 'summary':
318 + $out = $record->summary;
319 + $object_title = $record->get_object_title();
320 + /* translators: %s: the title of any object, like a Post (e.g. "Hello World") */
242 321 $view_all_text = $object_title ? sprintf( esc_html__( 'View all activity for "%s"', 'stream' ), esc_attr( $object_title ) ) : esc_html__( 'View all activity for this object', 'stream' );
243 322
244 323 if ( $record->object_id ) {
245 324 $out .= $this->column_link(
@@ -254,9 +333,9 @@
254 333 }
255 334 $out .= $this->get_action_links( $record );
256 335 break;
257 336
258 - case 'user_id' :
337 + case 'user_id':
259 338 $user = new Author( (int) $record->user_id, (array) $record->user_meta );
260 339
261 340 $filtered_records_url = add_query_arg(
262 341 array(
@@ -300,20 +379,22 @@
300 379 $blog = ( $record->blog_id && is_multisite() ) ? get_blog_details( $record->blog_id ) : $this->plugin->admin->network->get_network_blog();
301 380 $out = $this->column_link( $blog->blogname, 'blog_id', $blog->blog_id );
302 381 break;
303 382
304 - case 'ip' :
383 + case 'ip':
305 384 $out = $this->column_link( $record->{$column_name}, 'ip', $record->{$column_name} );
306 385 break;
307 386
308 - default :
387 + default:
309 388 /**
310 389 * Registers new Columns to be inserted into the table. The cell contents of this column is set
311 390 * below with 'wp_stream_insert_column_default_'
312 391 *
392 + * @param array $new_columns Columns injected in the table.
393 + *
313 394 * @return array
314 395 */
315 - $inserted_columns = apply_filters( 'wp_stream_register_column_defaults', $new_columns = array() );
396 + $inserted_columns = apply_filters( 'wp_stream_register_column_defaults', array() );
316 397
317 398 if ( ! empty( $inserted_columns ) && is_array( $inserted_columns ) ) {
318 399 foreach ( $inserted_columns as $column_title ) {
319 400 /**
@@ -323,33 +404,41 @@
323 404 *
324 405 * Also, note that the action name must include the $column_title registered
325 406 * with wp_stream_register_column_defaults
326 407 */
327 - if ( $column_title === $column_name && has_filter( "wp_stream_insert_column_default_{$column_title}" ) ) {
408 + if ( $column_title === $column_name ) {
328 409 /**
329 410 * Allows for the addition of content under a specified column.
330 411 *
331 - * @param object $record Contents of the row
412 + * @param string $out Column content.
413 + * @param object $record Record with row content.
414 + * @param string $column_name Column name.
332 415 *
333 416 * @return string
334 417 */
335 - $out = apply_filters( "wp_stream_insert_column_default_{$column_title}", $column_name, $record );
336 - } else {
337 - $out = $column_name;
418 + $out = apply_filters( "wp_stream_insert_column_default_{$column_title}", $out, $record, $column_name );
419 + break;
338 420 }
339 421 }
340 - } else {
341 - $out = $column_name;
342 422 }
343 423 }
344 424
345 - $allowed_tags = wp_kses_allowed_html( 'post' );
346 - $allowed_tags['time'] = array( 'datetime' => true, 'class' => true );
425 + $allowed_tags = wp_kses_allowed_html( 'post' );
426 + $allowed_tags['time'] = array(
427 + 'datetime' => true,
428 + 'class' => true,
429 + );
347 430 $allowed_tags['img']['srcset'] = true;
348 431
349 432 echo wp_kses( $out, $allowed_tags );
350 433 }
351 434
435 + /**
436 + * Returns the actions links for the provided record. (Eg. Edit, View)
437 + *
438 + * @param Record $record Record.
439 + * @return string
440 + */
352 441 public function get_action_links( $record ) {
353 442 $out = '';
354 443
355 444 /**
@@ -401,9 +490,18 @@
401 490
402 491 return $out;
403 492 }
404 493
405 - function column_link( $display, $key, $value = null, $title = null ) {
494 + /**
495 + * Returns a link to be display in the table.
496 + *
497 + * @param string $display Text to be displayed in link.
498 + * @param string|array $key Query string variable(s).
499 + * @param string $value Single query string value.
500 + * @param string $title Tooltip value.
501 + * @return string
502 + */
503 + public function column_link( $display, $key, $value = null, $title = null ) {
406 504 $url = add_query_arg(
407 505 array(
408 506 'page' => $this->plugin->admin->records_page_slug,
409 507 ),
@@ -409,9 +507,11 @@
409 507 ),
410 508 self_admin_url( $this->plugin->admin->admin_parent_page )
411 509 );
412 510
413 - $args = ! is_array( $key ) ? array( $key => $value ) : $key;
511 + $args = ! is_array( $key ) ? array(
512 + $key => $value,
513 + ) : $key;
414 514
415 515 foreach ( $args as $k => $v ) {
416 516 $url = add_query_arg( $k, $v, $url );
417 517 }
@@ -423,14 +523,21 @@
423 523 $display
424 524 );
425 525 }
426 526
527 + /**
528 + * Returns the label for a connector term.
529 + *
530 + * @param string $term Connector label type.
531 + * @param string $type Connector term.
532 + * @return string
533 + */
427 534 public function get_term_title( $term, $type ) {
428 - if ( ! isset( $this->plugin->connectors->term_labels[ "stream_$type" ][ $term ] ) ) {
535 + if ( ! isset( $this->plugin->connectors->term_labels[ 'stream_' . $type ][ $term ] ) ) {
429 536 return $term;
430 537 }
431 538
432 - return $this->plugin->connectors->term_labels[ "stream_$type" ][ $term ];
539 + return $this->plugin->connectors->term_labels[ 'stream_' . $type ][ $term ];
433 540 }
434 541
435 542 /**
436 543 * Assembles records for display in search filters
@@ -438,18 +545,18 @@
438 545 * Gathers list of all users/connectors, then compares it to
439 546 * results of existing records. All items that do not exist in records
440 547 * get assigned a disabled value of "true".
441 548 *
442 - * @param string $column List table column name
549 + * @param string $column List table column name.
443 550 *
444 551 * @return array Options to be displayed in search filters
445 552 */
446 - function assemble_records( $column ) {
553 + public function assemble_records( $column ) {
447 554 // @todo eliminate special condition for authors, especially using a WP_User object as the value; should use string or stringifiable object
448 555 if ( 'user_id' === $column ) {
449 556 $all_records = array();
450 557
451 - // If the number of users exceeds the max users constant value then return an empty array and use AJAX instead
558 + // If the number of users exceeds the max users constant value then return an empty array and use AJAX instead.
452 559 $user_count = count_users();
453 560 $total_users = $user_count['total_users'];
454 561
455 562 if ( $total_users > $this->plugin->admin->preload_users_max ) {
@@ -455,9 +562,12 @@
455 562 if ( $total_users > $this->plugin->admin->preload_users_max ) {
456 563 $selected_user = wp_stream_filter_input( INPUT_GET, 'user_id' );
457 564 if ( $selected_user ) {
458 565 $user = new Author( $selected_user );
459 - return array( $selected_user => $user->get_display_name() );
566 +
567 + return array(
568 + $selected_user => $user->get_display_name(),
569 + );
460 570 } else {
461 571 return array();
462 572 }
463 573 }
@@ -462,26 +572,36 @@
462 572 }
463 573 }
464 574
465 575 $users = array_map(
466 - function( $user_id ) {
576 + function ( $user_id ) {
467 577 return new Author( $user_id );
468 578 },
469 - get_users( array( 'fields' => 'ID' ) )
579 + get_users(
580 + array(
581 + 'fields' => 'ID',
582 + )
583 + )
470 584 );
471 585
472 586 if ( is_multisite() && is_super_admin() ) {
473 587 $super_admins = array_map(
474 - function( $login ) {
588 + function ( $login ) {
475 589 $user = get_user_by( 'login', $login );
590 +
476 591 return new Author( $user->ID );
477 592 },
478 593 get_super_admins()
479 594 );
480 - $users = array_unique( array_merge( $users, $super_admins ) );
595 + $users = array_unique( array_merge( $users, $super_admins ) );
481 596 }
482 597
483 - $users[] = new Author( 0, array( 'is_wp_cli' => true ) );
598 + $users[] = new Author(
599 + 0,
600 + array(
601 + 'is_wp_cli' => true,
602 + )
603 + );
484 604
485 605 foreach ( $users as $user ) {
486 606 $all_records[ $user->id ] = $user->get_display_name();
487 607 }
@@ -495,20 +615,26 @@
495 615 $disabled_records = array();
496 616
497 617 foreach ( $all_records as $record => $label ) {
498 618 if ( array_key_exists( $record, $existing_records ) ) {
499 - $active_records[ $record ] = array( 'label' => $label, 'disabled' => '' );
619 + $active_records[ $record ] = array(
620 + 'label' => $label,
621 + 'disabled' => '',
622 + );
500 623 } else {
501 - $disabled_records[ $record ] = array( 'label' => $label, 'disabled' => 'disabled="disabled"' );
624 + $disabled_records[ $record ] = array(
625 + 'label' => $label,
626 + 'disabled' => 'disabled="disabled"',
627 + );
502 628 }
503 629 }
504 630
505 - // Remove WP-CLI pseudo user if no records with user=0 exist
631 + // Remove WP-CLI pseudo user if no records with user=0 exist.
506 632 if ( isset( $disabled_records[0] ) ) {
507 633 unset( $disabled_records[0] );
508 634 }
509 635
510 - $sort = function( $a, $b ) use ( $column ) {
636 + $sort = function ( $a, $b ) use ( $column ) {
511 637 $label_a = (string) $a['label'];
512 638 $label_b = (string) $b['label'];
513 639
514 640 if ( $label_a === $label_b ) {
@@ -514,20 +640,25 @@
514 640 if ( $label_a === $label_b ) {
515 641 return 0;
516 642 }
517 643
518 - return ( strtolower( $label_a ) < strtolower( $label_b ) ) ? -1 : 1;
644 + return ( strtolower( $label_a ) < strtolower( $label_b ) ) ? - 1 : 1;
519 645 };
520 646
521 647 uasort( $active_records, $sort );
522 648 uasort( $disabled_records, $sort );
523 649
524 - // Not using array_merge() in order to preserve the array index for the users dropdown which uses the user_id as the key
650 + // Not using array_merge() in order to preserve the array index for the users dropdown which uses the user_id as the key.
525 651 $all_records = $active_records + $disabled_records;
526 652
527 653 return $all_records;
528 654 }
529 655
656 + /**
657 + * Returns list filters.
658 + *
659 + * @return array
660 + */
530 661 public function get_filters() {
531 662 $filters = array();
532 663
533 664 $date_interval = new Date_Interval();
@@ -566,9 +697,14 @@
566 697 */
567 698 return apply_filters( 'wp_stream_list_table_filters', $filters );
568 699 }
569 700
570 - function filters_form() {
701 + /**
702 + * Returns table filters form.
703 + *
704 + * @return string
705 + */
706 + public function filters_form() {
571 707 $filters = $this->get_filters();
572 708
573 709 $filters_string = sprintf( '<input type="hidden" name="page" value="%s" />', 'wp_stream' );
574 710 $filters_string .= sprintf( '<span class="filter_info hidden">%s</span>', esc_html__( 'Show filter controls via the screen options tab above.', 'stream' ) );
@@ -574,19 +710,22 @@
574 710 $filters_string .= sprintf( '<span class="filter_info hidden">%s</span>', esc_html__( 'Show filter controls via the screen options tab above.', 'stream' ) );
575 711
576 712 foreach ( $filters as $name => $data ) {
577 713
578 - $data = wp_parse_args( $data, array(
579 - 'title' => '',
580 - 'items' => array(),
581 - 'ajax' => false,
582 - ) );
714 + $data = wp_parse_args(
715 + $data,
716 + array(
717 + 'title' => '',
718 + 'items' => array(),
719 + 'ajax' => false,
720 + )
721 + );
583 722
584 723 if ( 'date' === $name ) {
585 724 $filters_string .= $this->filter_date( $data['items'] );
586 725 } else {
587 726 if ( 'context' === $name ) {
588 - // Add Connectors as parents, and apply the Contexts as children
727 + // Add Connectors as parents, and apply the Contexts as children.
589 728 $connectors = $this->assemble_records( 'connector' );
590 729 $context_items = array();
591 730
592 731 foreach ( $connectors as $connector => $item ) {
@@ -600,9 +739,9 @@
600 739
601 740 if ( isset( $context_items[ $connector ]['children'] ) ) {
602 741 $labels = wp_list_pluck( $context_items[ $connector ]['children'], 'label' );
603 742
604 - // Sort child items by label
743 + // Sort child items by label.
605 744 array_multisort( $labels, SORT_ASC, $context_items[ $connector ]['children'] );
606 745 }
607 746 }
608 747
@@ -615,12 +754,12 @@
615 754 $data['items'] = $context_items;
616 755
617 756 $labels = wp_list_pluck( $data['items'], 'label' );
618 757
619 - // Sort top-level items by label
758 + // Sort top-level items by label.
620 759 array_multisort( $labels, SORT_ASC, $data['items'] );
621 760
622 - // Output a hidden input to handle the connector value
761 + // Output a hidden input to handle the connector value.
623 762 $filters_string .= sprintf(
624 763 '<input type="hidden" name="connector" class="record-filter-connector" value="%s" />',
625 764 esc_attr( wp_stream_filter_input( INPUT_GET, 'connector' ) )
626 765 );
@@ -631,9 +770,9 @@
631 770 }
632 771
633 772 $filters_string .= sprintf( '<input type="submit" id="record-query-submit" class="button" value="%s" />', __( 'Filter', 'stream' ) );
634 773
635 - // Parse all query vars into an array
774 + // Parse all query vars into an array.
636 775 $query_vars = array();
637 776
638 777 if ( isset( $_SERVER['QUERY_STRING'] ) ) {
639 778 parse_str( urldecode( $_SERVER['QUERY_STRING'] ), $query_vars );
@@ -638,9 +777,9 @@
638 777 if ( isset( $_SERVER['QUERY_STRING'] ) ) {
639 778 parse_str( urldecode( $_SERVER['QUERY_STRING'] ), $query_vars );
640 779 }
641 780
642 - // Ignore certain query vars and query vars that are empty
781 + // Ignore certain query vars and query vars that are empty.
643 782 foreach ( $query_vars as $query_var => $value ) {
644 783 if ( '' === $value || 'page' === $query_var || 'paged' === $query_var ) {
645 784 unset( $query_vars[ $query_var ] );
646 785 }
@@ -652,70 +791,77 @@
652 791 ),
653 792 self_admin_url( $this->plugin->admin->admin_parent_page )
654 793 );
655 794
656 - // Display reset action if records are being filtered
795 + // Display reset action if records are being filtered.
657 796 if ( ! empty( $query_vars ) ) {
658 797 $filters_string .= sprintf( '<a href="%s" id="record-query-reset"><span class="dashicons dashicons-dismiss"></span> <span class="record-query-reset-text">%s</span></a>', esc_url( $url ), __( 'Reset filters', 'stream' ) );
659 798 }
660 799
661 - return sprintf( '<div class="alignleft actions">%s</div>', $filters_string ); // xss ok
800 + return sprintf( '<div class="alignleft actions">%s</div>', $filters_string ); // xss ok.
662 801 }
663 802
664 - function filter_select( $name, $title, $items, $ajax = false ) {
665 - if ( $ajax ) {
666 - $out = sprintf(
667 - '<input type="hidden" name="%s" class="chosen-select" value="%s" data-placeholder="%s" />',
668 - esc_attr( $name ),
669 - esc_attr( wp_stream_filter_input( INPUT_GET, $name ) ),
670 - esc_attr( $title )
803 + /**
804 + * Returns HTML string of filterable select control with filtered items.
805 + *
806 + * @param string $name Search input.
807 + * @param string $title Name of the control.
808 + * @param array $items Items to be filtered.
809 + * @param boolean $ajax Whether is an ajax request or not.
810 + * @return string
811 + */
812 + public function filter_select( $name, $title, $items, $ajax = false ) {
813 + $options = array( '<option value=""></option>' );
814 + $selected = wp_stream_filter_input( INPUT_GET, $name );
815 +
816 + foreach ( $items as $key => $item ) {
817 + $value = isset( $item['children'] ) ? 'group-' . $key : $key;
818 + $option_args = array(
819 + 'value' => $value,
820 + 'selected' => selected( $value, $selected, false ),
821 + 'disabled' => isset( $item['disabled'] ) ? $item['disabled'] : null,
822 + 'icon' => isset( $item['icon'] ) ? $item['icon'] : null,
823 + 'group' => isset( $item['children'] ) ? $key : null,
824 + 'tooltip' => isset( $item['tooltip'] ) ? $item['tooltip'] : null,
825 + 'class' => isset( $item['children'] ) ? 'level-1' : null,
826 + 'label' => isset( $item['label'] ) ? $item['label'] : null,
671 827 );
672 - } else {
673 - $options = array( '<option value=""></option>' );
674 - $selected = wp_stream_filter_input( INPUT_GET, $name );
828 + $options[] = $this->filter_option( $option_args );
675 829
676 - foreach ( $items as $key => $item ) {
677 - $value = isset( $item['children'] ) ? 'group-' . $key : $key;
678 - $option_args = array(
679 - 'value' => $value,
680 - 'selected' => selected( $value, $selected, false ),
681 - 'disabled' => isset( $item['disabled'] ) ? $item['disabled'] : null,
682 - 'icon' => isset( $item['icon'] ) ? $item['icon'] : null,
683 - 'group' => isset( $item['children'] ) ? $key : null,
684 - 'tooltip' => isset( $item['tooltip'] ) ? $item['tooltip'] : null,
685 - 'class' => isset( $item['children'] ) ? 'level-1' : null,
686 - 'label' => isset( $item['label'] ) ? $item['label'] : null,
687 - );
688 - $options[] = $this->filter_option( $option_args );
689 -
690 - if ( isset( $item['children'] ) ) {
691 - foreach ( $item['children'] as $child_value => $child_item ) {
692 - $option_args = array(
693 - 'value' => $child_value,
694 - 'selected' => selected( $child_value, $selected, false ),
695 - 'disabled' => isset( $child_item['disabled'] ) ? $child_item['disabled'] : null,
696 - 'icon' => isset( $child_item['icon'] ) ? $child_item['icon'] : null,
697 - 'group' => $key,
698 - 'tooltip' => isset( $child_item['tooltip'] ) ? $child_item['tooltip'] : null,
699 - 'class' => 'level-2',
700 - 'label' => isset( $child_item['label'] ) ? '- ' . $child_item['label'] : null,
701 - );
702 - $options[] = $this->filter_option( $option_args );
703 - }
830 + if ( isset( $item['children'] ) ) {
831 + foreach ( $item['children'] as $child_value => $child_item ) {
832 + $option_args = array(
833 + 'value' => $child_value,
834 + 'selected' => selected( $child_value, $selected, false ),
835 + 'disabled' => isset( $child_item['disabled'] ) ? $child_item['disabled'] : null,
836 + 'icon' => isset( $child_item['icon'] ) ? $child_item['icon'] : null,
837 + 'group' => $key,
838 + 'tooltip' => isset( $child_item['tooltip'] ) ? $child_item['tooltip'] : null,
839 + 'class' => 'level-2',
840 + 'label' => isset( $child_item['label'] ) ? '- ' . $child_item['label'] : null,
841 + );
842 + $options[] = $this->filter_option( $option_args );
704 843 }
705 844 }
706 - $out = sprintf(
707 - '<select name="%s" class="chosen-select" data-placeholder="%s">%s</select>',
708 - esc_attr( $name ),
709 - sprintf( esc_attr__( 'Show all %s', 'stream' ), $title ),
710 - implode( '', $options )
711 - );
712 845 }
846 + $out = sprintf(
847 + '<select name="%s" class="chosen-select" data-placeholder="%s">%s</select>',
848 + esc_attr( $name ),
849 + /* translators: %s: the title of the dropdown menu (e.g. "users") */
850 + sprintf( esc_attr__( 'Show all %s', 'stream' ), $title ),
851 + implode( '', $options )
852 + );
713 853
714 854 return $out;
715 855 }
716 856
717 - function filter_option( $args ) {
857 + /**
858 + * Return HTML string of a filterable select option.
859 + *
860 + * @param array $args Option attributes.
861 + * @return string
862 + */
863 + public function filter_option( $args ) {
718 864 $defaults = array(
719 865 'value' => null,
720 866 'selected' => null,
721 867 'disabled' => null,
@@ -739,13 +885,17 @@
739 885 esc_html( $args['label'] )
740 886 );
741 887 }
742 888
743 - function filter_search() {
889 + /**
890 + * Return HTML string of a filter search box.
891 + *
892 + * @return string
893 + */
894 + public function filter_search() {
744 895 $search = null;
745 - if ( isset( $_GET['search'] ) ) {
746 - // @TODO: Make this pass phpcs
747 - $search = esc_attr( wp_unslash( $_GET['search'] ) ); // input var okay
896 + if ( isset( $_GET['search'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
897 + $search = sanitize_key( wp_unslash( $_GET['search'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
748 898 }
749 899 $out = sprintf(
750 900 '<p class="search-box">
751 901 <label class="screen-reader-text" for="record-search-input">%1$s:</label>
@@ -758,9 +908,15 @@
758 908
759 909 return $out;
760 910 }
761 911
762 - function filter_date( $items ) {
912 + /**
913 + * Return HTML string of a filter select box based upon date.
914 + *
915 + * @param array $items Records.
916 + * @return string
917 + */
918 + public function filter_date( $items ) {
763 919 wp_enqueue_style( 'jquery-ui' );
764 920 wp_enqueue_style( 'wp-stream-datepicker' );
765 921 wp_enqueue_script( 'jquery-ui-datepicker' );
766 922
@@ -771,11 +927,11 @@
771 927 ob_start();
772 928 ?>
773 929 <div class="date-interval">
774 930
775 - <select class="field-predefined hide-if-no-js chosen-select" name="date_predefined" data-placeholder="<?php esc_attr_e( 'All Time', 'stream' ) ?>">
931 + <select class="field-predefined hide-if-no-js chosen-select" name="date_predefined" data-placeholder="<?php esc_attr_e( 'All Time', 'stream' ); ?>">
776 932 <option></option>
777 - <option value="custom" <?php selected( 'custom' === $date_predefined ); ?>><?php esc_attr_e( 'Custom', 'stream' ) ?></option>
933 + <option value="custom" <?php selected( 'custom' === $date_predefined ); ?>><?php esc_attr_e( 'Custom', 'stream' ); ?></option>
778 934 <?php
779 935 foreach ( $items as $key => $interval ) {
780 936 $end = isset( $interval['end'] ) ? $interval['end']->format( 'Y/m/d' ) : null;
781 937
@@ -793,15 +949,15 @@
793 949
794 950 <div class="date-inputs">
795 951 <div class="box">
796 952 <i class="date-remove dashicons"></i>
797 - <input type="text" name="date_from" class="date-picker field-from" placeholder="<?php esc_attr_e( 'Start Date', 'stream' ) ?>" value="<?php echo esc_attr( $date_from ) ?>" />
953 + <input type="text" name="date_from" class="date-picker field-from" placeholder="<?php esc_attr_e( 'Start Date', 'stream' ); ?>" value="<?php echo esc_attr( $date_from ); ?>"/>
798 954 </div>
799 955 <span class="connector dashicons"></span>
800 956
801 957 <div class="box">
802 958 <i class="date-remove dashicons"></i>
803 - <input type="text" name="date_to" class="date-picker field-to" placeholder="<?php esc_attr_e( 'End Date', 'stream' ) ?>" value="<?php echo esc_attr( $date_to ) ?>" />
959 + <input type="text" name="date_to" class="date-picker field-to" placeholder="<?php esc_attr_e( 'End Date', 'stream' ); ?>" value="<?php echo esc_attr( $date_to ); ?>"/>
804 960 </div>
805 961 </div>
806 962
807 963 </div>
@@ -814,9 +970,9 @@
814 970 * Output a Select dropdown of actions relating to the Stream records
815 971 *
816 972 * @return string
817 973 */
818 - function record_actions_form() {
974 + public function record_actions_form() {
819 975 /**
820 976 * Filter the records screen actions dropdown menu
821 977 *
822 978 * @return array Should be in the format of action_slug => 'Action Name'
@@ -838,8 +994,9 @@
838 994 );
839 995 }
840 996 echo '</select></div>';
841 997 wp_nonce_field( 'stream_record_actions_nonce', 'stream_record_actions_nonce' );
998 + wp_nonce_field( 'stream_filters_user_search_nonce', 'stream_filters_user_search_nonce' );
842 999
843 1000 printf( '<input type="hidden" name="page" value="%s">', esc_attr( wp_stream_filter_input( INPUT_GET, 'page' ) ) );
844 1001 printf( '<input type="hidden" name="date_predefined" value="%s">', esc_attr( wp_stream_filter_input( INPUT_GET, 'date_predefined' ) ) );
845 1002 printf( '<input type="hidden" name="date_from" value="%s">', esc_attr( wp_stream_filter_input( INPUT_GET, 'date_from' ) ) );
@@ -854,22 +1011,30 @@
854 1011
855 1012 return ob_get_clean();
856 1013 }
857 1014
858 - function display() {
1015 + /**
1016 + * Renders record filter forms.
1017 + */
1018 + public function display() {
859 1019 $url = self_admin_url( $this->plugin->admin->admin_parent_page );
860 1020
861 1021 echo '<form method="get" action="' . esc_url( $url ) . '" id="record-filter-form">';
862 - echo $this->filter_search(); // xss ok
1022 + echo $this->filter_search(); // xss ok.
863 1023 parent::display();
864 1024 echo '</form>';
865 1025
866 1026 echo '<form method="get" action="' . esc_url( $url ) . '" id="record-actions-form">';
867 - echo $this->record_actions_form(); // xss ok
1027 + echo $this->record_actions_form(); // xss ok.
868 1028 echo '</form>';
869 1029 }
870 1030
871 - function single_row( $item ) {
1031 + /**
1032 + * Renders a single record
1033 + *
1034 + * @param array $item Record data.
1035 + */
1036 + public function single_row( $item ) {
872 1037 $classes = apply_filters( 'wp_stream_record_classes', array(), $item );
873 1038 $class_string = '';
874 1039 if ( ! empty( $classes ) ) {
875 1040 $class_string = ' class="' . esc_attr( join( ' ', $classes ) ) . '"';
@@ -874,15 +1039,21 @@
874 1039 if ( ! empty( $classes ) ) {
875 1040 $class_string = ' class="' . esc_attr( join( ' ', $classes ) ) . '"';
876 1041 }
877 1042
878 - echo sprintf( '<tr%s>', $class_string ); // xss ok
1043 + echo sprintf( '<tr%s>', $class_string ); // xss ok.
879 1044 $this->single_row_columns( $item );
880 1045 echo '</tr>';
881 1046 }
882 1047
883 - function display_tablenav( $which ) {
884 - if ( 'top' === $which ) : ?>
1048 + /**
1049 + * Renders table navigation controls
1050 + *
1051 + * @param string $which Location controls.
1052 + */
1053 + public function display_tablenav( $which ) {
1054 + if ( 'top' === $which ) :
1055 + ?>
885 1056 <div class="tablenav <?php echo esc_attr( $which ); ?>">
886 1057 <?php
887 1058 $this->pagination( $which );
888 1059 $this->extra_tablenav( $which );
@@ -887,9 +1058,9 @@
887 1058 $this->pagination( $which );
888 1059 $this->extra_tablenav( $which );
889 1060 ?>
890 1061
891 - <br class="clear" />
1062 + <br class="clear"/>
892 1063 </div>
893 1064 <?php else : ?>
894 1065 <div class="tablenav <?php echo esc_attr( $which ); ?>">
895 1066 <?php
@@ -900,15 +1071,23 @@
900 1071 $this->pagination( $which );
901 1072 $this->extra_tablenav( $which );
902 1073 ?>
903 1074
904 - <br class="clear" />
1075 + <br class="clear"/>
905 1076 </div>
906 - <?php
1077 + <?php
907 1078 endif;
908 1079 }
909 1080
910 - function set_screen_option( $dummy, $option, $value ) {
1081 + /**
1082 + * Sets the screen options.
1083 + *
1084 + * @param string $dummy Unused.
1085 + * @param string $option Screen option name.
1086 + * @param string $value Screen option value.
1087 + * @return string
1088 + */
1089 + public function set_screen_option( $dummy, $option, $value ) {
911 1090 if ( 'edit_stream_per_page' === $option ) {
912 1091 return $value;
913 1092 } else {
914 1093 return $dummy;
@@ -914,9 +1093,17 @@
914 1093 return $dummy;
915 1094 }
916 1095 }
917 1096
918 - function set_live_update_option( $dummy, $option, $value ) {
1097 + /**
1098 + * Sets the live update options.
1099 + *
1100 + * @param string $dummy Unused.
1101 + * @param string $option Screen option name.
1102 + * @param string $value Screen option value.
1103 + * @return string
1104 + */
1105 + public function set_live_update_option( $dummy, $option, $value ) {
919 1106 unset( $value );
920 1107
921 1108 // @codingStandardsIgnoreStart
922 1109 if (
@@ -927,13 +1114,21 @@
927 1114 $value = esc_attr( $_POST[ $this->plugin->admin->live_update->user_meta_key ] ); //input var okay
928 1115
929 1116 return $value;
930 1117 }
1118 +
931 1119 // @codingStandardsIgnoreEnd
932 1120
933 1121 return $dummy;
934 1122 }
935 1123
1124 + /**
1125 + * Return HTML string of the "Live updates" screen option.
1126 + *
1127 + * @param string $status Unused.
1128 + * @param array $args Unused.
1129 + * @return string
1130 + */
936 1131 public function screen_controls( $status, $args ) {
937 1132 unset( $status );
938 1133 unset( $args );
939 1134
@@ -951,20 +1146,21 @@
951 1146
952 1147 ob_start();
953 1148 ?>
954 1149 <fieldset>
955 - <h5><?php esc_html_e( 'Live updates', 'stream' ) ?></h5>
1150 + <h5><?php esc_html_e( 'Live updates', 'stream' ); ?></h5>
956 1151
957 1152 <div>
958 - <input type="hidden" name="stream_live_update_nonce" id="stream_live_update_nonce" value="<?php echo esc_attr( $nonce ) ?>" />
1153 + <input type="hidden" name="stream_live_update_nonce" id="stream_live_update_nonce" value="<?php echo esc_attr( $nonce ); ?>"/>
959 1154 </div>
960 1155 <div>
961 - <input type="hidden" name="enable_live_update_user" id="enable_live_update_user" value="<?php echo absint( $user_id ) ?>" />
1156 + <input type="hidden" name="enable_live_update_user" id="enable_live_update_user" value="<?php echo absint( $user_id ); ?>"/>
962 1157 </div>
963 1158 <div class="metabox-prefs stream-live-update-checkbox">
964 1159 <label for="enable_live_update">
965 - <input type="checkbox" value="on" name="enable_live_update" id="enable_live_update" data-heartbeat="<?php echo esc_attr( $heartbeat ) ?>" <?php checked( $option, 'on' ) ?> />
966 - <?php esc_html_e( 'Enabled', 'stream' ) ?><span class="spinner"></span>
1160 + <input type="checkbox" value="on" name="enable_live_update" id="enable_live_update" data-heartbeat="<?php echo esc_attr( $heartbeat ); ?>" <?php checked( $option, 'on' ); ?> />
1161 + <?php esc_html_e( 'Enabled', 'stream' ); ?>
1162 + <span class="spinner"></span>
967 1163 </label>
968 1164 </div>
969 1165 </fieldset>
970 1166 <?php
@@ -973,13 +1169,13 @@
973 1169
974 1170 /**
975 1171 * This function is use to map List table column name with excluded setting keys
976 1172 *
977 - * @param string $column List table column name
1173 + * @param string $column List table column name.
978 1174 *
979 1175 * @return string setting name for that column
980 1176 */
981 - function get_column_excluded_setting_key( $column ) {
1177 + public function get_column_excluded_setting_key( $column ) {
982 1178 switch ( $column ) {
983 1179 case 'connector':
984 1180 $output = 'connectors';
985 1181 break;
@@ -1004,9 +1200,9 @@
1004 1200
1005 1201 /**
1006 1202 * Get users as dropdown items
1007 1203 *
1008 - * @param array $users
1204 + * @param array $users Users.
1009 1205 *
1010 1206 * @return array
1011 1207 */
1012 1208 public function get_users_dropdown_items( $users ) {