Skip to content

Commit

Permalink
Release version 3.4.2 (#1037)
Browse files Browse the repository at this point in the history
  • Loading branch information
kasparsd authored Sep 26, 2019
1 parent fac6064 commit d3c596e
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 90 deletions.
140 changes: 85 additions & 55 deletions classes/class-log.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ function ( $var ) {
* @return bool
*/
public function is_record_excluded( $connector, $context, $action, $user = null, $ip = null ) {
$exclude_record = false;

if ( is_null( $user ) ) {
$user = wp_get_current_user();
}
Expand Down Expand Up @@ -191,64 +193,25 @@ public function is_record_excluded( $connector, $context, $action, $user = null,
$exclude_settings = isset( $this->plugin->settings->options['exclude_rules'] ) ? $this->plugin->settings->options['exclude_rules'] : array();

if ( is_multisite() && $this->plugin->is_network_activated() && ! is_network_admin() ) {
$multisite_options = (array) get_site_option( 'wp_stream_network', array() );
$multisite_exclude_settings = isset( $multisite_options['exclude_rules'] ) ? $multisite_options['exclude_rules'] : array();

if ( ! empty( $multisite_exclude_settings ) ) {
foreach ( $multisite_exclude_settings['exclude_row'] as $key => $rule ) {
$exclude_settings['exclude_row'][] = $multisite_exclude_settings['exclude_row'][ $key ];
$exclude_settings['author_or_role'][] = $multisite_exclude_settings['author_or_role'][ $key ];
$exclude_settings['connector'][] = $multisite_exclude_settings['connector'][ $key ];
$exclude_settings['context'][] = $multisite_exclude_settings['context'][ $key ];
$exclude_settings['action'][] = $multisite_exclude_settings['action'][ $key ];
$exclude_settings['ip_address'][] = $multisite_exclude_settings['ip_address'][ $key ];
}
}
$multisite_options = (array) get_site_option( 'wp_stream_network', array() );
$exclude_settings = isset( $multisite_options['exclude_rules'] ) ? $multisite_options['exclude_rules'] : array();
}

$exclude_record = false;
foreach ( $this->exclude_rules_by_rows( $exclude_settings ) as $exclude_rule ) {
$exclude = array(
'connector' => ! empty( $exclude_rule['connector'] ) ? $exclude_rule['connector'] : null,
'context' => ! empty( $exclude_rule['context'] ) ? $exclude_rule['context'] : null,
'action' => ! empty( $exclude_rule['action'] ) ? $exclude_rule['action'] : null,
'ip_address' => ! empty( $exclude_rule['ip_address'] ) ? $exclude_rule['ip_address'] : null,
'author' => is_numeric( $exclude_rule['author_or_role'] ) ? absint( $exclude_rule['author_or_role'] ) : null,
'role' => ( ! empty( $exclude_rule['author_or_role'] ) && ! is_numeric( $exclude_rule['author_or_role'] ) ) ? $exclude_rule['author_or_role'] : null,
);

if ( isset( $exclude_settings['exclude_row'] ) && ! empty( $exclude_settings['exclude_row'] ) ) {
foreach ( $exclude_settings['exclude_row'] as $key => $value ) {
// Prepare values.
$author_or_role = isset( $exclude_settings['author_or_role'][ $key ] ) ? $exclude_settings['author_or_role'][ $key ] : '';
$connector = isset( $exclude_settings['connector'][ $key ] ) ? $exclude_settings['connector'][ $key ] : '';
$context = isset( $exclude_settings['context'][ $key ] ) ? $exclude_settings['context'][ $key ] : '';
$action = isset( $exclude_settings['action'][ $key ] ) ? $exclude_settings['action'][ $key ] : '';
$ip_address = isset( $exclude_settings['ip_address'][ $key ] ) ? $exclude_settings['ip_address'][ $key ] : '';

$exclude = array(
'connector' => ! empty( $connector ) ? $connector : null,
'context' => ! empty( $context ) ? $context : null,
'action' => ! empty( $action ) ? $action : null,
'ip_address' => ! empty( $ip_address ) ? $ip_address : null,
'author' => is_numeric( $author_or_role ) ? absint( $author_or_role ) : null,
'role' => ( ! empty( $author_or_role ) && ! is_numeric( $author_or_role ) ) ? $author_or_role : null,
);

$exclude_rules = array_filter( $exclude, 'strlen' );

if ( ! empty( $exclude_rules ) ) {
$matches_exclusion_rule = true;

foreach ( $exclude_rules as $exclude_key => $exclude_value ) {
if ( 'ip_address' === $exclude_key ) {
$ip_addresses = explode( ',', $exclude_value );
if ( ! in_array( $record['ip_address'], $ip_addresses, true ) ) {
$matches_exclusion_rule = false;
break;
}
} elseif ( $record[ $exclude_key ] !== $exclude_value ) {
$matches_exclusion_rule = false;
break;
}
}

if ( $matches_exclusion_rule ) {
$exclude_record = true;
break;
}
}
$exclude_rules = array_filter( $exclude, 'strlen' );

if ( $this->record_matches_rules( $record, $exclude_rules ) ) {
$exclude_record = true;
break;
}
}

Expand All @@ -265,6 +228,73 @@ public function is_record_excluded( $connector, $context, $action, $user = null,
return apply_filters( 'wp_stream_is_record_excluded', $exclude_record, $record );
}

/**
* Check if a record to stored matches certain rules.
*
* @param array $record List of record parameters.
* @param array $exclude_rules List of record exclude rules.
*
* @return boolean
*/
public function record_matches_rules( $record, $exclude_rules ) {
foreach ( $exclude_rules as $exclude_key => $exclude_value ) {
if ( ! isset( $record[ $exclude_key ] ) ) {
continue;
}

if ( 'ip_address' === $exclude_key ) {
$ip_addresses = explode( ',', $exclude_value );

if ( in_array( $record['ip_address'], $ip_addresses, true ) ) {
return true;
}
} elseif ( $record[ $exclude_key ] === $exclude_value ) {
return true;
}
}

return false;
}

/**
* Get all exclude rules by row because we store them by rule instead.
*
* @param array $rules List of rules indexed by rule ID.
*
* @return array
*/
public function exclude_rules_by_rows( $rules ) {
$excludes = array();

// TODO: Move these to where the settings are generated to ensure they're in sync.
$rule_keys = array(
'exclude_row',
'author_or_role',
'connector',
'context',
'action',
'ip_address',
);

if ( empty( $rules['exclude_row'] ) ) {
return array();
}

foreach ( array_keys( $rules['exclude_row'] ) as $row_id ) {
$excludes[ $row_id ] = array();

foreach ( $rule_keys as $rule_key ) {
if ( isset( $rules[ $rule_key ][ $row_id ] ) ) {
$excludes[ $row_id ][ $rule_key ] = $rules[ $rule_key ][ $row_id ];
} else {
$excludes[ $row_id ][ $rule_key ] = null;
}
}
}

return $excludes;
}

/**
* Helper function to send a full backtrace of calls to the PHP error log for debugging
*
Expand Down
2 changes: 1 addition & 1 deletion classes/class-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class Plugin {
*
* @const string
*/
const VERSION = '3.4.1';
const VERSION = '3.4.2';

/**
* WP-CLI command
Expand Down
13 changes: 9 additions & 4 deletions classes/class-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 ] ) );
}
}
}
Expand Down Expand Up @@ -842,8 +842,13 @@ public function render_field( $field ) {

$exclude_rows = array();

// Account for when no rules have been added yet.
if ( ! is_array( $current_value ) ) {
$current_value = 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.
Expand Down
9 changes: 7 additions & 2 deletions readme.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
=== Stream ===
Contributors: lukecarbis, fjarrett, stream, xwp
Contributors: lukecarbis, fjarrett, stream, xwp, kasparsd
Tags: wp stream, stream, activity, logs, track
Requires at least: 4.5
Tested up to: 5.2
Stable tag: 3.4.1
Stable tag: 3.4.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Expand Down Expand Up @@ -87,6 +87,11 @@ Thank you for wanting to make Stream better for everyone!

== Changelog ==

= 3.4.2 - September 26, 2019 =

* Fix: Visiting the plugin settings page no longer produces PHP warnings for undefined variables [#1031](https://github.com/xwp/stream/issues/1031).
* 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.

= 3.4.1 - July 25, 2019 =

* 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).
Expand Down
2 changes: 1 addition & 1 deletion stream.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: Stream
* Plugin URI: https://wp-stream.com/
* 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.
* Version: 3.4.1
* Version: 3.4.2
* Author: XWP
* Author URI: https://xwp.co/
* License: GPLv2+
Expand Down
99 changes: 98 additions & 1 deletion tests/tests/test-class-log.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,103 @@ public function test_field_lengths() {
// Test action length

// Test IP length


}

public function test_can_map_exclude_rules_settings_to_rows() {
$rules_settings = array(
'exclude_row' => array(
null,
null,
),
'action' => array(
'one',
null,
'three'
)
);

$this->assertEquals(
array(
array(
'exclude_row' => null,
'action' => 'one',
'author_or_role' => null,
'connector' => null,
'context' => null,
'ip_address' => null,
),
array(
'exclude_row' => null,
'action' => null,
'author_or_role' => null,
'connector' => null,
'context' => null,
'ip_address' => null,
)
),
$this->plugin->log->exclude_rules_by_rows( $rules_settings )
);
}

public function test_can_match_record_exclude() {
$rules = array(
'action' => 'mega_action',
);

$this->assertTrue(
$this->plugin->log->record_matches_rules(
array(
'action' => 'mega_action',
'ip_address' => '1.1.1.1',
),
$rules
),
'Record action is the same'
);

$this->assertFalse(
$this->plugin->log->record_matches_rules(
array(
'action' => 'different_action',
),
$rules
),
'Record action is different'
);
}

public function test_can_match_record_id_address() {
$this->assertFalse(
$this->plugin->log->record_matches_rules(
array(
'ip_address' => '1.1.1.1',
),
array(
'ip_address' => '8.8.8.8',
)
),
'Record IP address is different'
);

$this->assertTrue( $this->plugin->log->record_matches_rules(
array(
'ip_address' => '1.1.1.1',
),
array(
'ip_address' => '1.1.1.1',
),
'Record and rule IP addresses match'
) );

$this->assertTrue( $this->plugin->log->record_matches_rules(
array(
'ip_address' => '1.1.1.1',
),
array(
'ip_address' => '8.8.8.8,1.1.1.1',
),
'Record IP address is one of the IP addresses in the rule'
) );
}
}
Loading

0 comments on commit d3c596e

Please sign in to comment.