PluginProbe
Stream – Activity Log & Audit Trail / 3.4.2
Stream – Activity Log & Audit Trail v3.4.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-settings.php +293 -149 3.0.23.4.2 View file →
@@ -1,5 +1,6 @@
1 1 <?php
2 +
2 3 namespace WP_Stream;
3 4
4 5 use \WP_Roles;
5 6 use \WP_User;
@@ -5,10 +6,12 @@
5 6 use \WP_User;
6 7 use \WP_User_Query;
7 8
8 9 class Settings {
10 +
9 11 /**
10 12 * Hold Plugin class
13 + *
11 14 * @var Plugin
12 15 */
13 16 public $plugin;
14 17
@@ -54,12 +57,26 @@
54 57 // Register settings, and fields
55 58 add_action( 'admin_init', array( $this, 'register_settings' ) );
56 59
57 60 // Remove records when records TTL is shortened
58 - add_action( 'update_option_' . $this->option_key, array( $this, 'updated_option_ttl_remove_records' ), 10, 2 );
61 + add_action(
62 + 'update_option_' . $this->option_key,
63 + array(
64 + $this,
65 + 'updated_option_ttl_remove_records',
66 + ),
67 + 10,
68 + 2
69 + );
59 70
60 71 // Apply label translations for settings
61 - add_filter( 'wp_stream_serialized_labels', array( $this, 'get_settings_translations' ) );
72 + add_filter(
73 + 'wp_stream_serialized_labels',
74 + array(
75 + $this,
76 + 'get_settings_translations',
77 + )
78 + );
62 79
63 80 // Ajax callback function to search users
64 81 add_action( 'wp_ajax_stream_get_users', array( $this, 'get_users' ) );
65 82
@@ -84,21 +101,31 @@
84 101 'message' => esc_html__( 'There was an error in the request', 'stream' ),
85 102 );
86 103
87 104 $search = '';
88 - if ( isset( $_POST['find'] ) ) {
89 - // @TODO: Make this pass phpcs
90 - $search = esc_html( wp_unslash( trim( $_POST['find'] ) ) ); // input var okay
105 + $input = wp_stream_filter_input( INPUT_POST, 'find' );
106 +
107 + if ( ! isset( $input['term'] ) ) {
108 + $search = wp_unslash( trim( $input['term'] ) );
91 109 }
110 +
92 111 $request = (object) array(
93 112 'find' => $search,
94 113 );
95 114
96 - add_filter( 'user_search_columns', array( $this, 'add_display_name_search_columns' ), 10, 3 );
115 + add_filter(
116 + 'user_search_columns',
117 + array(
118 + $this,
119 + 'add_display_name_search_columns',
120 + ),
121 + 10,
122 + 3
123 + );
97 124
98 125 $users = new WP_User_Query(
99 126 array(
100 - 'search' => "*{$request->find}*",
127 + 'search' => "*{$request->find}*",
101 128 'search_columns' => array(
102 129 'user_login',
103 130 'user_nicename',
104 131 'user_email',
@@ -103,24 +130,49 @@
103 130 'user_nicename',
104 131 'user_email',
105 132 'user_url',
106 133 ),
107 - 'orderby' => 'display_name',
108 - 'number' => $this->plugin->admin->preload_users_max,
134 + 'orderby' => 'display_name',
135 + 'number' => $this->plugin->admin->preload_users_max,
109 136 )
110 137 );
111 138
112 - remove_filter( 'user_search_columns', array( $this, 'add_display_name_search_columns' ), 10 );
139 + remove_filter(
140 + 'user_search_columns',
141 + array(
142 + $this,
143 + 'add_display_name_search_columns',
144 + ),
145 + 10
146 + );
113 147
114 148 if ( 0 === $users->get_total() ) {
115 149 wp_send_json_error( $response );
116 150 }
151 + $users_array = $users->results;
117 152
118 - $response->status = true;
119 - $response->message = '';
120 - $response->users = array();
153 + if ( is_multisite() && is_super_admin() ) {
154 + $super_admins = get_super_admins();
155 + foreach ( $super_admins as $admin ) {
156 + $user = get_user_by( 'login', $admin );
157 + $users_array[] = $user;
158 + }
159 + }
121 160
122 - foreach ( $users->results as $key => $user ) {
161 + $response->status = true;
162 + $response->message = '';
163 + $response->roles = $this->get_roles();
164 + $response->users = array();
165 + $users_added_to_response = array();
166 +
167 + foreach ( $users_array as $key => $user ) {
168 + // exclude duplications:
169 + if ( array_key_exists( $user->ID, $users_added_to_response ) ) {
170 + continue;
171 + } else {
172 + $users_added_to_response[ $user->ID ] = true;
173 + }
174 +
123 175 $author = new Author( $user->ID );
124 176
125 177 $args = array(
126 178 'id' => $author->ID,
@@ -128,9 +180,10 @@
128 180 );
129 181
130 182 $args['tooltip'] = esc_attr(
131 183 sprintf(
132 - __( "ID: %d\nUser: %s\nEmail: %s\nRole: %s", 'stream' ),
184 + // translators: Placeholders refers to a user ID, a username, an email address, and a user role (e.g. "42", "administrator", "foo@bar.com", "subscriber").
185 + __( 'ID: %1$d\nUser: %2$s\nEmail: %3$s\nRole: %4$s', 'stream' ),
133 186 $author->id,
134 187 $author->user_login,
135 188 $author->user_email,
136 189 ucwords( $author->get_role() )
@@ -141,12 +194,19 @@
141 194
142 195 $response->users[] = $args;
143 196 }
144 197
198 + usort(
199 + $response->users,
200 + function ( $a, $b ) {
201 + return strcmp( $a['text'], $b['text'] );
202 + }
203 + );
204 +
145 205 if ( empty( $search ) || preg_match( '/wp|cli|system|unknown/i', $search ) ) {
146 - $author = new Author( 0 );
206 + $author = new Author( 0 );
147 207 $response->users[] = array(
148 - 'id' => $author->id,
208 + 'id' => '0',
149 209 'text' => $author->get_display_name(),
150 210 'icon' => $author->get_avatar_src( 32 ),
151 211 'tooltip' => esc_html__( 'Actions performed by the system when a user is not logged in (e.g. auto site upgrader, or invoking WP-CLI without --user)', 'stream' ),
152 212 );
@@ -155,10 +215,10 @@
155 215 wp_send_json_success( $response );
156 216 }
157 217
158 218 /**
159 - * Ajax callback function to search IP addresses, used on exclude setting page
160 - */
219 + * Ajax callback function to search IP addresses, used on exclude setting page
220 + */
161 221 public function get_ips() {
162 222 if ( ! defined( 'DOING_AJAX' ) || ! current_user_can( $this->plugin->admin->settings_cap ) ) {
163 223 return;
164 224 }
@@ -164,10 +224,20 @@
164 224 }
165 225
166 226 check_ajax_referer( 'stream_get_ips', 'nonce' );
167 227
168 - $ips = $this->plugin->db->existing_records( 'ip' );
228 + $ips = $this->plugin->db->existing_records( 'ip' );
229 + $find = wp_stream_filter_input( INPUT_POST, 'find' );
169 230
231 + if ( isset( $find['term'] ) && '' !== $find['term'] ) {
232 + $ips = array_filter(
233 + $ips,
234 + function ( $ip ) use ( $find ) {
235 + return 0 === strpos( $ip, $find['term'] );
236 + }
237 + );
238 + }
239 +
170 240 if ( $ips ) {
171 241 wp_send_json_success( $ips );
172 242 } else {
173 243 wp_send_json_error();
@@ -176,11 +246,11 @@
176 246
177 247 /**
178 248 * Filter the columns to search in a WP_User_Query search.
179 249 *
180 - * @param array $search_columns Array of column names to be searched.
181 - * @param string $search Text being searched.
182 - * @param \WP_User_Query $query current WP_User_Query instance.
250 + * @param array $search_columns Array of column names to be searched.
251 + * @param string $search Text being searched.
252 + * @param \WP_User_Query $query current WP_User_Query instance.
183 253 *
184 254 * @return array
185 255 */
186 256 public function add_display_name_search_columns( $search_columns, $search, $query ) {
@@ -219,18 +289,18 @@
219 289 * @return array
220 290 */
221 291 public function get_fields() {
222 292 $fields = array(
223 - 'general' => array(
293 + 'general' => array(
224 294 'title' => esc_html__( 'General', 'stream' ),
225 295 'fields' => array(
226 296 array(
227 - 'name' => 'role_access',
228 - 'title' => esc_html__( 'Role Access', 'stream' ),
229 - 'type' => 'multi_checkbox',
230 - 'desc' => esc_html__( 'Users from the selected roles above will have permission to view Stream Records. However, only site Administrators can access Stream Settings.', 'stream' ),
231 - 'choices' => $this->get_roles(),
232 - 'default' => array( 'administrator' ),
297 + 'name' => 'role_access',
298 + 'title' => esc_html__( 'Role Access', 'stream' ),
299 + 'type' => 'multi_checkbox',
300 + 'desc' => esc_html__( 'Users from the selected roles above will have permission to view Stream Records. However, only site Administrators can access Stream Settings.', 'stream' ),
301 + 'choices' => $this->get_roles(),
302 + 'default' => array( 'administrator' ),
233 303 ),
234 304 array(
235 305 'name' => 'records_ttl',
236 306 'title' => esc_html__( 'Keep Records for', 'stream' ),
@@ -252,18 +322,18 @@
252 322 'default' => 0,
253 323 ),
254 324 ),
255 325 ),
256 - 'exclude' => array(
326 + 'exclude' => array(
257 327 'title' => esc_html__( 'Exclude', 'stream' ),
258 328 'fields' => array(
259 329 array(
260 - 'name' => 'rules',
261 - 'title' => esc_html__( 'Exclude Rules', 'stream' ),
262 - 'type' => 'rule_list',
263 - 'desc' => esc_html__( 'Create rules to exclude certain kinds of activity from being recorded by Stream.', 'stream' ),
264 - 'default' => array(),
265 - 'nonce' => 'stream_get_ips',
330 + 'name' => 'rules',
331 + 'title' => esc_html__( 'Exclude Rules', 'stream' ),
332 + 'type' => 'rule_list',
333 + 'desc' => esc_html__( 'Create rules to exclude certain kinds of activity from being recorded by Stream.', 'stream' ),
334 + 'default' => array(),
335 + 'nonce' => 'stream_get_ips',
266 336 ),
267 337 ),
268 338 ),
269 339 'advanced' => array(
@@ -277,22 +347,22 @@
277 347 'after_field' => esc_html__( 'Enabled', 'stream' ),
278 348 'default' => 0,
279 349 ),
280 350 array(
281 - 'name' => 'delete_all_records',
282 - 'title' => esc_html__( 'Reset Stream Database', 'stream' ),
283 - 'type' => 'link',
284 - 'href' => add_query_arg(
351 + 'name' => 'delete_all_records',
352 + 'title' => esc_html__( 'Reset Stream Database', 'stream' ),
353 + 'type' => 'link',
354 + 'href' => add_query_arg(
285 355 array(
286 - 'action' => 'wp_stream_reset',
287 - 'wp_stream_nonce' => wp_create_nonce( 'stream_nonce' ),
356 + 'action' => 'wp_stream_reset',
357 + 'wp_stream_nonce_reset' => wp_create_nonce( 'stream_nonce_reset' ),
288 358 ),
289 359 admin_url( 'admin-ajax.php' )
290 360 ),
291 - 'class' => 'warning',
292 - 'desc' => esc_html__( 'Warning: This will delete all activity records from the database.', 'stream' ),
293 - 'default' => 0,
294 - 'sticky' => 'bottom',
361 + 'class' => 'warning',
362 + 'desc' => esc_html__( 'Warning: This will delete all activity records from the database.', 'stream' ),
363 + 'default' => 0,
364 + 'sticky' => 'bottom',
295 365 ),
296 366 ),
297 367 ),
298 368 );
@@ -310,21 +380,18 @@
310 380
311 381 array_push( $fields['advanced']['fields'], $akismet_tracking );
312 382 }
313 383
314 - // If WP Cron is enabled, allow Admins to opt-in to WP Cron tracking
315 - if ( wp_stream_is_cron_enabled() ) {
316 - $wp_cron_tracking = array(
317 - 'name' => 'wp_cron_tracking',
318 - 'title' => esc_html__( 'WP Cron Tracking', 'stream' ),
319 - 'type' => 'checkbox',
320 - 'desc' => esc_html__( 'By default, Stream does not track activity performed by WordPress cron events unless you opt-in here. Enabling this is not necessary or recommended for most sites.', 'stream' ),
321 - 'after_field' => esc_html__( 'Enabled', 'stream' ),
322 - 'default' => 0,
323 - );
384 + $wp_cron_tracking = array(
385 + 'name' => 'wp_cron_tracking',
386 + 'title' => esc_html__( 'WP Cron Tracking', 'stream' ),
387 + 'type' => 'checkbox',
388 + 'desc' => esc_html__( 'By default, Stream does not track activity performed by WordPress cron events unless you opt-in here. Enabling this is not necessary or recommended for most sites.', 'stream' ),
389 + 'after_field' => esc_html__( 'Enabled', 'stream' ),
390 + 'default' => 0,
391 + );
324 392
325 - array_push( $fields['advanced']['fields'], $wp_cron_tracking );
326 - }
393 + array_push( $fields['advanced']['fields'], $wp_cron_tracking );
327 394
328 395 /**
329 396 * Filter allows for modification of options fields
330 397 *
@@ -403,9 +470,16 @@
403 470 */
404 471 public function register_settings() {
405 472 $sections = $this->get_fields();
406 473
407 - register_setting( $this->option_key, $this->option_key, array( $this, 'sanitize_settings' ) );
474 + register_setting(
475 + $this->option_key,
476 + $this->option_key,
477 + array(
478 + $this,
479 + 'sanitize_settings',
480 + )
481 + );
408 482
409 483 foreach ( $sections as $section_name => $section ) {
410 484 add_settings_section(
411 485 $section_name,
@@ -421,14 +495,18 @@
421 495
422 496 add_settings_field(
423 497 $field['name'],
424 498 $field['title'],
425 - ( isset( $field['callback'] ) ? $field['callback'] : array( $this, 'output_field' ) ),
499 + ( isset( $field['callback'] ) ? $field['callback'] : array(
500 + $this,
501 + 'output_field',
502 + ) ),
426 503 $this->option_key,
427 504 $section_name,
428 505 $field + array(
429 506 'section' => $section_name,
430 - 'label_for' => sprintf( '%s_%s_%s', $this->option_key, $section_name, $field['name'] ), // xss ok
507 + 'label_for' => sprintf( '%s_%s_%s', $this->option_key, $section_name, $field['name'] ),
508 + // xss ok
431 509 )
432 510 );
433 511 }
434 512 }
@@ -457,9 +535,9 @@
457 535 if ( empty( $type ) || ! isset( $input[ $name ] ) || '' === $input[ $name ] ) {
458 536 continue;
459 537 }
460 538
461 - // Sanitize depending on the type of field
539 + // Sanitize depending on the type of field.
462 540 switch ( $type ) {
463 541 case 'number':
464 542 $output[ $name ] = is_numeric( $input[ $name ] ) ? intval( trim( $input[ $name ] ) ) : '';
465 543 break;
@@ -469,14 +547,17 @@
469 547 default:
470 548 if ( is_array( $input[ $name ] ) ) {
471 549 $output[ $name ] = $input[ $name ];
472 550
473 - // Support all values in multidimentional arrays too
474 - array_walk_recursive( $output[ $name ], function( &$v, $k ) {
475 - $v = trim( $v );
476 - } );
551 + // Support all values in multidimentional arrays too.
552 + array_walk_recursive(
553 + $output[ $name ],
554 + function ( &$v ) {
555 + $v = sanitize_text_field( trim( $v ) );
556 + }
557 + );
477 558 } else {
478 - $output[ $name ] = trim( $input[ $name ] );
559 + $output[ $name ] = sanitize_text_field( trim( $input[ $name ] ) );
479 560 }
480 561 }
481 562 }
482 563 }
@@ -529,11 +610,9 @@
529 610 if ( ! $type || ! $section || ! $name ) {
530 611 return '';
531 612 }
532 613
533 - if ( 'multi_checkbox' === $type
534 - && ( empty( $field['choices'] ) || ! is_array( $field['choices'] ) )
535 - ) {
614 + if ( 'multi_checkbox' === $type && ( empty( $field['choices'] ) || ! is_array( $field['choices'] ) ) ) {
536 615 return '';
537 616 }
538 617
539 618 switch ( $type ) {
@@ -568,14 +647,22 @@
568 647 wp_kses_post( $after_field )
569 648 );
570 649 break;
571 650 case 'checkbox':
651 + if ( isset( $current_value ) ) {
652 + $value = $current_value;
653 + } elseif ( isset( $default ) ) {
654 + $value = $default;
655 + } else {
656 + $value = 0;
657 + }
658 +
572 659 $output = sprintf(
573 660 '<label><input type="checkbox" name="%1$s[%2$s_%3$s]" id="%1$s[%2$s_%3$s]" value="1" %4$s /> %5$s</label>',
574 661 esc_attr( $option_key ),
575 662 esc_attr( $section ),
576 663 esc_attr( $name ),
577 - checked( $current_value, 1, false ),
664 + checked( $value, 1, false ),
578 665 wp_kses_post( $after_field )
579 666 );
580 667 break;
581 668 case 'multi_checkbox':
@@ -584,10 +671,10 @@
584 671 esc_attr( $option_key ),
585 672 esc_attr( $section ),
586 673 esc_attr( $name )
587 674 );
588 - // Fallback if nothing is selected
589 - $output .= sprintf(
675 + // Fallback if nothing is selected.
676 + $output .= sprintf(
590 677 '<input type="hidden" name="%1$s[%2$s_%3$s][]" value="__placeholder__" />',
591 678 esc_attr( $option_key ),
592 679 esc_attr( $section ),
593 680 esc_attr( $name )
@@ -592,9 +679,9 @@
592 679 esc_attr( $section ),
593 680 esc_attr( $name )
594 681 );
595 682 $current_value = (array) $current_value;
596 - $choices = $field['choices'];
683 + $choices = $field['choices'];
597 684 if ( is_callable( $choices ) ) {
598 685 $choices = call_user_func( $choices );
599 686 }
600 687 foreach ( $choices as $value => $label ) {
@@ -605,9 +692,9 @@
605 692 esc_attr( $option_key ),
606 693 esc_attr( $section ),
607 694 esc_attr( $name ),
608 695 esc_attr( $value ),
609 - checked( in_array( $value, $current_value ), true, false )
696 + checked( in_array( $value, $current_value, true ), true, false )
610 697 ),
611 698 esc_html( $label )
612 699 );
613 700 }
@@ -659,9 +746,9 @@
659 746 esc_attr( $href ),
660 747 esc_attr( $title )
661 748 );
662 749 break;
663 - case 'select2' :
750 + case 'select2':
664 751 if ( ! isset( $current_value ) ) {
665 752 $current_value = '';
666 753 }
667 754
@@ -678,16 +765,26 @@
678 765 $child_values = array();
679 766 if ( isset( $value['children'] ) ) {
680 767 $child_values = array();
681 768 foreach ( $value['children'] as $child_key => $child_value ) {
682 - $child_values[] = array( 'id' => $child_key, 'text' => $child_value );
769 + $child_values[] = array(
770 + 'id' => $child_key,
771 + 'text' => $child_value,
772 + );
683 773 }
684 774 }
685 775 if ( isset( $value['label'] ) ) {
686 - $data_values[] = array( 'id' => $key, 'text' => $value['label'], 'children' => $child_values );
776 + $data_values[] = array(
777 + 'id' => $key,
778 + 'text' => $value['label'],
779 + 'children' => $child_values,
780 + );
687 781 }
688 782 } else {
689 - $data_values[] = array( 'id' => $key, 'text' => $value );
783 + $data_values[] = array(
784 + 'id' => $key,
785 + 'text' => $value,
786 + );
690 787 }
691 788 }
692 789 $class .= ' with-source';
693 790 }
@@ -699,8 +796,9 @@
699 796 esc_attr( $name ),
700 797 esc_attr( wp_stream_json_encode( $data_values ) ),
701 798 esc_attr( $current_value ),
702 799 esc_attr( $class ),
800 + // translators: Placeholder refers to the title of the dropdown menu (e.g. "users")
703 801 sprintf( esc_html__( 'Any %s', 'stream' ), $title )
704 802 );
705 803
706 804 $output = sprintf(
@@ -711,13 +809,15 @@
711 809 $input_html
712 810 );
713 811
714 812 break;
715 - case 'rule_list' :
813 + case 'rule_list':
814 + $users = count_users();
815 + $form = new Form_Generator();
716 816 $output = '<p class="description">' . esc_html( $description ) . '</p>';
717 817
718 - $actions_top = sprintf( '<input type="button" class="button" id="%1$s_new_rule" value="&#43; %2$s" />', esc_attr( $section . '_' . $name ), esc_html__( 'Add New Rule', 'stream' ) );
719 - $actions_bottom = sprintf( '<input type="button" class="button" id="%1$s_remove_rules" value="%2$s" />', esc_attr( $section . '_' . $name ), esc_html__( 'Delete Selected Rules', 'stream' ) );
818 + $actions_top = sprintf( '<input type="button" class="button" id="%1$s_new_rule" value="&#43; %2$s" />', esc_attr( $section . '_' . $name ), esc_html__( 'Add New Rule', 'stream' ) );
819 + $actions_bottom = sprintf( '<input type="button" class="button" id="%1$s_remove_rules" value="%2$s" />', esc_attr( $section . '_' . $name ), esc_html__( 'Delete Selected Rules', 'stream' ) );
720 820
721 821 $output .= sprintf( '<div class="tablenav top">%1$s</div>', $actions_top );
722 822 $output .= '<table class="wp-list-table widefat fixed stream-exclude-list">';
723 823
@@ -741,13 +841,18 @@
741 841 );
742 842
743 843 $exclude_rows = array();
744 844
745 - // Prepend an empty row
746 - $current_value['exclude_row'] = array( 'helper' => '' ) + ( isset( $current_value['exclude_row'] ) ? $current_value['exclude_row'] : array() );
845 + // Account for when no rules have been added yet.
846 + if ( ! is_array( $current_value ) ) {
847 + $current_value = array();
848 + }
747 849
850 + // Prepend an empty row.
851 + $current_value['exclude_row'] = ( isset( $current_value['exclude_row'] ) ? $current_value['exclude_row'] : array() ) + array( 'helper' => '' );
852 +
748 853 foreach ( $current_value['exclude_row'] as $key => $value ) {
749 - // Prepare values
854 + // Prepare values.
750 855 $author_or_role = isset( $current_value['author_or_role'][ $key ] ) ? $current_value['author_or_role'][ $key ] : '';
751 856 $connector = isset( $current_value['connector'][ $key ] ) ? $current_value['connector'][ $key ] : '';
752 857 $context = isset( $current_value['context'][ $key ] ) ? $current_value['context'][ $key ] : '';
753 858 $action = isset( $current_value['action'][ $key ] ) ? $current_value['action'][ $key ] : '';
@@ -757,19 +862,22 @@
757 862 $author_or_role_values = array();
758 863 $author_or_role_selected = array();
759 864
760 865 foreach ( $this->get_roles() as $role_id => $role ) {
761 - $args = array( 'id' => $role_id, 'text' => $role );
762 - $users = count_users();
866 + $args = array(
867 + 'value' => $role_id,
868 + 'text' => $role,
869 + );
763 870 $count = isset( $users['avail_roles'][ $role_id ] ) ? $users['avail_roles'][ $role_id ] : 0;
764 871
765 872 if ( ! empty( $count ) ) {
766 - $args['user_count'] = sprintf( _n( '1 user', '%s users', absint( $count ), 'stream' ), absint( $count ) );
873 + // translators: Placeholder refers to a number of users (e.g. "42")
874 + $args['user_count'] = sprintf( _n( '%d user', '%d users', absint( $count ), 'stream' ), absint( $count ) );
767 875 }
768 876
769 877 if ( $role_id === $author_or_role ) {
770 - $author_or_role_selected['id'] = $role_id;
771 - $author_or_role_selected['text'] = $role;
878 + $author_or_role_selected['value'] = $role_id;
879 + $author_or_role_selected['text'] = $role;
772 880 }
773 881
774 882 $author_or_role_values[] = $args;
775 883 }
@@ -776,22 +884,28 @@
776 884
777 885 if ( empty( $author_or_role_selected ) && is_numeric( $author_or_role ) ) {
778 886 $user = new WP_User( $author_or_role );
779 887 $display_name = ( 0 === $user->ID ) ? esc_html__( 'N/A', 'stream' ) : $user->display_name;
780 - $author_or_role_selected = array( 'id' => $user->ID, 'text' => $display_name );
888 + $author_or_role_selected = array(
889 + 'value' => $user->ID,
890 + 'text' => $display_name,
891 + );
892 + $author_or_role_values[] = $author_or_role_selected;
781 893 }
782 894
783 - $author_or_role_input = sprintf(
784 - '<input type="hidden" name="%1$s[%2$s_%3$s][%4$s][]" data-values=\'%5$s\' data-selected-id=\'%6$s\' data-selected-text=\'%7$s\' value="%6$s" class="select2-select %4$s" data-placeholder="%8$s" data-nonce="%9$s" />',
785 - esc_attr( $option_key ),
786 - esc_attr( $section ),
787 - esc_attr( $name ),
788 - 'author_or_role',
789 - esc_attr( wp_stream_json_encode( $author_or_role_values ) ),
790 - isset( $author_or_role_selected['id'] ) ? esc_attr( $author_or_role_selected['id'] ) : '',
791 - isset( $author_or_role_selected['text'] ) ? esc_attr( $author_or_role_selected['text'] ) : '',
792 - esc_html__( 'Any Author or Role', 'stream' ),
793 - esc_attr( wp_create_nonce( 'stream_get_users' ) )
895 + $author_or_role_input = $form->render_field(
896 + 'select2',
897 + array(
898 + 'name' => esc_attr( sprintf( '%1$s[%2$s_%3$s][%4$s][]', $option_key, $section, $name, 'author_or_role' ) ),
899 + 'options' => $author_or_role_values,
900 + 'classes' => 'author_or_role',
901 + 'data' => array(
902 + 'placeholder' => esc_html__( 'Any Author or Role', 'stream' ),
903 + 'nonce' => esc_attr( wp_create_nonce( 'stream_get_users' ) ),
904 + 'selected-id' => isset( $author_or_role_selected['value'] ) ? esc_attr( $author_or_role_selected['value'] ) : '',
905 + 'selected-text' => isset( $author_or_role_selected['text'] ) ? esc_attr( $author_or_role_selected['text'] ) : '',
906 + ),
907 + )
794 908 );
795 909
796 910 // Context dropdown menu
797 911 $context_values = array();
@@ -801,68 +915,97 @@
801 915 $child_values = array();
802 916 if ( isset( $context_data['children'] ) ) {
803 917 $child_values = array();
804 918 foreach ( $context_data['children'] as $child_id => $child_value ) {
805 - $child_values[] = array( 'id' => $child_id, 'text' => $child_value, 'parent' => $context_id );
919 + $child_values[] = array(
920 + 'value' => $context_id . '-' . $child_id,
921 + 'text' => $child_value,
922 + 'parent' => $context_id,
923 + );
806 924 }
807 925 }
808 926 if ( isset( $context_data['label'] ) ) {
809 - $context_values[] = array( 'id' => $context_id, 'text' => $context_data['label'], 'children' => $child_values );
927 + $context_values[] = array(
928 + 'value' => $context_id,
929 + 'text' => $context_data['label'],
930 + 'children' => $child_values,
931 + );
810 932 }
811 933 } else {
812 - $context_values[] = array( 'id' => $context_id, 'text' => $context_data );
934 + $context_values[] = array(
935 + 'value' => $context_id,
936 + 'text' => $context_data,
937 + );
813 938 }
814 939 }
815 940
816 - $connector_input = sprintf(
817 - '<input type="hidden" name="%1$s[%2$s_%3$s][%4$s][]" class="%4$s" value="%5$s">',
818 - esc_attr( $option_key ),
819 - esc_attr( $section ),
820 - esc_attr( $name ),
821 - esc_attr( 'connector' ),
822 - esc_attr( $connector )
941 + $connector_or_context_input = $form->render_field(
942 + 'select2',
943 + array(
944 + 'name' => esc_attr( sprintf( '%1$s[%2$s_%3$s][%4$s][]', $option_key, $section, $name, 'connector_or_context' ) ),
945 + 'options' => $context_values,
946 + 'classes' => 'connector_or_context',
947 + 'data' => array(
948 + 'group' => 'connector',
949 + 'placeholder' => __( 'Any Context', 'stream' ),
950 + ),
951 + )
823 952 );
824 953
825 - $context_input = sprintf(
826 - '<input type="hidden" name="%1$s[%2$s_%3$s][%4$s][]" data-values=\'%5$s\' value="%6$s" class="select2-select with-source %4$s" data-placeholder="%7$s" data-group="%8$s" />',
827 - esc_attr( $option_key ),
828 - esc_attr( $section ),
829 - esc_attr( $name ),
830 - 'context',
831 - esc_attr( wp_stream_json_encode( $context_values ) ),
832 - esc_attr( $context ),
833 - esc_html__( 'Any Context', 'stream' ),
834 - 'connector'
954 + $connector_input = $form->render_field(
955 + 'hidden',
956 + array(
957 + 'name' => esc_attr( sprintf( '%1$s[%2$s_%3$s][%4$s][]', $option_key, $section, $name, 'connector' ) ),
958 + 'value' => $connector,
959 + 'classes' => 'connector',
960 + )
835 961 );
836 962
963 + $context_input = $form->render_field(
964 + 'hidden',
965 + array(
966 + 'name' => esc_attr( sprintf( '%1$s[%2$s_%3$s][%4$s][]', $option_key, $section, $name, 'context' ) ),
967 + 'value' => $context,
968 + 'classes' => 'context',
969 + )
970 + );
971 +
837 972 // Action dropdown menu
838 973 $action_values = array();
839 974
840 975 foreach ( $this->get_terms_labels( 'action' ) as $action_id => $action_data ) {
841 - $action_values[] = array( 'id' => $action_id, 'text' => $action_data );
976 + $action_values[] = array(
977 + 'value' => $action_id,
978 + 'text' => $action_data,
979 + );
842 980 }
843 981
844 - $action_input = sprintf(
845 - '<input type="hidden" name="%1$s[%2$s_%3$s][%4$s][]" data-values=\'%5$s\' value="%6$s" class="select2-select with-source %4$s" data-placeholder="%7$s" />',
846 - esc_attr( $option_key ),
847 - esc_attr( $section ),
848 - esc_attr( $name ),
849 - 'action',
850 - esc_attr( wp_stream_json_encode( $action_values ) ),
851 - esc_attr( $action ),
852 - esc_html__( 'Any Action', 'stream' )
982 + $action_input = $form->render_field(
983 + 'select2',
984 + array(
985 + 'name' => esc_attr( sprintf( '%1$s[%2$s_%3$s][%4$s][]', $option_key, $section, $name, 'action' ) ),
986 + 'value' => $action,
987 + 'options' => $action_values,
988 + 'classes' => 'action',
989 + 'data' => array(
990 + 'placeholder' => __( 'Any Action', 'stream' ),
991 + ),
992 + )
853 993 );
854 994
855 995 // IP Address input
856 - $ip_address_input = sprintf(
857 - '<input type="hidden" name="%1$s[%2$s_%3$s][%4$s][]" value="%5$s" class="select2-select %4$s" data-placeholder="%6$s" data-nonce="%7$s" />',
858 - esc_attr( $option_key ),
859 - esc_attr( $section ),
860 - esc_attr( $name ),
861 - 'ip_address',
862 - esc_attr( $ip_address ),
863 - esc_html__( 'Any IP Address', 'stream' ),
864 - esc_attr( wp_create_nonce( 'stream_get_ips' ) )
996 + $ip_address_input = $form->render_field(
997 + 'select2',
998 + array(
999 + 'name' => esc_attr( sprintf( '%1$s[%2$s_%3$s][%4$s][]', $option_key, $section, $name, 'ip_address' ) ),
1000 + 'value' => $ip_address,
1001 + 'classes' => 'ip_address',
1002 + 'data' => array(
1003 + 'placeholder' => esc_attr__( 'Any IP Address', 'stream' ),
1004 + 'nonce' => esc_attr( wp_create_nonce( 'stream_get_ips' ) ),
1005 + ),
1006 + 'multiple' => true,
1007 + )
865 1008 );
866 1009
867 1010 // Hidden helper input
868 1011 $helper_input = sprintf(
@@ -876,18 +1019,19 @@
876 1019 $exclude_rows[] = sprintf(
877 1020 '<tr class="%1$s %2$s">
878 1021 <th scope="row" class="check-column">%3$s %4$s</th>
879 1022 <td>%5$s</td>
880 - <td>%6$s %7$s</td>
881 - <td>%8$s</td>
1023 + <td>%6$s %7$s %8$s</td>
882 1024 <td>%9$s</td>
883 - <th scope="row" class="actions-column">%10$s</th>
1025 + <td>%10$s</td>
1026 + <th scope="row" class="actions-column">%11$s</th>
884 1027 </tr>',
885 - ( 0 !== $key % 2 ) ? 'alternate' : '',
886 - ( 'helper' === $key ) ? 'hidden helper' : '',
1028 + ( 0 !== (int) $key % 2 ) ? 'alternate' : '',
1029 + ( 'helper' === (string) $key ) ? 'hidden helper' : '',
887 1030 '<input class="cb-select" type="checkbox" />',
888 1031 $helper_input,
889 1032 $author_or_role_input,
1033 + $connector_or_context_input,
890 1034 $connector_input,
891 1035 $context_input,
892 1036 $action_input,
893 1037 $ip_address_input,
@@ -991,10 +1135,10 @@
991 1135 * @param array $old_value
992 1136 * @param array $new_value
993 1137 */
994 1138 public function updated_option_ttl_remove_records( $old_value, $new_value ) {
995 - $ttl_before = isset( $old_value['general_records_ttl'] ) ? (int) $old_value['general_records_ttl'] : -1;
996 - $ttl_after = isset( $new_value['general_records_ttl'] ) ? (int) $new_value['general_records_ttl'] : -1;
1139 + $ttl_before = isset( $old_value['general_records_ttl'] ) ? (int) $old_value['general_records_ttl'] : - 1;
1140 + $ttl_after = isset( $new_value['general_records_ttl'] ) ? (int) $new_value['general_records_ttl'] : - 1;
997 1141
998 1142 if ( $ttl_after < $ttl_before ) {
999 1143 /**
1000 1144 * Action assists in purging when TTL is shortened