diff --git a/classes/class-settings.php b/classes/class-settings.php index 94f1f694a..25ef23ef7 100644 --- a/classes/class-settings.php +++ b/classes/class-settings.php @@ -551,12 +551,12 @@ public function sanitize_settings( $input ) { // Support all values in multidimentional arrays too. array_walk_recursive( $output[ $name ], - function ( &$v, $k ) { - $v = trim( $v ); + function ( &$v ) { + $v = sanitize_text_field( trim( $v ) ); } ); } else { - $output[ $name ] = trim( $input[ $name ] ); + $output[ $name ] = sanitize_text_field( trim( $input[ $name ] ) ); } } } @@ -843,7 +843,7 @@ public function render_field( $field ) { $exclude_rows = array(); // Prepend an empty row. - $current_value['exclude_row'] = array( 'helper' => '' ) + ( isset( $current_value['exclude_row'] ) ? $current_value['exclude_row'] : array() ); + $current_value['exclude_row'] = ( isset( $current_value['exclude_row'] ) ? $current_value['exclude_row'] : array() ) + array( 'helper' => '' ); foreach ( $current_value['exclude_row'] as $key => $value ) { // Prepare values. diff --git a/ui/js/exclude.js b/ui/js/exclude.js index 1b6416f90..d74d33ed0 100644 --- a/ui/js/exclude.js +++ b/ui/js/exclude.js @@ -1,10 +1,13 @@ /* globals jQuery, ajaxurl, wp_stream_regenerate_alt_rows */ jQuery( function( $ ) { - var initSettingsSelect2 = function() { + var $excludeRows = $( '.stream-exclude-list tbody tr:not(.hidden)' ); + var $placeholderRow = $( '.stream-exclude-list tr.helper' ); + + var initSettingsSelect2 = function( $rowsWithSelect2 ) { var $input_user; - $( '.stream-exclude-list tr:not(.hidden) select.select2-select.connector_or_context' ).each( + $( 'select.select2-select.connector_or_context', $rowsWithSelect2 ).each( function( k, el ) { $( el ).select2( { @@ -64,7 +67,7 @@ jQuery( } ); - $( '.stream-exclude-list tr:not(.hidden) select.select2-select.action' ).each( + $( 'select.select2-select.action', $rowsWithSelect2 ).each( function( k, el ) { $( el ).select2( { @@ -74,7 +77,7 @@ jQuery( } ); - $( '.stream-exclude-list tr:not(.hidden) select.select2-select.author_or_role' ).each( + $( 'select.select2-select.author_or_role', $rowsWithSelect2 ).each( function( k, el ) { $input_user = $( el ); @@ -173,7 +176,7 @@ jQuery( } ); - $( '.stream-exclude-list tr:not(.hidden) select.select2-select.ip_address' ).each( + $( 'select.select2-select.ip_address', $rowsWithSelect2 ).each( function( k, el ) { var $input_ip = $( el ), searchTerm = ''; @@ -271,7 +274,7 @@ jQuery( } ); - $( '.stream-exclude-list tr:not(.hidden) .exclude_rules_remove_rule_row' ).on( + $( '.exclude_rules_remove_rule_row', $rowsWithSelect2 ).on( 'click', function() { var $thisRow = $( this ).closest( 'tr' ); @@ -283,16 +286,16 @@ jQuery( ); }; - initSettingsSelect2(); + initSettingsSelect2( $excludeRows ); - $( '.stream-exclude-list tr:not(.hidden) select.select2-select.author_or_role' ).each( + $( 'select.select2-select.author_or_role', $excludeRows ).each( function() { var $option = $( '' ).val( $( this ).data( 'selected-id' ) ); $( this ).append( $option ).trigger( 'change' ); } ); - $( '.stream-exclude-list tr:not(.hidden) select.select2-select.connector_or_context' ).each( + $( 'select.select2-select.connector_or_context', $excludeRows ).each( function() { var parts = [ $( this ).siblings( '.connector' ).val(), @@ -307,25 +310,12 @@ jQuery( $( '#exclude_rules_new_rule' ).on( 'click', function() { - var $excludeList = $( 'table.stream-exclude-list' ); - - $( 'tr:not(.hidden) select.select2-select', $excludeList ).each( - function() { - $( this ).select2( 'destroy' ); - } - ); - - var $lastRow = $( 'tr', $excludeList ).last(), - $newRow = $lastRow.clone(); + var $newRow = $placeholderRow.clone(); $newRow.removeAttr( 'class' ); - $( '.stream-exclude-list tbody :input' ).off(); - $( ':input', $newRow ).off().val( '' ); - - $lastRow.after( $newRow ); - - initSettingsSelect2(); + $newRow.insertBefore( $placeholderRow ); + initSettingsSelect2( $newRow ); recalculate_rules_found(); recalculate_rules_selected(); } @@ -369,6 +359,12 @@ jQuery( $( '.stream-exclude-list tbody tr:not(.hidden) select.select2-select.ip_address', this ).each( function() { var firstSelected = $( 'option:selected', this ).first(); + + // Ugly hack to ensure we always pass an empty value or the order of rows gets messed up. + if ( ! firstSelected.length ) { + $( this ).append( '' ); + } + $( 'option:selected:not(:first)', this ).each( function() { firstSelected.attr( 'value', firstSelected.attr( 'value' ) + ',' + $( this ).attr( 'value' ) );