reduce redundancies for recurring matching loops
Referer, target and user agent filter share most of their logic for different matching methods. We introduce a common routine for all of them to not repeat ourselves. Passing a value extractor by reference allows lazy evaluation (filter might be disabled) and overrides for different cases (i.e. domain extractor for exact match).
This commit is contained in:
parent
a6cc821089
commit
f424909515
@ -177,87 +177,21 @@ class StatifyBlacklist {
|
|||||||
*/
|
*/
|
||||||
public static function apply_blacklist_filter() {
|
public static function apply_blacklist_filter() {
|
||||||
// Referer filter.
|
// Referer filter.
|
||||||
if ( isset( self::$options['referer']['active'] ) && 0 !== self::$options['referer']['active'] ) {
|
if (
|
||||||
// Determine filter mode.
|
self::apply_single_filter(
|
||||||
$mode = isset( self::$options['referer']['regexp'] ) ? intval( self::$options['referer']['regexp'] ) : 0;
|
self::$options['referer'],
|
||||||
|
array(
|
||||||
// Get full referer string.
|
__CLASS__,
|
||||||
$referer = wp_get_raw_referer();
|
( ! isset( self::$options['referer']['regexp'] ) || self::MODE_NORMAL === self::$options['referer']['regexp'] ) ? 'get_referer_domain' : 'get_referer',
|
||||||
if ( ! $referer ) {
|
)
|
||||||
$referer = '';
|
)
|
||||||
}
|
) {
|
||||||
|
return true;
|
||||||
switch ( $mode ) {
|
|
||||||
|
|
||||||
// Regular Expression filtering since 1.3.0.
|
|
||||||
case self::MODE_REGEX:
|
|
||||||
case self::MODE_REGEX_CI:
|
|
||||||
// Merge given regular expressions into one.
|
|
||||||
$regexp = self::regex(
|
|
||||||
array_keys( self::$options['referer']['blacklist'] ),
|
|
||||||
self::MODE_REGEX_CI === self::$options['referer']['regexp']
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check filter (no return to continue filtering #12).
|
|
||||||
if ( 1 === preg_match( $regexp, $referer ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Keyword filter since 1.5.0 (#15).
|
|
||||||
case self::MODE_KEYWORD:
|
|
||||||
// Get filter.
|
|
||||||
$blacklist = self::$options['referer']['blacklist'];
|
|
||||||
|
|
||||||
foreach ( array_keys( $blacklist ) as $keyword ) {
|
|
||||||
if ( false !== strpos( strtolower( $referer ), strtolower( $keyword ) ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Standard domain filter.
|
|
||||||
default:
|
|
||||||
// Extract relevant domain parts.
|
|
||||||
$referer = wp_parse_url( $referer );
|
|
||||||
$referer = strtolower( ( isset( $referer['host'] ) ? $referer['host'] : '' ) );
|
|
||||||
|
|
||||||
// Get filter.
|
|
||||||
$blacklist = self::$options['referer']['blacklist'];
|
|
||||||
|
|
||||||
// Check filter.
|
|
||||||
if ( isset( $blacklist[ $referer ] ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Target filter (since 1.4.0).
|
// Target filter (since 1.4.0).
|
||||||
if ( isset( self::$options['target']['active'] ) && 0 !== self::$options['target']['active'] ) {
|
if ( self::apply_single_filter( self::$options['target'], array( __CLASS__, 'get_target' ) ) ) {
|
||||||
// Regular Expression filtering since 1.3.0.
|
return true;
|
||||||
if ( isset( self::$options['target']['regexp'] ) && 0 < self::$options['target']['regexp'] ) {
|
|
||||||
// Get full referer string.
|
|
||||||
$target = ( isset( $_SERVER['REQUEST_URI'] ) ? filter_var( wp_unslash( $_SERVER['REQUEST_URI'] ), FILTER_SANITIZE_URL ) : '/' );
|
|
||||||
// Merge given regular expressions into one.
|
|
||||||
$regexp = self::regex(
|
|
||||||
array_keys( self::$options['target']['blacklist'] ),
|
|
||||||
self::MODE_REGEX_CI === self::$options['target']['regexp']
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check filter (no return to continue filtering #12).
|
|
||||||
if ( 1 === preg_match( $regexp, $target ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Extract target page.
|
|
||||||
$target = ( isset( $_SERVER['REQUEST_URI'] ) ? filter_var( wp_unslash( $_SERVER['REQUEST_URI'] ), FILTER_SANITIZE_URL ) : '/' );
|
|
||||||
// Get filter.
|
|
||||||
$blacklist = self::$options['target']['blacklist'];
|
|
||||||
// Check filter.
|
|
||||||
if ( isset( $blacklist[ $target ] ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IP filter (since 1.4.0).
|
// IP filter (since 1.4.0).
|
||||||
@ -273,62 +207,72 @@ class StatifyBlacklist {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// User agent filter (since 1.6).
|
// User agent filter (since 1.6).
|
||||||
if ( isset( self::$options['ua']['active'] ) && 0 !== self::$options['ua']['active'] ) {
|
if ( self::apply_single_filter( self::$options['ua'], array( __CLASS__, 'get_user_agent' ) ) ) {
|
||||||
// Determine filter mode.
|
return true;
|
||||||
$mode = isset( self::$options['ua']['regexp'] ) ? intval( self::$options['ua']['regexp'] ) : 0;
|
|
||||||
|
|
||||||
// Get full user agent string.
|
|
||||||
if ( ! empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
|
|
||||||
$user_agent = filter_var( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ), FILTER_SANITIZE_STRING );
|
|
||||||
|
|
||||||
if ( $user_agent ) {
|
|
||||||
switch ( $mode ) {
|
|
||||||
|
|
||||||
// Regular Expression filtering since 1.3.0.
|
|
||||||
case self::MODE_REGEX:
|
|
||||||
case self::MODE_REGEX_CI:
|
|
||||||
// Merge given regular expressions into one.
|
|
||||||
$regexp = self::regex(
|
|
||||||
array_keys( self::$options['ua']['blacklist'] ),
|
|
||||||
self::MODE_REGEX_CI === self::$options['ua']['regexp']
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check filter (no return to continue filtering #12).
|
|
||||||
if ( 1 === preg_match( $regexp, $user_agent ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Keyword filter since 1.5.0 (#15).
|
|
||||||
case self::MODE_KEYWORD:
|
|
||||||
// Get filter.
|
|
||||||
$blacklist = self::$options['ua']['blacklist'];
|
|
||||||
|
|
||||||
foreach ( array_keys( $blacklist ) as $keyword ) {
|
|
||||||
if ( false !== strpos( strtolower( $user_agent ), strtolower( $keyword ) ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Standard exact filter.
|
|
||||||
default:
|
|
||||||
// Get filter.
|
|
||||||
$blacklist = self::$options['ua']['blacklist'];
|
|
||||||
|
|
||||||
// Check filter.
|
|
||||||
if ( isset( $blacklist[ $user_agent ] ) ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip and continue (return NULL), if all filters are inactive.
|
// Skip and continue (return NULL), if all filters are inactive.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a single filter, if active.
|
||||||
|
*
|
||||||
|
* @param array $config Configuration array from plugin options.
|
||||||
|
* @param callable $value_fn Extractor function for filterable value.
|
||||||
|
*
|
||||||
|
* @return bool TRUE if referer matches filter.
|
||||||
|
*
|
||||||
|
* @since 1.6 Extracted from "apply_blacklist_filter" to reduce redundancies.
|
||||||
|
*/
|
||||||
|
private static function apply_single_filter( $config, $value_fn ) {
|
||||||
|
// Is the filter active?
|
||||||
|
if ( ! isset( $config['active'] ) || 0 === $config['active'] ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the filterable value.
|
||||||
|
$value = call_user_func( $value_fn );
|
||||||
|
|
||||||
|
$mode = isset( $config['regexp'] ) ? intval( $config['regexp'] ) : self::MODE_NORMAL;
|
||||||
|
|
||||||
|
switch ( $mode ) {
|
||||||
|
case self::MODE_REGEX:
|
||||||
|
case self::MODE_REGEX_CI:
|
||||||
|
// Regular Expression filtering since 1.3.0.
|
||||||
|
|
||||||
|
// Merge given regular expressions into one.
|
||||||
|
$regexp = self::regex(
|
||||||
|
array_keys( $config['blacklist'] ),
|
||||||
|
self::MODE_REGEX_CI === $config['regexp']
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check filter (no return to continue filtering #12).
|
||||||
|
if ( 1 === preg_match( $regexp, $value ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case self::MODE_KEYWORD:
|
||||||
|
// Keyword filter since 1.5.0 (#15).
|
||||||
|
foreach ( array_keys( $config['blacklist'] ) as $keyword ) {
|
||||||
|
if ( false !== strpos( strtolower( $value ), strtolower( $keyword ) ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Standard exact filter.
|
||||||
|
if ( isset( $config['blacklist'][ $value ] ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preprocess regular expression provided by the user, i.e. add delimiters and optional ci flag.
|
* Preprocess regular expression provided by the user, i.e. add delimiters and optional ci flag.
|
||||||
*
|
*
|
||||||
@ -360,6 +304,47 @@ class StatifyBlacklist {
|
|||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to determine the client's referer.
|
||||||
|
*
|
||||||
|
* @return string The referer.
|
||||||
|
*/
|
||||||
|
private static function get_referer() {
|
||||||
|
$referer = wp_get_raw_referer();
|
||||||
|
if ( ! $referer ) {
|
||||||
|
$referer = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $referer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to determine the host part of the client's referer.
|
||||||
|
*
|
||||||
|
* @return string Referer domain.
|
||||||
|
*/
|
||||||
|
private static function get_referer_domain() {
|
||||||
|
$referer = wp_parse_url( self::get_referer() );
|
||||||
|
|
||||||
|
return strtolower( ( isset( $referer['host'] ) ? $referer['host'] : '' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to determine the client's referer.
|
||||||
|
*
|
||||||
|
* @return string The referer.
|
||||||
|
*/
|
||||||
|
private static function get_target() {
|
||||||
|
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
|
||||||
|
$target = filter_var( wp_unslash( $_SERVER['REQUEST_URI'] ), FILTER_SANITIZE_URL );
|
||||||
|
if ( $target ) {
|
||||||
|
return $target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to determine the client's IP address.
|
* Helper method to determine the client's IP address.
|
||||||
*
|
*
|
||||||
@ -396,6 +381,22 @@ class StatifyBlacklist {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to determine the user agent.
|
||||||
|
*
|
||||||
|
* @return string The user agent string.
|
||||||
|
*/
|
||||||
|
private static function get_user_agent() {
|
||||||
|
if ( ! empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
|
||||||
|
$user_agent = filter_var( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ), FILTER_SANITIZE_STRING );
|
||||||
|
if ( $user_agent ) {
|
||||||
|
return $user_agent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to check if an IP address matches a given subnet.
|
* Helper function to check if an IP address matches a given subnet.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user