Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release version 3.4.2 #1037

Merged
merged 22 commits into from
Sep 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c32c989
Always allow tracking CRON runs (#1029)
kasparsd Jul 25, 2019
73cf9b1
Merge remote-tracking branch 'origin/master' into develop
kasparsd Sep 23, 2019
04c75a8
Fix IP address based exclude rule matching (#1034)
kasparsd Sep 26, 2019
07eb979
Bump select2 to 4.0.10
kasparsd Sep 26, 2019
9761670
Bump the version strings too
kasparsd Sep 26, 2019
99b219d
Skip header and footer rows which don’t have select enabled
kasparsd Sep 26, 2019
ef2862d
Pass the targets for re-usability instead
kasparsd Sep 26, 2019
3c112cb
Revert "Bump the version strings too"
kasparsd Sep 26, 2019
0497e96
Simplify the overrides
kasparsd Sep 26, 2019
2607a05
Revert "Bump select2 to 4.0.10"
kasparsd Sep 26, 2019
6431dde
Sanitize as strings by default
kasparsd Sep 26, 2019
20fd91e
Ugly hack to ensure we always pass an empty value or the order of row…
kasparsd Sep 26, 2019
5a0f238
Add the placeholder row at the bottom since we want new rows there
kasparsd Sep 26, 2019
8c28e46
Skip the default anchor jump
kasparsd Sep 26, 2019
9915fa5
Fix IP exclude rules settings (#1036)
kasparsd Sep 26, 2019
cc04ac4
Merge branch 'fix/1035-exclude-rules-table' of github.com:xwp/stream …
kasparsd Sep 26, 2019
3cede5e
Bump version to 3.4.2
kasparsd Sep 26, 2019
4c11a4e
Bump another version string
kasparsd Sep 26, 2019
d344bad
Add changelog
kasparsd Sep 26, 2019
6e9e6cf
Formatting
kasparsd Sep 26, 2019
6f454cf
Include an additional IP address to ensure it doesn’t mess with the r…
kasparsd Sep 26, 2019
f3c2396
Add me as a contributor
kasparsd Sep 26, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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