9 Commits

7 changed files with 204 additions and 46 deletions

View File

@ -1,8 +1,8 @@
# Statify Blacklist #
* Contributors: Stefan Kalscheuer
* Requires at least: 3.9
* Tested up to: 4.6
* Stable tag: 1.2.0
* Tested up to: 4.7
* Stable tag: 1.3.1
* License: GPLv3 or later
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
@ -32,8 +32,8 @@ The plugin is capable of handling multisite installations.
* Goto _Settings_ -> _Statify Blacklist_ to configure the plugin
### Requirements ###
* PHP 5.2.4
* WordPress 3.9
* PHP 5.2.4 or above
* WordPress 3.9 or above
* Statify plugin installed and activated (tested up to 1.4.3)
## Frequently Asked Questions ##
@ -55,15 +55,25 @@ If this still is an issue for you, consider deactivating the filter and only run
No. The privacy policy of _Statify_ is untouched. Data is only processed, not stored or exposed to anyone.
### Are regular expression filters possible? ###
Not for now. At the moment it's only a simple domain filter, as regular expression matching is significantly slower.
Yes, it it. Just select if you want to filter using regular expressions case sensitive or insensitive.
If you like to have this feature, please leave a feature request in GitHub or the WordPress support forum.
Note, that regular expression matching is significantly slower than the plain domain filter. Hence it is only recommended for asynchronous cron or manual execution and not for live filtering.
## Screenshots ##
1. Statify Blacklist settings page
## Changelog ##
### 1.3.1 / 09.12.2016 ###
* Continue filtering if no filter applies (#6)
### 1.3.0 / 17.10.2016 ###
* Regular expressions filtering implemented
### 1.2.1 / 10.10.2016 ###
* Fix live filter configuration check
### 1.2.0 / 29.08.2016 ###
* Switched from `in_array()` to faster `isset()` for referer checking
* Optional cron execiton implemented
@ -78,4 +88,4 @@ If you like to have this feature, please leave a feature request in GitHub or th
* One-time execution on database
### 1.0.0 / 14.08.2016 ###
* First release
* First release

View File

@ -38,7 +38,7 @@ class StatifyBlacklist {
* Class constructor
*
* @since 1.0.0
* @changed 1.1.2
* @changed 1.2.1
*/
public function __construct() {
/* Skip on autosave or AJAX */
@ -53,7 +53,7 @@ class StatifyBlacklist {
self::$multisite = ( is_multisite() && array_key_exists( STATIFYBLACKLIST_BASE, (array) get_site_option( 'active_sitewide_plugins' ) ) );
/* Add Filter to statify hook if enabled */
if ( self::$_options['active_referer'] != 1 ) {
if ( self::$_options['active_referer'] != 0 ) {
add_filter( 'statify_skip_tracking', array( 'StatifyBlacklist', 'apply_blacklist_filter' ) );
}
@ -101,7 +101,8 @@ class StatifyBlacklist {
array(
'active_referer' => 0,
'cron_referer' => 0,
'referer' => array()
'referer' => array(),
'referer_regexp' => 0
)
);
}
@ -112,28 +113,34 @@ class StatifyBlacklist {
* @return TRUE if referer matches blacklist.
*
* @since 1.0.0
* @changed 1.2.0
* @changed 1.3.1
*/
public static function apply_blacklist_filter() {
/* Skip if blacklist is inactive */
if ( self::$_options['active_referer'] != 1 ) {
return false;
return NULL;
}
/* Extract relevant domain parts */
$referer = strtolower( ( isset( $_SERVER['HTTP_REFERER'] ) ? parse_url( $_SERVER['HTTP_REFERER'], PHP_URL_HOST ) : '' ) );
$referer = explode( '.', $referer );
// if ( count( $referer ) > 1 ) {
// $referer = implode( '.', array_slice( $referer, - 2 ) );
// } else {
$referer = implode( '.', $referer );
// }
/* Regular Expression filtering since 1.3.0 */
if ( isset(self::$_options['referer_regexp']) && self::$_options['referer_regexp'] > 0 ) {
/* Get full referer string */
$referer = ( isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : '' );
/* Merge given regular expressions into one */
$regexp = '/' . implode( "|", array_keys( self::$_options['referer'] ) ) . '/';
if ( self::$_options['referer_regexp'] == 2 ) {
$regexp .= 'i';
}
/* Check blacklist (return NULL to continue filtering) */
return (preg_match( $regexp, $referer) === 1) ? true : NULL;
} else {
/* Extract relevant domain parts */
$referer = strtolower( ( isset( $_SERVER['HTTP_REFERER'] ) ? parse_url( $_SERVER['HTTP_REFERER'], PHP_URL_HOST ) : '' ) );
/* Get blacklist */
$blacklist = self::$_options['referer'];
/* Get blacklist */
$blacklist = self::$_options['referer'];
/* Check blacklist */
return isset( $blacklist[ $referer ] );
/* Check blacklist (return NULL to continue filtering) */
return isset($blacklist[ $referer]) ? true : NULL;
}
}
}

View File

@ -15,12 +15,16 @@ class StatifyBlacklist_Admin extends StatifyBlacklist {
* @param $options array New options to save
* @return mixed array of sanitized array on errors, FALSE if there were none
* @since 1.1.1
* @changed 1.3.0
*/
public static function update_options( $options = null ) {
if ( isset( $options ) && current_user_can( 'manage_options' ) ) {
/* Sanitize URLs and remove empty inputs */
$givenReferer = $options['referer'];
$sanitizedReferer = self::sanitizeURLs( $givenReferer );
if ($options['referer_regexp'] == 0)
$sanitizedReferer = self::sanitizeURLs( $givenReferer );
else
$sanitizedReferer = $givenReferer;
/* Abort on errors */
if ( ! empty( array_diff( $givenReferer, $sanitizedReferer ) ) ) {
@ -110,7 +114,7 @@ class StatifyBlacklist_Admin extends StatifyBlacklist {
* Filter database for cleanup.
*
* @since 1.1.0
* @changed 1.2.0
* @changed 1.3.0
*/
public static function cleanup_database() {
/* Check user permissions */
@ -120,22 +124,30 @@ class StatifyBlacklist_Admin extends StatifyBlacklist {
global $wpdb;
/* Sanitize URLs */
$referer = self::sanitizeURLs( self::$_options['referer'] );
if ( isset( self::$_options['referer_regexp'] ) && self::$_options['referer_regexp'] > 0 ) {
/* Merge given regular expressions into one */
$refererRegexp = implode( "|", array_keys( self::$_options['referer'] ) );
} else {
/* Sanitize URLs */
$referer = self::sanitizeURLs( self::$_options['referer'] );
/* Build filter regexp */
$refererRegexp = str_replace( '.', '\.', implode( '|', array_flip( $referer ) ) );
}
/* Build filter regexp */
$refererRegexp = str_replace( '.', '\.', implode( '|', array_flip( $referer ) ) );
if ( ! empty( $refererRegexp ) ) {
/* Execute filter on database */
$wpdb->query(
$wpdb->prepare( "DELETE FROM `$wpdb->statify` WHERE referrer REGEXP %s", $refererRegexp )
$wpdb->prepare( "DELETE FROM `$wpdb->statify` WHERE "
. ( ( self::$_options['referer_regexp'] == 1 ) ? " BINARY " : "" )
. "referrer REGEXP %s", $refererRegexp )
);
/* Optimize DB */
$wpdb->query( "OPTIMIZE TABLE `$wpdb->statify`" );
/* Delete transient statify data */
delete_transient('statify_data');
delete_transient( 'statify_data' );
}
}

View File

@ -9,6 +9,9 @@ defined( 'ABSPATH' ) OR exit;
* @since 1.0.0
*/
class StatifyBlacklist_System extends StatifyBlacklist {
const VERSION_MAIN = 1.3;
/**
* Plugin install handler.
*
@ -77,10 +80,8 @@ class StatifyBlacklist_System extends StatifyBlacklist {
/**
* Upgrade plugin options.
*
* @param object $upgrader Upgrader object (unused)
* @param array $options Options array
*
* @since 1.2.0
* @since 1.2.0
* @changed 1.3.0
*/
public static function upgrade() {
self::update_options();
@ -95,5 +96,19 @@ class StatifyBlacklist_System extends StatifyBlacklist {
update_option( 'statify-blacklist', $options );
}
}
/* Check if version is set (not before 1.3.0) */
if ( ! isset( self::$_options['version'] ) ) {
$options = self::$_options;
/* Set version */
$options['version'] = self::VERSION_MAIN;
/* Add regular expression option (as of 1.3) */
$options['referer_regexp'] = 0;
if ( ( is_multisite() && array_key_exists( STATIFYBLACKLIST_BASE, (array) get_site_option( 'active_sitewide_plugins' ) ) ) ) {
update_site_option( 'statify-blacklist', $options );
} else {
update_option( 'statify-blacklist', $options );
}
}
}
}

View File

@ -8,7 +8,7 @@ Author: Stefan Kalscheuer
Author URI: https://stklcode.de
Plugin URI: https://wordpress.org/plugins/statify-blacklist
License: GPLv3 or later
Version: 1.2.0
Version: 1.3.1
*/
/* Quit */
@ -26,7 +26,7 @@ register_activation_hook( STATIFYBLACKLIST_FILE, array( 'StatifyBlacklist_System
register_uninstall_hook( STATIFYBLACKLIST_FILE, array( 'StatifyBlacklist_System', 'uninstall' ) );
/* Upgrade hook to v1.2.0 */
/* Upgrade hook */
register_activation_hook( STATIFYBLACKLIST_FILE, array( 'StatifyBlacklist_System', 'upgrade' ) );
/* Autoload */

View File

@ -0,0 +1,95 @@
<?php
const ABSPATH = false;
require_once( '../inc/statifyblacklist.class.php' );
/**
* Class StatifyBlacklistTest
*
* PHPUnit test class for StatifyBlacklist
*/
class StatifyBlacklistTest extends PHPUnit_Framework_TestCase {
public function testFilter() {
/* Prepare Options: 2 blacklisted domains, disabled */
StatifyBlacklist::$_options = array(
'active_referer' => 0,
'cron_referer' => 0,
'referer' => array(
'example.com' => 0,
'example.net' => 1
)
);
/* No multisite */
StatifyBlacklist::$multisite = false;
/* No referer */
unset( $_SERVER['HTTP_REFERER'] );
$this->assertFalse( StatifyBlacklist::apply_blacklist_filter() );
/* Non-blacklisted referer */
$_SERVER['HTTP_REFERER'] = 'http://example.org';
$this->assertFalse( StatifyBlacklist::apply_blacklist_filter() );
/* Blacklisted referer */
$_SERVER['HTTP_REFERER'] = 'http://example.com';
$this->assertFalse( StatifyBlacklist::apply_blacklist_filter() );
/* Blacklisted referer with path */
$_SERVER['HTTP_REFERER'] = 'http://example.net/foo/bar.html';
$this->assertFalse( StatifyBlacklist::apply_blacklist_filter() );
/* Activate filter and run tests again */
StatifyBlacklist::$_options['active_referer'] = 1;
unset( $_SERVER['HTTP_REFERER'] );
$this->assertFalse( StatifyBlacklist::apply_blacklist_filter() );
$_SERVER['HTTP_REFERER'] = 'http://example.org';
$this->assertFalse( StatifyBlacklist::apply_blacklist_filter() );
$_SERVER['HTTP_REFERER'] = 'http://example.com';
$this->assertTrue( StatifyBlacklist::apply_blacklist_filter() );
$_SERVER['HTTP_REFERER'] = 'http://example.net/foo/bar.html';
$this->assertTrue( StatifyBlacklist::apply_blacklist_filter() );
}
public function testRegexFilter() {
/* Prepare Options: 2 regular expressions */
StatifyBlacklist::$_options = array(
'active_referer' => 1,
'cron_referer' => 0,
'referer' => array(
'example.[a-z]+' => 0,
'test' => 1
),
'referer_regexp' => 1
);
/* No multisite */
StatifyBlacklist::$multisite = false;
/* No referer */
unset( $_SERVER['HTTP_REFERER'] );
$this->assertFalse( StatifyBlacklist::apply_blacklist_filter() );
/* Non-blacklisted referer */
$_SERVER['HTTP_REFERER'] = 'http://not.evil';
$this->assertFalse( StatifyBlacklist::apply_blacklist_filter() );
/* Blacklisted referer */
$_SERVER['HTTP_REFERER'] = 'http://example.com';
$this->assertTrue( StatifyBlacklist::apply_blacklist_filter() );
/* Blacklisted referer with path */
$_SERVER['HTTP_REFERER'] = 'http://foobar.net/test/me';
$this->assertTrue( StatifyBlacklist::apply_blacklist_filter() );
/* Matching both */
$_SERVER['HTTP_REFERER'] = 'http://example.net/test/me';
$this->assertTrue( StatifyBlacklist::apply_blacklist_filter() );
/* Mathinc with wrong case */
$_SERVER['HTTP_REFERER'] = 'http://eXaMpLe.NeT/tEsT/mE';
$this->assertFalse( StatifyBlacklist::apply_blacklist_filter() );
/* Set RegExp filter to case insensitive */
StatifyBlacklist::$_options['referer_regexp'] = 2;
$this->assertTrue( StatifyBlacklist::apply_blacklist_filter() );
}
}

View File

@ -29,7 +29,8 @@ if ( ! empty( $_POST['statifyblacklist'] ) ) {
array(
'active_referer' => (int) @$_POST['statifyblacklist']['active_referer'],
'cron_referer' => (int) @$_POST['statifyblacklist']['cron_referer'],
'referer' => array_flip( $referer )
'referer' => array_flip( $referer ),
'referer_regexp' => (int) @$_POST['statifyblacklist']['referer_regexp']
)
);
@ -79,6 +80,24 @@ if ( ! empty( $_POST['statifyblacklist'] ) ) {
<small>(<?php esc_html_e( 'Clean database periodically in background', 'statify-blacklist' ); ?>)</small>
</label>
</li>
<li>
<label for="statify-blacklist_referer_regexp">
<?php esc_html_e( 'Use regular expressions', 'statify-blacklist' ); ?>:
<br />
<select name="statifyblacklist[referer_regexp]" id="statifyblacklist_referer_regexp">
<option value="0" <?php selected( StatifyBlacklist::$_options['referer_regexp'], 0 ); ?>>
<?php esc_html_e( 'Disabled', 'statify-blacklist' ); ?>
</option>
<option value="1" <?php selected( StatifyBlacklist::$_options['referer_regexp'], 1 ); ?>>
<?php esc_html_e( 'Case-sensitive', 'statify-blacklist' ); ?>
</option>
<option value="2" <?php selected( StatifyBlacklist::$_options['referer_regexp'], 2 ); ?>>
<?php esc_html_e( 'Case-insensitive', 'statify-blacklist' ); ?>
</option>
</select>
<small>(<?php esc_html_e( 'Performance slower than standard domain filter. Recommended for cron or manual execition only.', 'statify-blacklist' ); ?>)</small>
</label>
</li>
<li>
<label for="statify-blacklist_referer">
<?php esc_html_e( 'Referer blacklist:', 'statify-blacklist' ); ?><br/>
@ -101,12 +120,12 @@ if ( ! empty( $_POST['statifyblacklist'] ) ) {
<p class="submit">
<input class="button-primary" type="submit" name="submit" value="<?php _e( 'Save Changes' ) ?>">
<hr />
<input class="button-secondary" type="submit" name="cleanUp"
value="<?php esc_html_e( 'CleanUp Database', 'statify-blacklist' ) ?>"
onclick="return confirm('Do you really want to apply filters to database? This cannot be undone.');">
<br />
<small><?php esc_html_e( 'Applies filter (even if disabled) to data stored in database. This cannot be undone!', 'statify-blacklist' ); ?></small>
<hr />
<input class="button-secondary" type="submit" name="cleanUp"
value="<?php esc_html_e( 'CleanUp Database', 'statify-blacklist' ) ?>"
onclick="return confirm('Do you really want to apply filters to database? This cannot be undone.');">
<br />
<small><?php esc_html_e( 'Applies filter (even if disabled) to data stored in database. This cannot be undone!', 'statify-blacklist' ); ?></small>
</p>
</form>
</div>