Stream - Version 3.4.2

Version Description

  • September 26, 2019 =

  • Fix: Visiting the plugin settings page no longer produces PHP warnings for undefined variables #1031.

  • Fix: The IP address based exclude rules now stay with the same ruleset when saving #1035. Previously IP addresses would jump to the previous rule which didn't have an IP address based conditional.

Download this release

Release Info

Developer kasparsd
Plugin Icon 128x128 Stream
Version 3.4.2
Comparing to
See all releases

Code changes from version 3.4.1 to 3.4.2

classes/class-log.php CHANGED
@@ -163,6 +163,8 @@ class Log {
163
  * @return bool
164
  */
165
  public function is_record_excluded( $connector, $context, $action, $user = null, $ip = null ) {
 
 
166
  if ( is_null( $user ) ) {
167
  $user = wp_get_current_user();
168
  }
@@ -191,64 +193,25 @@ class Log {
191
  $exclude_settings = isset( $this->plugin->settings->options['exclude_rules'] ) ? $this->plugin->settings->options['exclude_rules'] : array();
192
 
193
  if ( is_multisite() && $this->plugin->is_network_activated() && ! is_network_admin() ) {
194
- $multisite_options = (array) get_site_option( 'wp_stream_network', array() );
195
- $multisite_exclude_settings = isset( $multisite_options['exclude_rules'] ) ? $multisite_options['exclude_rules'] : array();
196
-
197
- if ( ! empty( $multisite_exclude_settings ) ) {
198
- foreach ( $multisite_exclude_settings['exclude_row'] as $key => $rule ) {
199
- $exclude_settings['exclude_row'][] = $multisite_exclude_settings['exclude_row'][ $key ];
200
- $exclude_settings['author_or_role'][] = $multisite_exclude_settings['author_or_role'][ $key ];
201
- $exclude_settings['connector'][] = $multisite_exclude_settings['connector'][ $key ];
202
- $exclude_settings['context'][] = $multisite_exclude_settings['context'][ $key ];
203
- $exclude_settings['action'][] = $multisite_exclude_settings['action'][ $key ];
204
- $exclude_settings['ip_address'][] = $multisite_exclude_settings['ip_address'][ $key ];
205
- }
206
- }
207
  }
208
 
209
- $exclude_record = false;
 
 
 
 
 
 
 
 
210
 
211
- if ( isset( $exclude_settings['exclude_row'] ) && ! empty( $exclude_settings['exclude_row'] ) ) {
212
- foreach ( $exclude_settings['exclude_row'] as $key => $value ) {
213
- // Prepare values.
214
- $author_or_role = isset( $exclude_settings['author_or_role'][ $key ] ) ? $exclude_settings['author_or_role'][ $key ] : '';
215
- $connector = isset( $exclude_settings['connector'][ $key ] ) ? $exclude_settings['connector'][ $key ] : '';
216
- $context = isset( $exclude_settings['context'][ $key ] ) ? $exclude_settings['context'][ $key ] : '';
217
- $action = isset( $exclude_settings['action'][ $key ] ) ? $exclude_settings['action'][ $key ] : '';
218
- $ip_address = isset( $exclude_settings['ip_address'][ $key ] ) ? $exclude_settings['ip_address'][ $key ] : '';
219
-
220
- $exclude = array(
221
- 'connector' => ! empty( $connector ) ? $connector : null,
222
- 'context' => ! empty( $context ) ? $context : null,
223
- 'action' => ! empty( $action ) ? $action : null,
224
- 'ip_address' => ! empty( $ip_address ) ? $ip_address : null,
225
- 'author' => is_numeric( $author_or_role ) ? absint( $author_or_role ) : null,
226
- 'role' => ( ! empty( $author_or_role ) && ! is_numeric( $author_or_role ) ) ? $author_or_role : null,
227
- );
228
-
229
- $exclude_rules = array_filter( $exclude, 'strlen' );
230
-
231
- if ( ! empty( $exclude_rules ) ) {
232
- $matches_exclusion_rule = true;
233
-
234
- foreach ( $exclude_rules as $exclude_key => $exclude_value ) {
235
- if ( 'ip_address' === $exclude_key ) {
236
- $ip_addresses = explode( ',', $exclude_value );
237
- if ( ! in_array( $record['ip_address'], $ip_addresses, true ) ) {
238
- $matches_exclusion_rule = false;
239
- break;
240
- }
241
- } elseif ( $record[ $exclude_key ] !== $exclude_value ) {
242
- $matches_exclusion_rule = false;
243
- break;
244
- }
245
- }
246
-
247
- if ( $matches_exclusion_rule ) {
248
- $exclude_record = true;
249
- break;
250
- }
251
- }
252
  }
253
  }
254
 
@@ -265,6 +228,73 @@ class Log {
265
  return apply_filters( 'wp_stream_is_record_excluded', $exclude_record, $record );
266
  }
267
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  /**
269
  * Helper function to send a full backtrace of calls to the PHP error log for debugging
270
  *
163
  * @return bool
164
  */
165
  public function is_record_excluded( $connector, $context, $action, $user = null, $ip = null ) {
166
+ $exclude_record = false;
167
+
168
  if ( is_null( $user ) ) {
169
  $user = wp_get_current_user();
170
  }
193
  $exclude_settings = isset( $this->plugin->settings->options['exclude_rules'] ) ? $this->plugin->settings->options['exclude_rules'] : array();
194
 
195
  if ( is_multisite() && $this->plugin->is_network_activated() && ! is_network_admin() ) {
196
+ $multisite_options = (array) get_site_option( 'wp_stream_network', array() );
197
+ $exclude_settings = isset( $multisite_options['exclude_rules'] ) ? $multisite_options['exclude_rules'] : array();
 
 
 
 
 
 
 
 
 
 
 
198
  }
199
 
200
+ foreach ( $this->exclude_rules_by_rows( $exclude_settings ) as $exclude_rule ) {
201
+ $exclude = array(
202
+ 'connector' => ! empty( $exclude_rule['connector'] ) ? $exclude_rule['connector'] : null,
203
+ 'context' => ! empty( $exclude_rule['context'] ) ? $exclude_rule['context'] : null,
204
+ 'action' => ! empty( $exclude_rule['action'] ) ? $exclude_rule['action'] : null,
205
+ 'ip_address' => ! empty( $exclude_rule['ip_address'] ) ? $exclude_rule['ip_address'] : null,
206
+ 'author' => is_numeric( $exclude_rule['author_or_role'] ) ? absint( $exclude_rule['author_or_role'] ) : null,
207
+ 'role' => ( ! empty( $exclude_rule['author_or_role'] ) && ! is_numeric( $exclude_rule['author_or_role'] ) ) ? $exclude_rule['author_or_role'] : null,
208
+ );
209
 
210
+ $exclude_rules = array_filter( $exclude, 'strlen' );
211
+
212
+ if ( $this->record_matches_rules( $record, $exclude_rules ) ) {
213
+ $exclude_record = true;
214
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  }
216
  }
217
 
228
  return apply_filters( 'wp_stream_is_record_excluded', $exclude_record, $record );
229
  }
230
 
231
+ /**
232
+ * Check if a record to stored matches certain rules.
233
+ *
234
+ * @param array $record List of record parameters.
235
+ * @param array $exclude_rules List of record exclude rules.
236
+ *
237
+ * @return boolean
238
+ */
239
+ public function record_matches_rules( $record, $exclude_rules ) {
240
+ foreach ( $exclude_rules as $exclude_key => $exclude_value ) {
241
+ if ( ! isset( $record[ $exclude_key ] ) ) {
242
+ continue;
243
+ }
244
+
245
+ if ( 'ip_address' === $exclude_key ) {
246
+ $ip_addresses = explode( ',', $exclude_value );
247
+
248
+ if ( in_array( $record['ip_address'], $ip_addresses, true ) ) {
249
+ return true;
250
+ }
251
+ } elseif ( $record[ $exclude_key ] === $exclude_value ) {
252
+ return true;
253
+ }
254
+ }
255
+
256
+ return false;
257
+ }
258
+
259
+ /**
260
+ * Get all exclude rules by row because we store them by rule instead.
261
+ *
262
+ * @param array $rules List of rules indexed by rule ID.
263
+ *
264
+ * @return array
265
+ */
266
+ public function exclude_rules_by_rows( $rules ) {
267
+ $excludes = array();
268
+
269
+ // TODO: Move these to where the settings are generated to ensure they're in sync.
270
+ $rule_keys = array(
271
+ 'exclude_row',
272
+ 'author_or_role',
273
+ 'connector',
274
+ 'context',
275
+ 'action',
276
+ 'ip_address',
277
+ );
278
+
279
+ if ( empty( $rules['exclude_row'] ) ) {
280
+ return array();
281
+ }
282
+
283
+ foreach ( array_keys( $rules['exclude_row'] ) as $row_id ) {
284
+ $excludes[ $row_id ] = array();
285
+
286
+ foreach ( $rule_keys as $rule_key ) {
287
+ if ( isset( $rules[ $rule_key ][ $row_id ] ) ) {
288
+ $excludes[ $row_id ][ $rule_key ] = $rules[ $rule_key ][ $row_id ];
289
+ } else {
290
+ $excludes[ $row_id ][ $rule_key ] = null;
291
+ }
292
+ }
293
+ }
294
+
295
+ return $excludes;
296
+ }
297
+
298
  /**
299
  * Helper function to send a full backtrace of calls to the PHP error log for debugging
300
  *
classes/class-plugin.php CHANGED
@@ -9,7 +9,7 @@ class Plugin {
9
  *
10
  * @const string
11
  */
12
- const VERSION = '3.4.1';
13
 
14
  /**
15
  * WP-CLI command
9
  *
10
  * @const string
11
  */
12
+ const VERSION = '3.4.2';
13
 
14
  /**
15
  * WP-CLI command
classes/class-settings.php CHANGED
@@ -551,12 +551,12 @@ class Settings {
551
  // Support all values in multidimentional arrays too.
552
  array_walk_recursive(
553
  $output[ $name ],
554
- function ( &$v, $k ) {
555
- $v = trim( $v );
556
  }
557
  );
558
  } else {
559
- $output[ $name ] = trim( $input[ $name ] );
560
  }
561
  }
562
  }
@@ -842,8 +842,13 @@ class Settings {
842
 
843
  $exclude_rows = array();
844
 
 
 
 
 
 
845
  // Prepend an empty row.
846
- $current_value['exclude_row'] = array( 'helper' => '' ) + ( isset( $current_value['exclude_row'] ) ? $current_value['exclude_row'] : array() );
847
 
848
  foreach ( $current_value['exclude_row'] as $key => $value ) {
849
  // Prepare values.
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
  );
558
  } else {
559
+ $output[ $name ] = sanitize_text_field( trim( $input[ $name ] ) );
560
  }
561
  }
562
  }
842
 
843
  $exclude_rows = array();
844
 
845
+ // Account for when no rules have been added yet.
846
+ if ( ! is_array( $current_value ) ) {
847
+ $current_value = array();
848
+ }
849
+
850
  // Prepend an empty row.
851
+ $current_value['exclude_row'] = ( isset( $current_value['exclude_row'] ) ? $current_value['exclude_row'] : array() ) + array( 'helper' => '' );
852
 
853
  foreach ( $current_value['exclude_row'] as $key => $value ) {
854
  // Prepare values.
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === Stream ===
2
- Contributors: lukecarbis, fjarrett, stream, xwp
3
  Tags: wp stream, stream, activity, logs, track
4
  Requires at least: 4.5
5
  Tested up to: 5.2
6
- Stable tag: 3.4.1
7
  License: GPLv2 or later
8
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -87,6 +87,11 @@ Thank you for wanting to make Stream better for everyone!
87
 
88
  == Changelog ==
89
 
 
 
 
 
 
90
  = 3.4.1 - July 25, 2019 =
91
 
92
  * Fix: Allow tracking cron events even when the default WordPress front-end cron runner is disabled via `DISABLE_WP_CRON`. See [#959], props [@khromov](https://github.com/khromov) and [@tareiking](https://github.com/tareiking).
1
  === Stream ===
2
+ Contributors: lukecarbis, fjarrett, stream, xwp, kasparsd
3
  Tags: wp stream, stream, activity, logs, track
4
  Requires at least: 4.5
5
  Tested up to: 5.2
6
+ Stable tag: 3.4.2
7
  License: GPLv2 or later
8
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
9
 
87
 
88
  == Changelog ==
89
 
90
+ = 3.4.2 - September 26, 2019 =
91
+
92
+ * Fix: Visiting the plugin settings page no longer produces PHP warnings for undefined variables [#1031](https://github.com/xwp/stream/issues/1031).
93
+ * Fix: The IP address based exclude rules now stay with the same ruleset when saving [#1035](https://github.com/xwp/stream/issues/1035). Previously IP addresses would jump to the previous rule which didn't have an IP address based conditional.
94
+
95
  = 3.4.1 - July 25, 2019 =
96
 
97
  * Fix: Allow tracking cron events even when the default WordPress front-end cron runner is disabled via `DISABLE_WP_CRON`. See [#959], props [@khromov](https://github.com/khromov) and [@tareiking](https://github.com/tareiking).
stream.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Stream
4
  * Plugin URI: https://wp-stream.com/
5
  * Description: Stream tracks logged-in user activity so you can monitor every change made on your WordPress site in beautifully organized detail. All activity is organized by context, action and IP address for easy filtering. Developers can extend Stream with custom connectors to log any kind of action.
6
- * Version: 3.4.1
7
  * Author: XWP
8
  * Author URI: https://xwp.co/
9
  * License: GPLv2+
3
  * Plugin Name: Stream
4
  * Plugin URI: https://wp-stream.com/
5
  * Description: Stream tracks logged-in user activity so you can monitor every change made on your WordPress site in beautifully organized detail. All activity is organized by context, action and IP address for easy filtering. Developers can extend Stream with custom connectors to log any kind of action.
6
+ * Version: 3.4.2
7
  * Author: XWP
8
  * Author URI: https://xwp.co/
9
  * License: GPLv2+
ui/js/exclude.js CHANGED
@@ -1,10 +1,13 @@
1
  /* globals jQuery, ajaxurl, wp_stream_regenerate_alt_rows */
2
  jQuery(
3
  function( $ ) {
4
- var initSettingsSelect2 = function() {
 
 
 
5
  var $input_user;
6
 
7
- $( '.stream-exclude-list tr:not(.hidden) select.select2-select.connector_or_context' ).each(
8
  function( k, el ) {
9
  $( el ).select2(
10
  {
@@ -64,7 +67,7 @@ jQuery(
64
  }
65
  );
66
 
67
- $( '.stream-exclude-list tr:not(.hidden) select.select2-select.action' ).each(
68
  function( k, el ) {
69
  $( el ).select2(
70
  {
@@ -74,7 +77,7 @@ jQuery(
74
  }
75
  );
76
 
77
- $( '.stream-exclude-list tr:not(.hidden) select.select2-select.author_or_role' ).each(
78
  function( k, el ) {
79
  $input_user = $( el );
80
 
@@ -173,7 +176,7 @@ jQuery(
173
  }
174
  );
175
 
176
- $( '.stream-exclude-list tr:not(.hidden) select.select2-select.ip_address' ).each(
177
  function( k, el ) {
178
  var $input_ip = $( el ),
179
  searchTerm = '';
@@ -271,28 +274,30 @@ jQuery(
271
  }
272
  );
273
 
274
- $( '.stream-exclude-list tr:not(.hidden) .exclude_rules_remove_rule_row' ).on(
275
- 'click', function() {
276
  var $thisRow = $( this ).closest( 'tr' );
277
 
278
  $thisRow.remove();
279
 
280
  recalculate_rules_found();
281
  recalculate_rules_selected();
 
 
282
  }
283
  );
284
  };
285
 
286
- initSettingsSelect2();
287
 
288
- $( '.stream-exclude-list tr:not(.hidden) select.select2-select.author_or_role' ).each(
289
  function() {
290
  var $option = $( '<option selected>' + $( this ).data( 'selected-text' ) + '</option>' ).val( $( this ).data( 'selected-id' ) );
291
  $( this ).append( $option ).trigger( 'change' );
292
  }
293
  );
294
 
295
- $( '.stream-exclude-list tr:not(.hidden) select.select2-select.connector_or_context' ).each(
296
  function() {
297
  var parts = [
298
  $( this ).siblings( '.connector' ).val(),
@@ -307,25 +312,12 @@ jQuery(
307
 
308
  $( '#exclude_rules_new_rule' ).on(
309
  'click', function() {
310
- var $excludeList = $( 'table.stream-exclude-list' );
311
-
312
- $( 'tr:not(.hidden) select.select2-select', $excludeList ).each(
313
- function() {
314
- $( this ).select2( 'destroy' );
315
- }
316
- );
317
-
318
- var $lastRow = $( 'tr', $excludeList ).last(),
319
- $newRow = $lastRow.clone();
320
 
321
  $newRow.removeAttr( 'class' );
322
- $( '.stream-exclude-list tbody :input' ).off();
323
- $( ':input', $newRow ).off().val( '' );
324
-
325
- $lastRow.after( $newRow );
326
-
327
- initSettingsSelect2();
328
 
 
329
  recalculate_rules_found();
330
  recalculate_rules_selected();
331
  }
@@ -369,6 +361,12 @@ jQuery(
369
  $( '.stream-exclude-list tbody tr:not(.hidden) select.select2-select.ip_address', this ).each(
370
  function() {
371
  var firstSelected = $( 'option:selected', this ).first();
 
 
 
 
 
 
372
  $( 'option:selected:not(:first)', this ).each(
373
  function() {
374
  firstSelected.attr( 'value', firstSelected.attr( 'value' ) + ',' + $( this ).attr( 'value' ) );
1
  /* globals jQuery, ajaxurl, wp_stream_regenerate_alt_rows */
2
  jQuery(
3
  function( $ ) {
4
+ var $excludeRows = $( '.stream-exclude-list tbody tr:not(.hidden)' );
5
+ var $placeholderRow = $( '.stream-exclude-list tr.helper' );
6
+
7
+ var initSettingsSelect2 = function( $rowsWithSelect2 ) {
8
  var $input_user;
9
 
10
+ $( 'select.select2-select.connector_or_context', $rowsWithSelect2 ).each(
11
  function( k, el ) {
12
  $( el ).select2(
13
  {
67
  }
68
  );
69
 
70
+ $( 'select.select2-select.action', $rowsWithSelect2 ).each(
71
  function( k, el ) {
72
  $( el ).select2(
73
  {
77
  }
78
  );
79
 
80
+ $( 'select.select2-select.author_or_role', $rowsWithSelect2 ).each(
81
  function( k, el ) {
82
  $input_user = $( el );
83
 
176
  }
177
  );
178
 
179
+ $( 'select.select2-select.ip_address', $rowsWithSelect2 ).each(
180
  function( k, el ) {
181
  var $input_ip = $( el ),
182
  searchTerm = '';
274
  }
275
  );
276
 
277
+ $( '.exclude_rules_remove_rule_row', $rowsWithSelect2 ).on(
278
+ 'click', function( e ) {
279
  var $thisRow = $( this ).closest( 'tr' );
280
 
281
  $thisRow.remove();
282
 
283
  recalculate_rules_found();
284
  recalculate_rules_selected();
285
+
286
+ e.preventDefault();
287
  }
288
  );
289
  };
290
 
291
+ initSettingsSelect2( $excludeRows );
292
 
293
+ $( 'select.select2-select.author_or_role', $excludeRows ).each(
294
  function() {
295
  var $option = $( '<option selected>' + $( this ).data( 'selected-text' ) + '</option>' ).val( $( this ).data( 'selected-id' ) );
296
  $( this ).append( $option ).trigger( 'change' );
297
  }
298
  );
299
 
300
+ $( 'select.select2-select.connector_or_context', $excludeRows ).each(
301
  function() {
302
  var parts = [
303
  $( this ).siblings( '.connector' ).val(),
312
 
313
  $( '#exclude_rules_new_rule' ).on(
314
  'click', function() {
315
+ var $newRow = $placeholderRow.clone();
 
 
 
 
 
 
 
 
 
316
 
317
  $newRow.removeAttr( 'class' );
318
+ $newRow.insertBefore( $placeholderRow );
 
 
 
 
 
319
 
320
+ initSettingsSelect2( $newRow );
321
  recalculate_rules_found();
322
  recalculate_rules_selected();
323
  }
361
  $( '.stream-exclude-list tbody tr:not(.hidden) select.select2-select.ip_address', this ).each(
362
  function() {
363
  var firstSelected = $( 'option:selected', this ).first();
364
+
365
+ // Ugly hack to ensure we always pass an empty value or the order of rows gets messed up.
366
+ if ( ! firstSelected.length ) {
367
+ $( this ).append( '<option selected="selected"></option>' );
368
+ }
369
+
370
  $( 'option:selected:not(:first)', this ).each(
371
  function() {
372
  firstSelected.attr( 'value', firstSelected.attr( 'value' ) + ',' + $( this ).attr( 'value' ) );
ui/js/exclude.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function(e){function t(t,s){var n=e(".select2-select.action",t),l=n.val();n.empty(),n.prop("disabled",!0);var i=e("<option/>",{value:"",text:""});n.append(i);var c={action:"get_actions",connector:s};e.post(window.ajaxurl,c,function(t){var s=t.success,i=t.data;if(s){for(var c in i)if(i.hasOwnProperty(c)){var r=i[c],a=e("<option/>",{value:c,text:r});n.append(a)}n.val(l),n.prop("disabled",!1),e(document).trigger("alert-actions-updated")}})}function s(){var t=e("table.stream-exclude-list tbody tr:not( .hidden ) input.cb-select:checked"),s=e("#exclude_rules_remove_rules");0===t.length?s.prop("disabled",!0):s.prop("disabled",!1)}function n(){var t=e("table.stream-exclude-list tbody tr:not( .hidden )"),s=e("table.stream-exclude-list tbody tr.no-items"),n=e(".check-column.manage-column input.cb-select"),l=e("#exclude_rules_remove_rules");0===t.length?(s.show(),n.prop("disabled",!0),l.prop("disabled",!0)):(s.hide(),n.prop("disabled",!1)),wp_stream_regenerate_alt_rows(t)}var l=function(){var l;e(".stream-exclude-list tr:not(.hidden) select.select2-select.connector_or_context").each(function(s,n){e(n).select2({allowClear:!0,templateResult:function(t){return void 0===t.id?t.text:e(-1===t.id.indexOf("-")?'<span class="parent">'+t.text+"</span>":'<span class="child">'+t.text+"</span>")},matcher:function(t,s){var n=e.extend(!0,{},s);if(null===t.term||""===e.trim(t.term))return n;var l=t.term.toLowerCase();if(n.id=n.id.replace("blogs","sites"),n.id.toLowerCase().indexOf(l)>=0)return n;if(n.children){for(var i=n.children.length-1;i>=0;i--)-1===n.children[i].id.toLowerCase().indexOf(l)&&n.children.splice(i,1);if(n.children.length>0)return n}return null}}).on("change",function(){var s=e(this).closest("tr"),n=e(this).val();n&&0<n.indexOf("-")&&(n=n.split("-")[0]),t(s,n)})}),e(".stream-exclude-list tr:not(.hidden) select.select2-select.action").each(function(t,s){e(s).select2({allowClear:!0})}),e(".stream-exclude-list tr:not(.hidden) select.select2-select.author_or_role").each(function(t,s){(l=e(s)).select2({ajax:{type:"POST",url:ajaxurl,dataType:"json",quietMillis:500,data:function(e,t){return{find:e,limit:10,pager:t,action:"stream_get_users",nonce:l.data("nonce")}},processResults:function(t){var s={results:[{text:"",id:""},{text:"Roles",children:[]},{text:"Users",children:[]}]};if(!0!==t.success||void 0===t.data||!0!==t.data.status)return s;if(void 0===t.data.users||void 0===t.data.roles)return s;var n=[];return e.each(t.data.roles,function(e,t){n.push({id:e,text:t})}),s.results[1].children=n,s.results[2].children=t.data.users,s}},templateResult:function(t){var s=e("<div>").text(t.text);return void 0!==t.icon&&t.icon&&(s.prepend(e('<img src="'+t.icon+'" class="wp-stream-select2-icon">')),s.attr("title",t.tooltip)),void 0!==t.tooltip?s.attr("title",t.tooltip):void 0!==t.user_count&&s.attr("title",t.user_count),s},templateSelection:function(t){var s=e("<div>").text(t.text);return e.isNumeric(t.id)&&t.text.indexOf("icon-users")<0&&s.append(e('<i class="icon16 icon-users"></i>')),s},allowClear:!0,placeholder:l.data("placeholder")}).on("change",function(){var t=e(this).select2("data");e(this).data("selected-id",t.id),e(this).data("selected-text",t.text)})}),e(".stream-exclude-list tr:not(.hidden) select.select2-select.ip_address").each(function(t,s){var n=e(s),l="";n.select2({ajax:{type:"POST",url:ajaxurl,dataType:"json",quietMillis:500,data:function(e){return l=e.term,{find:e,limit:10,action:"stream_get_ips",nonce:n.data("nonce")}},processResults:function(t){var s={results:[]},n=[];return!0===t.success&&void 0!==t.data&&e.each(t.data,function(e,t){s.results.push({id:t,text:t})}),void 0===l?s:null===(n=l.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/))?s:(n.shift(),(n=e.grep(n,function(e){var t=parseInt(e,10);return t<=255&&t.toString()===e})).length>=4&&s.results.push({id:l,text:l}),s)}},allowClear:!1,multiple:!0,maximumSelectionSize:1,placeholder:n.data("placeholder"),tags:!0})}).on("change",function(){e(this).prev(".select2-container").find("input.select2-input").blur()}),e("ul.select2-choices, ul.select2-choices li, input.select2-input",".stream-exclude-list tr:not(.hidden) .ip_address").on("mousedown click focus",function(){var t=e(this).closest(".select2-container"),s=t.find("input.select2-input");if(t.select2("data").length>=1)return s.blur(),!1}),e(".stream-exclude-list tr:not(.hidden) .exclude_rules_remove_rule_row").on("click",function(){e(this).closest("tr").remove(),n(),s()})};l(),e(".stream-exclude-list tr:not(.hidden) select.select2-select.author_or_role").each(function(){var t=e("<option selected>"+e(this).data("selected-text")+"</option>").val(e(this).data("selected-id"));e(this).append(t).trigger("change")}),e(".stream-exclude-list tr:not(.hidden) select.select2-select.connector_or_context").each(function(){var t=[e(this).siblings(".connector").val(),e(this).siblings(".context").val()];""===t[1]&&t.splice(1,1),e(this).val(t.join("-")).trigger("change")}),e("#exclude_rules_new_rule").on("click",function(){var t=e("table.stream-exclude-list");e("tr:not(.hidden) select.select2-select",t).each(function(){e(this).select2("destroy")});var i=e("tr",t).last(),c=i.clone();c.removeAttr("class"),e(".stream-exclude-list tbody :input").off(),e(":input",c).off().val(""),i.after(c),l(),n(),s()}),e("#exclude_rules_remove_rules").on("click",function(){var t=e("table.stream-exclude-list"),l=e("tbody input.cb-select:checked",t).closest("tr");e("tbody tr",t).length-l.length>=2?l.remove():(e(":input",l).val(""),e(l).not(":first").remove(),e(".select2-select",l).select2("val","")),t.find("input.cb-select").prop("checked",!1),n(),s()}),e(".stream-exclude-list").closest("form").submit(function(){e(".stream-exclude-list tbody tr.hidden",this).each(function(){e(this).find(":input").removeAttr("name")}),e(".stream-exclude-list tbody tr:not(.hidden) select.select2-select.connector_or_context",this).each(function(){var t=e(this).val().split("-");e(this).siblings(".connector").val(t[0]),e(this).siblings(".context").val(t[1]),e(this).removeAttr("name")}),e(".stream-exclude-list tbody tr:not(.hidden) select.select2-select.ip_address",this).each(function(){var t=e("option:selected",this).first();e("option:selected:not(:first)",this).each(function(){t.attr("value",t.attr("value")+","+e(this).attr("value")),e(this).removeAttr("selected")})})}),e(".stream-exclude-list").closest("td").prev("th").hide(),e("table.stream-exclude-list").on("click","input.cb-select",function(){s()}),e(document).ready(function(){n(),s()})});
1
+ jQuery(function(e){function t(t,s){var n=e(".select2-select.action",t),i=n.val();n.empty(),n.prop("disabled",!0);var l=e("<option/>",{value:"",text:""});n.append(l);var c={action:"get_actions",connector:s};e.post(window.ajaxurl,c,function(t){var s=t.success,l=t.data;if(s){for(var c in l)if(l.hasOwnProperty(c)){var r=l[c],a=e("<option/>",{value:c,text:r});n.append(a)}n.val(i),n.prop("disabled",!1),e(document).trigger("alert-actions-updated")}})}function s(){var t=e("table.stream-exclude-list tbody tr:not( .hidden ) input.cb-select:checked"),s=e("#exclude_rules_remove_rules");0===t.length?s.prop("disabled",!0):s.prop("disabled",!1)}function n(){var t=e("table.stream-exclude-list tbody tr:not( .hidden )"),s=e("table.stream-exclude-list tbody tr.no-items"),n=e(".check-column.manage-column input.cb-select"),i=e("#exclude_rules_remove_rules");0===t.length?(s.show(),n.prop("disabled",!0),i.prop("disabled",!0)):(s.hide(),n.prop("disabled",!1)),wp_stream_regenerate_alt_rows(t)}var i=e(".stream-exclude-list tbody tr:not(.hidden)"),l=e(".stream-exclude-list tr.helper"),c=function(i){var l;e("select.select2-select.connector_or_context",i).each(function(s,n){e(n).select2({allowClear:!0,templateResult:function(t){return void 0===t.id?t.text:e(-1===t.id.indexOf("-")?'<span class="parent">'+t.text+"</span>":'<span class="child">'+t.text+"</span>")},matcher:function(t,s){var n=e.extend(!0,{},s);if(null===t.term||""===e.trim(t.term))return n;var i=t.term.toLowerCase();if(n.id=n.id.replace("blogs","sites"),n.id.toLowerCase().indexOf(i)>=0)return n;if(n.children){for(var l=n.children.length-1;l>=0;l--)-1===n.children[l].id.toLowerCase().indexOf(i)&&n.children.splice(l,1);if(n.children.length>0)return n}return null}}).on("change",function(){var s=e(this).closest("tr"),n=e(this).val();n&&0<n.indexOf("-")&&(n=n.split("-")[0]),t(s,n)})}),e("select.select2-select.action",i).each(function(t,s){e(s).select2({allowClear:!0})}),e("select.select2-select.author_or_role",i).each(function(t,s){(l=e(s)).select2({ajax:{type:"POST",url:ajaxurl,dataType:"json",quietMillis:500,data:function(e,t){return{find:e,limit:10,pager:t,action:"stream_get_users",nonce:l.data("nonce")}},processResults:function(t){var s={results:[{text:"",id:""},{text:"Roles",children:[]},{text:"Users",children:[]}]};if(!0!==t.success||void 0===t.data||!0!==t.data.status)return s;if(void 0===t.data.users||void 0===t.data.roles)return s;var n=[];return e.each(t.data.roles,function(e,t){n.push({id:e,text:t})}),s.results[1].children=n,s.results[2].children=t.data.users,s}},templateResult:function(t){var s=e("<div>").text(t.text);return void 0!==t.icon&&t.icon&&(s.prepend(e('<img src="'+t.icon+'" class="wp-stream-select2-icon">')),s.attr("title",t.tooltip)),void 0!==t.tooltip?s.attr("title",t.tooltip):void 0!==t.user_count&&s.attr("title",t.user_count),s},templateSelection:function(t){var s=e("<div>").text(t.text);return e.isNumeric(t.id)&&t.text.indexOf("icon-users")<0&&s.append(e('<i class="icon16 icon-users"></i>')),s},allowClear:!0,placeholder:l.data("placeholder")}).on("change",function(){var t=e(this).select2("data");e(this).data("selected-id",t.id),e(this).data("selected-text",t.text)})}),e("select.select2-select.ip_address",i).each(function(t,s){var n=e(s),i="";n.select2({ajax:{type:"POST",url:ajaxurl,dataType:"json",quietMillis:500,data:function(e){return i=e.term,{find:e,limit:10,action:"stream_get_ips",nonce:n.data("nonce")}},processResults:function(t){var s={results:[]},n=[];return!0===t.success&&void 0!==t.data&&e.each(t.data,function(e,t){s.results.push({id:t,text:t})}),void 0===i?s:null===(n=i.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/))?s:(n.shift(),(n=e.grep(n,function(e){var t=parseInt(e,10);return t<=255&&t.toString()===e})).length>=4&&s.results.push({id:i,text:i}),s)}},allowClear:!1,multiple:!0,maximumSelectionSize:1,placeholder:n.data("placeholder"),tags:!0})}).on("change",function(){e(this).prev(".select2-container").find("input.select2-input").blur()}),e("ul.select2-choices, ul.select2-choices li, input.select2-input",".stream-exclude-list tr:not(.hidden) .ip_address").on("mousedown click focus",function(){var t=e(this).closest(".select2-container"),s=t.find("input.select2-input");if(t.select2("data").length>=1)return s.blur(),!1}),e(".exclude_rules_remove_rule_row",i).on("click",function(t){e(this).closest("tr").remove(),n(),s(),t.preventDefault()})};c(i),e("select.select2-select.author_or_role",i).each(function(){var t=e("<option selected>"+e(this).data("selected-text")+"</option>").val(e(this).data("selected-id"));e(this).append(t).trigger("change")}),e("select.select2-select.connector_or_context",i).each(function(){var t=[e(this).siblings(".connector").val(),e(this).siblings(".context").val()];""===t[1]&&t.splice(1,1),e(this).val(t.join("-")).trigger("change")}),e("#exclude_rules_new_rule").on("click",function(){var e=l.clone();e.removeAttr("class"),e.insertBefore(l),c(e),n(),s()}),e("#exclude_rules_remove_rules").on("click",function(){var t=e("table.stream-exclude-list"),i=e("tbody input.cb-select:checked",t).closest("tr");e("tbody tr",t).length-i.length>=2?i.remove():(e(":input",i).val(""),e(i).not(":first").remove(),e(".select2-select",i).select2("val","")),t.find("input.cb-select").prop("checked",!1),n(),s()}),e(".stream-exclude-list").closest("form").submit(function(){e(".stream-exclude-list tbody tr.hidden",this).each(function(){e(this).find(":input").removeAttr("name")}),e(".stream-exclude-list tbody tr:not(.hidden) select.select2-select.connector_or_context",this).each(function(){var t=e(this).val().split("-");e(this).siblings(".connector").val(t[0]),e(this).siblings(".context").val(t[1]),e(this).removeAttr("name")}),e(".stream-exclude-list tbody tr:not(.hidden) select.select2-select.ip_address",this).each(function(){var t=e("option:selected",this).first();t.length||e(this).append('<option selected="selected"></option>'),e("option:selected:not(:first)",this).each(function(){t.attr("value",t.attr("value")+","+e(this).attr("value")),e(this).removeAttr("selected")})})}),e(".stream-exclude-list").closest("td").prev("th").hide(),e("table.stream-exclude-list").on("click","input.cb-select",function(){s()}),e(document).ready(function(){n(),s()})});