Spider Blocker - Version v1.2.5

Version Description

  • Visual fixes and code clean-up
  • Added support for LiteSpeed server
Download this release

Release Info

Developer niteoweb
Plugin Icon 128x128 Spider Blocker
Version v1.2.5
Comparing to
See all releases

Code changes from version v1.2.0 to v1.2.5

Files changed (4) hide show
  1. i18n/spiderblocker.pot +74 -55
  2. inc/templates/settings.php +134 -0
  3. index.php +434 -304
  4. readme.txt +6 -2
i18n/spiderblocker.pot CHANGED
@@ -2,20 +2,20 @@
2
  # This file is distributed under the same license as the Spider Blocker plugin.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Spider Blocker 1.2.0\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/src\n"
7
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
  "Language-Team: LANGUAGE <LL@li.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "POT-Creation-Date: 2020-01-13T09:39:59+05:30\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
- "X-Generator: WP-CLI 2.3.0\n"
15
  "X-Domain: spiderblocker\n"
16
 
17
  #. Plugin Name of the plugin
18
- #: index.php:752
19
  msgid "Spider Blocker"
20
  msgstr ""
21
 
@@ -31,97 +31,116 @@ msgstr ""
31
  msgid "www.easyblognetworks.com"
32
  msgstr ""
33
 
34
- #: index.php:41
35
- msgid ""
36
- "This plugin requires PHP 5.6.0 or higher. Please contact your hosting provider about upgrading your\n"
37
- "\t\t\tserver software. Your PHP version is"
38
  msgstr ""
39
 
40
- #: index.php:374
41
- msgid "SpiderBlocker plugin has enabled blocking of some bots, please review settings by visiting"
 
 
42
  msgstr ""
43
 
44
- #: index.php:374
45
- msgid "Setting page"
46
  msgstr ""
47
 
48
- #: index.php:399
49
- msgid "This plugin requires Apache2 server with mod_rewrite support. Please contact your hosting provider about upgrading your server software. Your Apache version is"
50
  msgstr ""
51
 
52
- #: index.php:413
53
- msgid "%1$s %2$s %3$s"
54
  msgstr ""
55
 
56
- #: index.php:414
57
- msgid "This plugin requires"
58
  msgstr ""
59
 
60
- #: index.php:416
61
- msgid "file that is writable by the server. Please enable write access for file"
62
  msgstr ""
63
 
64
- #: index.php:574
65
- msgid "Failed parsing JSON"
 
66
  msgstr ""
67
 
68
- #: index.php:588
69
- msgid "Unable to process the request as no data has been received."
 
70
  msgstr ""
71
 
72
- #: index.php:766
73
- msgid "Add New Bot"
 
74
  msgstr ""
75
 
76
- #: index.php:772
77
- #: index.php:800
78
- #: index.php:812
79
- msgid "User Agent"
80
  msgstr ""
81
 
82
- #: index.php:776
83
- msgid "Bot Name"
84
  msgstr ""
85
 
86
- #: index.php:781
87
- msgid "Bot Description URL"
88
  msgstr ""
89
 
90
- #: index.php:788
91
- msgid "Add Bot"
92
  msgstr ""
93
 
94
- #: index.php:791
95
- msgid "List of bots"
96
  msgstr ""
97
 
98
- #: index.php:793
99
- msgid "Filter..."
100
  msgstr ""
101
 
102
- #: index.php:802
103
- #: index.php:813
104
- msgid "Name"
105
  msgstr ""
106
 
107
- #: index.php:804
108
- #: index.php:814
109
- msgid "State"
110
  msgstr ""
111
 
112
- #: index.php:806
113
- #: index.php:816
114
- msgid "Action"
115
  msgstr ""
116
 
117
- #: index.php:841
118
- msgid "Save"
119
  msgstr ""
120
 
121
- #: index.php:842
122
- msgid "Reset to Defaults"
 
123
  msgstr ""
124
 
125
- #: index.php:843
126
- msgid "Import/Export Definitions"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  msgstr ""
2
  # This file is distributed under the same license as the Spider Blocker plugin.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Spider Blocker 1.2.5\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/src\n"
7
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
  "Language-Team: LANGUAGE <LL@li.org>\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2020-07-20T15:38:48+05:30\n"
13
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
+ "X-Generator: WP-CLI 2.4.0\n"
15
  "X-Domain: spiderblocker\n"
16
 
17
  #. Plugin Name of the plugin
18
+ #: inc/templates/settings.php:14
19
  msgid "Spider Blocker"
20
  msgstr ""
21
 
31
  msgid "www.easyblognetworks.com"
32
  msgstr ""
33
 
34
+ #: inc/templates/settings.php:29
35
+ msgid "Add New Bot"
 
 
36
  msgstr ""
37
 
38
+ #: inc/templates/settings.php:35
39
+ #: inc/templates/settings.php:69
40
+ #: inc/templates/settings.php:90
41
+ msgid "User Agent"
42
  msgstr ""
43
 
44
+ #: inc/templates/settings.php:39
45
+ msgid "Bot Name"
46
  msgstr ""
47
 
48
+ #: inc/templates/settings.php:44
49
+ msgid "Bot Description URL"
50
  msgstr ""
51
 
52
+ #: inc/templates/settings.php:52
53
+ msgid "Add Bot"
54
  msgstr ""
55
 
56
+ #: inc/templates/settings.php:57
57
+ msgid "List of bots"
58
  msgstr ""
59
 
60
+ #: inc/templates/settings.php:60
61
+ msgid "Filter..."
62
  msgstr ""
63
 
64
+ #: inc/templates/settings.php:73
65
+ #: inc/templates/settings.php:94
66
+ msgid "Name"
67
  msgstr ""
68
 
69
+ #: inc/templates/settings.php:77
70
+ #: inc/templates/settings.php:98
71
+ msgid "State"
72
  msgstr ""
73
 
74
+ #: inc/templates/settings.php:81
75
+ #: inc/templates/settings.php:102
76
+ msgid "Action"
77
  msgstr ""
78
 
79
+ #: inc/templates/settings.php:115
80
+ msgid "Block"
 
 
81
  msgstr ""
82
 
83
+ #: inc/templates/settings.php:116
84
+ msgid "Allow"
85
  msgstr ""
86
 
87
+ #: inc/templates/settings.php:117
88
+ msgid "Remove"
89
  msgstr ""
90
 
91
+ #: inc/templates/settings.php:128
92
+ msgid "Save"
93
  msgstr ""
94
 
95
+ #: inc/templates/settings.php:129
96
+ msgid "Reset to Defaults"
97
  msgstr ""
98
 
99
+ #: inc/templates/settings.php:130
100
+ msgid "Import/Export Definitions"
101
  msgstr ""
102
 
103
+ #: index.php:352
104
+ msgid "%s requires Apache2 server with mod_rewrite support. Please contact your hosting provider about upgrading your server software."
 
105
  msgstr ""
106
 
107
+ #: index.php:365
108
+ msgid "%s requires .htaccess file that is writable by the server. Please enable write access for the file."
 
109
  msgstr ""
110
 
111
+ #: index.php:382
112
+ msgid "%1$s requires WordPress version %2$s or higher. Please %3$supdate WordPress &raquo;%4$s"
 
113
  msgstr ""
114
 
115
+ #: index.php:397
116
+ msgid "%1$s plugin has enabled blocking of some bots, please review settings by visiting %2$sSettings page%3$s!"
117
  msgstr ""
118
 
119
+ #: index.php:599
120
+ #: index.php:604
121
+ msgid "Unable to process the request as no data has been received."
122
  msgstr ""
123
 
124
+ #: index.php:611
125
+ msgid "Failed parsing JSON data."
126
+ msgstr ""
127
+
128
+ #: index.php:678
129
+ msgid "List of bots was saved and new blocklist applied!"
130
+ msgstr ""
131
+
132
+ #: index.php:679
133
+ msgid "List of bots was reset to defaults!"
134
+ msgstr ""
135
+
136
+ #: index.php:680
137
+ msgid "Bot"
138
+ msgstr ""
139
+
140
+ #: index.php:681
141
+ msgid "was added!"
142
+ msgstr ""
143
+
144
+ #: index.php:682
145
+ msgid "Bot was removed!"
146
  msgstr ""
inc/templates/settings.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * View for plugin settings panel.
5
+ */
6
+
7
+ if ( ! defined( 'ABSPATH' ) ) {
8
+ exit;
9
+ }
10
+
11
+ ?>
12
+
13
+ <div class="spiderblocker-root">
14
+ <h1><?php esc_html_e( 'Spider Blocker', 'spiderblocker' ); ?></h1>
15
+ <hr/>
16
+
17
+ <div ng-app="spiderBlockApp">
18
+ <div ng-controller="NotificationsCtrl">
19
+ <div class="notice notice-{{ n.state }} fixed" ng-repeat="n in notifications" style="top: {{3.5*($index+1)}}em">
20
+ <p>{{n.msg}}
21
+ <a ng-click="removeNotification(notification)">
22
+ <span class="dashicons dashicons-no-alt"></span>
23
+ </a>
24
+ </p>
25
+ </div>
26
+ </div>
27
+
28
+ <div ng-controller="BotListCtrl">
29
+ <h2><?php esc_html_e( 'Add New Bot', 'spiderblocker' ); ?></h2>
30
+
31
+ <form name="add_form" ng-submit="add()">
32
+ <table class="form-table">
33
+ <tbody>
34
+ <tr>
35
+ <th scope="row"><label><?php esc_html_e( 'User Agent', 'spiderblocker' ); ?></label></th>
36
+ <td><input type="text" bots="bots" ng-model='bot.re' class="regular-text" required/></td>
37
+ </tr>
38
+ <tr>
39
+ <th scope="row"><label><?php esc_html_e( 'Bot Name', 'spiderblocker' ); ?></label></th>
40
+ <td><input type="text" ng-model='bot.name' class="regular-text" required/></td>
41
+ </tr>
42
+ <tr>
43
+ <tr>
44
+ <th scope="row"><label><?php esc_html_e( 'Bot Description URL', 'spiderblocker' ); ?></label></th>
45
+ <td><input type="url" ng-model='bot.desc' class="regular-text" placeholder="http://"/>
46
+ </td>
47
+ </tr>
48
+ </tbody>
49
+ </table>
50
+
51
+ <p class="submit">
52
+ <input ng-disabled="add_form.$invalid" type="submit" class="button button-primary" value="<?php esc_attr_e( 'Add Bot', 'spiderblocker' ); ?>">
53
+ </p>
54
+ </form>
55
+
56
+ <div class="sb-table-top">
57
+ <h2><?php esc_html_e( 'List of bots', 'spiderblocker' ); ?></h2>
58
+
59
+ <ng-form class="search-box">
60
+ <input size="35" type="search" id="ua-search-input" ng-model="query" placeholder="<?php esc_attr_e( 'Filter...', 'spiderblocker' ); ?>">
61
+ </ng-form>
62
+ </div><!-- .sb-table-top -->
63
+
64
+ <table class="wp-list-table widefat bots">
65
+ <thead>
66
+ <tr>
67
+ <th scope="col" class="manage-column column-description">
68
+ <a href="" ng-click="predicate = 're'; reverse=false">
69
+ <?php esc_html_e( 'User Agent', 'spiderblocker' ); ?> <span class="dashicons dashicons-sort"></span>
70
+ </a>
71
+ </th>
72
+ <th scope="col" class="manage-column column-name">
73
+ <?php esc_html_e( 'Name', 'spiderblocker' ); ?>
74
+ </th>
75
+ <th scope="col" class="manage-column column-state">
76
+ <a href="" ng-click="predicate = 'state'; reverse=false">
77
+ <?php esc_html_e( 'State', 'spiderblocker' ); ?> <span class="dashicons dashicons-sort"></span>
78
+ </a>
79
+ </th>
80
+ <th scope="col" id="action" class="manage-column column-action">
81
+ <?php esc_html_e( 'Action', 'spiderblocker' ); ?>
82
+ </th>
83
+ </tr>
84
+ </thead>
85
+
86
+ <tfoot>
87
+ <tr>
88
+ <th scope="col" class="manage-column column-description">
89
+ <a href="" ng-click="predicate = 're'; reverse=false">
90
+ <?php esc_html_e( 'User Agent', 'spiderblocker' ); ?>
91
+ </a>
92
+ </th>
93
+ <th scope="col" class="manage-column column-name">
94
+ <?php esc_html_e( 'Name', 'spiderblocker' ); ?>
95
+ </th>
96
+ <th scope="col" class="manage-column column-state">
97
+ <a href="" ng-click="predicate = 'state'; reverse=false">
98
+ <?php esc_html_e( 'State', 'spiderblocker' ); ?>
99
+ </a>
100
+ </th>
101
+ <th scope="col" id="action" class="manage-column column-action">
102
+ <?php esc_html_e( 'Action', 'spiderblocker' ); ?>
103
+ </th>
104
+ </tr>
105
+ </tfoot>
106
+
107
+ <tbody id="the-list">
108
+ <tr id="spider-blocker" ng-repeat="bot in bots | filter:query | orderBy:predicate:reverse"
109
+ ng-class="{'active': bot.state}">
110
+
111
+ <th class="bot-re"> {{ bot.re }}</th>
112
+ <td class="bot-title"><strong>{{ bot.name }}</strong> <a target="_blank" ng-href="{{bot.desc}}">{{ bot.desc }}</a></td>
113
+ <th class="expression" ng-class="{'blocked':bot.state}"> {{ bot.state?"Blocked":"Allowed" }}</th>
114
+ <td class="actions">
115
+ <input ng-hide="bot.state" type="button" ng-click="bot.state=true" class="button button-primary" value="<?php esc_attr_e( 'Block', 'spiderblocker' ); ?>">
116
+ <input ng-show="bot.state" type="button" ng-click="bot.state=false" class="button button-secondary" value="<?php esc_attr_e( 'Allow', 'spiderblocker' ); ?>">
117
+ <input type="button" ng-click="remove(bot.re)" class="button button-secondary" value="<?php esc_attr_e( 'Remove', 'spiderblocker' ); ?>">
118
+ </td>
119
+ </tr>
120
+ </tbody>
121
+ </table>
122
+
123
+ <div id="rules-export-import" style="display:none;">
124
+ <textarea style="-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;width: 100%;height: 99%;" json-text ng-model="bots"></textarea>
125
+ </div>
126
+
127
+ <p class="submit">
128
+ <input type="button" class="button button-primary" ng-click="save()" value="<?php esc_attr_e( 'Save', 'spiderblocker' ); ?>">
129
+ <input type="button" class="button button-primary" ng-click="reset()" value="<?php esc_attr_e( 'Reset to Defaults', 'spiderblocker' ); ?>">
130
+ <a href="#TB_inline?width=540&height=360&inlineId=rules-export-import" class="thickbox button button-secondary"><?php esc_html_e( 'Import/Export Definitions', 'spiderblocker' ); ?></a>
131
+ </p>
132
+ </div>
133
+ </div>
134
+ </div><!-- .spiderblocker-root -->
index.php CHANGED
@@ -5,7 +5,7 @@ namespace Niteoweb\SpiderBlocker;
5
  /**
6
  * Plugin Name: Spider Blocker
7
  * Description: Spider Blocker will block most common bots that consume bandwidth and slow down your server.
8
- * Version: 1.2.0
9
  * Runtime: 5.6+
10
  * Author: Easy Blog Networks
11
  * Text Domain: spiderblocker
@@ -13,43 +13,6 @@ namespace Niteoweb\SpiderBlocker;
13
  * Author URI: www.easyblognetworks.com
14
  */
15
 
16
- if ( ! function_exists( 'apache_get_version' ) ) {
17
- /**
18
- * Fetch the Apache version.
19
- *
20
- * @return string|false
21
- */
22
- function apache_get_version() {
23
- if ( stristr( $_ENV['SERVER_SOFTWARE'], 'Apache' ) ) {
24
- return sanitize_text_field( $_ENV['SERVER_SOFTWARE'] );
25
- }
26
- if ( stristr( $_SERVER['SERVER_SOFTWARE'], 'Apache' ) ) {
27
- return sanitize_text_field( $_SERVER['SERVER_SOFTWARE'] );
28
- }
29
- return false;
30
- }
31
- }
32
-
33
- /**
34
- * Checks for PHP version and stop the plugin if the version is < 5.6.0.
35
- */
36
- if ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
37
- ?>
38
- <div id="error-page">
39
- <p>
40
- <?php
41
- esc_html_e(
42
- 'This plugin requires PHP 5.6.0 or higher. Please contact your hosting provider about upgrading your
43
- server software. Your PHP version is',
44
- 'spiderblocker'
45
- );
46
- ?>
47
- <b><?php echo sanitize_text_field( PHP_VERSION ); ?></b></p>
48
- </div>
49
- <?php
50
- die();
51
- }
52
-
53
  /**
54
  * Spiderblocker class where all the action happens.
55
  *
@@ -58,9 +21,50 @@ if ( version_compare( PHP_VERSION, '5.6.0', '<' ) ) {
58
  */
59
  class SpiderBlocker {
60
 
61
- const OPTIONNAME = 'Niteoweb.SpiderBlocker.Bots';
62
- const NONCE = 'Niteoweb.SpiderBlocker.Nonce';
63
- const CHECKHOOK = 'Niteoweb.SpiderBlocker.CheckHook';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
  /**
66
  * Bots which can be blocked by the spiderblocker plugin
@@ -308,18 +312,134 @@ class SpiderBlocker {
308
  * Class Constructor.
309
  */
310
  public function __construct() {
311
- if ( is_admin() ) {
312
- add_action( 'admin_notices', array( &$this, 'activate_plugin_notice' ) );
313
- add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
314
- add_action( 'wp_ajax_NSB-get_list', array( &$this, 'load_list' ) );
315
- add_action( 'wp_ajax_NSB-set_list', array( &$this, 'save_list' ) );
316
- add_action( 'wp_ajax_NSB-reset_list', array( &$this, 'reset_list' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  }
318
 
319
- // Filter for Robots file.
320
- add_filter( 'robots_txt', array( &$this, 'robots_file' ), ~PHP_INT_MAX, 2 );
321
- add_action( 'generate_rewrite_rules', array( &$this, 'generate_rewrite_rules' ) );
322
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  }
324
 
325
  /**
@@ -337,9 +457,8 @@ class SpiderBlocker {
337
  * Fetch Plugin URL.
338
  *
339
  * @return string
340
- * @codeCoverageIgnore
341
  */
342
- private function plugin_url() {
343
  $url = wp_make_link_relative( plugin_dir_url( __FILE__ ) );
344
  $url = ltrim( $url, '/' );
345
 
@@ -361,22 +480,6 @@ class SpiderBlocker {
361
  add_action( 'load-' . $menu, array( &$this, 'view_handler_load' ) );
362
  }
363
 
364
- /**
365
- * Admin notice which gets fired on plugin activation.
366
- *
367
- * @codeCoverageIgnore
368
- */
369
- public function activate_plugin_notice() {
370
- if ( get_option( self::OPTIONNAME ) === false ) {
371
- update_option( self::OPTIONNAME, $this->default_bots );
372
- ?>
373
- <div class="notice notice-success">
374
- <p><?php esc_html_e( 'SpiderBlocker plugin has enabled blocking of some bots, please review settings by visiting', 'spiderblocker' ); ?> <a href="<?php echo esc_url( admin_url( 'tools.php?page=ni_spider_block' ) ); ?>"><?php esc_html_e( 'Setting page', 'spiderblocker' ); ?></a>!</p>
375
- </div>
376
- <?php
377
- }
378
- }
379
-
380
  /**
381
  * Generate block rules when the download process for a plugin
382
  * install or update finishes.
@@ -393,80 +496,7 @@ class SpiderBlocker {
393
  * @codeCoverageIgnore
394
  */
395
  public function activate_plugin() {
396
- if ( ! apache_get_version() ) {
397
- ?>
398
- <div id="error-page">
399
- <p><?php esc_html_e( 'This plugin requires Apache2 server with mod_rewrite support. Please contact your hosting provider about upgrading your server software. Your Apache version is', 'spiderblocker' ); ?> <b><?php echo esc_html( apache_get_version() ); ?></b></p>
400
- </div>
401
- <?php
402
- die();
403
- }
404
-
405
- if ( ! self::is_htaccess_writable() ) {
406
- $state = self::chmod_htaccess();
407
- if ( ! self::is_htaccess_writable() || ! $state ) {
408
- ?>
409
- <div id="error-page">
410
- <p>
411
- <?php
412
- printf(
413
- esc_html__( '%1$s %2$s %3$s', 'spiderblocker' ),
414
- esc_html__( 'This plugin requires', 'spiderblocker' ),
415
- '<b>.htaccess</b>',
416
- esc_html__( 'file that is writable by the server. Please enable write access for file', 'spiderblocker' )
417
- );
418
- ?>
419
- <b><?php echo esc_html( ABSPATH . '.htaccess' ); ?></b>.</p>
420
- </div>
421
- <?php
422
- die();
423
- }
424
- }
425
  $this->generate_block_rules();
426
-
427
- }
428
-
429
- /**
430
- * Check if the .htaccess file is writable.
431
- *
432
- * @return bool
433
- * @codeCoverageIgnore
434
- */
435
- private static function is_htaccess_writable() {
436
- $htaccess_file = self::join_paths( ABSPATH, '.htaccess' );
437
- return is_writable( $htaccess_file );
438
- }
439
-
440
- /**
441
- * Function to join the supplied arguments together.
442
- *
443
- * @return string
444
- * @codeCoverageIgnore
445
- */
446
- private static function join_paths() {
447
- $paths = array();
448
-
449
- foreach ( func_get_args() as $arg ) {
450
- if ( '' !== $arg ) {
451
- $paths[] = $arg;
452
- }
453
- }
454
-
455
- return preg_replace( '#/+#', '/', join( '/', $paths ) );
456
- }
457
-
458
- /**
459
- * Change file permission of the .htaccess file.
460
- *
461
- * @param int $mod octet value for chmod.
462
- * @return bool
463
- * @codeCoverageIgnore
464
- */
465
- private static function chmod_htaccess( $mod = 0644 ) {
466
- $home_path = function_exists( 'get_home_path' ) ? get_home_path() : ABSPATH;
467
- $htaccess_file = $home_path . '.htaccess';
468
-
469
- return chmod( $htaccess_file, $mod );
470
  }
471
 
472
  /**
@@ -564,29 +594,34 @@ class SpiderBlocker {
564
  */
565
  public function save_list() {
566
  check_ajax_referer( self::NONCE, 'nonce' );
567
- if ( isset( $_POST['data'] ) && '' !== $_POST['data'] ) {
568
- $data = json_decode( stripcslashes( $_POST['data'] ), true );
569
-
570
- if ( json_last_error() ) {
571
- if ( function_exists( 'json_last_error_msg' ) ) {
572
- wp_send_json_error( json_last_error_msg() );
573
- } else {
574
- wp_send_json_error( esc_html__( 'Failed parsing JSON', 'spiderblocker' ) );
575
- }
576
- }
577
 
578
- if ( get_option( self::OPTIONNAME ) !== false ) {
579
- update_option( self::OPTIONNAME, maybe_serialize( $data ) );
580
- } else {
581
- add_option( self::OPTIONNAME, maybe_serialize( $data ), '', 'no' );
582
- }
583
 
584
- $this->generate_block_rules();
585
- add_filter( 'robots_txt', array( &$this, 'robots_file' ), ~PHP_INT_MAX, 2 );
586
- wp_send_json_success( $this->get_bots() );
587
- } else {
588
  wp_send_json_error( esc_html__( 'Unable to process the request as no data has been received.', 'spiderblocker' ) );
 
589
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
590
  }
591
 
592
  /**
@@ -618,28 +653,101 @@ class SpiderBlocker {
618
  * @codeCoverageIgnore
619
  */
620
  public function view_handler() {
621
- ?>
622
- <style>
623
- .notice.fixed {
624
- position: fixed;
625
- right: 1em;
626
- top: 3.5em;
627
- }
628
 
629
- tr.active {
630
- background-color: rgba(54, 204, 255, 0.05);
631
- }
632
 
633
- .active th.bot-re {
634
- border-left: 4px solid #2ea2cc;
635
- }
636
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
637
 
638
- <script>
639
- window.sb_nonce = "<?php echo esc_html( wp_create_nonce( self::NONCE ) ); ?>";
 
 
 
 
 
 
640
  -(function () {
641
  var spiderBlockApp = angular.module('spiderBlockApp', []);
642
-
643
  spiderBlockApp.directive('jsonText', function () {
644
  return {
645
  restrict: 'A',
@@ -648,11 +756,11 @@ class SpiderBlocker {
648
  function into(input) {
649
  return angular.fromJson(input);
650
  }
651
-
652
  function out(data) {
653
  return angular.toJson(data, true);
654
  }
655
-
656
  ngModel.$parsers.push(into);
657
  ngModel.$formatters.push(out);
658
  }
@@ -660,14 +768,14 @@ class SpiderBlocker {
660
  });
661
  spiderBlockApp.controller('NotificationsCtrl', function ($scope, $rootScope, $timeout) {
662
  $scope.notifications = [];
663
-
664
  $rootScope.$on('notification', function (event, data) {
665
  $scope.notifications.push(data);
666
  $timeout(function () {
667
  $scope.removeNotification(data);
668
  }, 3000);
669
  });
670
-
671
  $scope.removeNotification = function (notification) {
672
  var index;
673
  if ($scope.notifications !== undefined) {
@@ -678,7 +786,8 @@ class SpiderBlocker {
678
  });
679
  spiderBlockApp.controller('BotListCtrl', function ($scope, $http, $rootScope) {
680
  var wp_ajax = function (_req) {
681
- _req.nonce = window.sb_nonce;
 
682
  return $http({
683
  method: 'POST',
684
  url: ajaxurl,
@@ -686,7 +795,7 @@ class SpiderBlocker {
686
  headers: {'Content-Type': 'application/x-www-form-urlencoded'}
687
  })
688
  };
689
-
690
  var find_bot = function (re) {
691
  for (var i = $scope.bots.length - 1; i >= 0; i--) {
692
  if ($scope.bots[i]['re'] == re) {
@@ -697,13 +806,13 @@ class SpiderBlocker {
697
  };
698
 
699
  $scope.bot = {"state": true};
700
-
701
  wp_ajax({
702
  action: 'NSB-get_list'
703
  }).success(function (res) {
704
  $scope.bots = res.data;
705
  });
706
-
707
  $scope.save = function () {
708
  wp_ajax({
709
  action: 'NSB-set_list',
@@ -713,14 +822,14 @@ class SpiderBlocker {
713
  $scope.bots = res.data;
714
  $rootScope.$emit('notification', {
715
  state: 'success',
716
- msg: 'List of bots was saved and new blocklist applied!'
717
  });
718
  } else {
719
  $rootScope.$emit('notification', {state: 'errror', msg: res.data});
720
  }
721
  });
722
  };
723
-
724
  $scope.reset = function () {
725
  wp_ajax({
726
  action: 'NSB-reset_list'
@@ -728,154 +837,175 @@ class SpiderBlocker {
728
  $scope.bots = res.data;
729
  $rootScope.$emit('notification', {
730
  state: 'success',
731
- msg: 'List of bots was reset to defaults!'
732
  });
733
  });
734
  };
735
-
736
  $scope.add = function () {
737
  $scope.bots.push($scope.bot);
738
  $rootScope.$emit('notification', {
739
  state: 'success',
740
- msg: 'Bot ' + $scope.bot.name + ' was added!'
741
  });
742
  $scope.bot = {"state": true};
743
  };
744
-
745
  $scope.remove = function (at) {
746
- $rootScope.$emit('notification', {state: 'success', msg: 'Bot was removed!'});
747
  $scope.bots.splice(find_bot(at), 1);
748
  };
749
  });
750
  })(angular, document, jQuery);
751
  </script>
752
- <h1><?php esc_html_e( 'Spider Blocker', 'spiderblocker' ); ?></h1>
753
- <hr/>
754
- <div ng-app="spiderBlockApp">
755
- <div ng-controller="NotificationsCtrl">
756
- <div class="notice notice-{{ n.state }} fixed" ng-repeat="n in notifications" style="top: {{3.5*($index+1)}}em">
757
- <p>{{n.msg}}
758
- <a ng-click="removeNotification(notification)">
759
- <span class="dashicons dashicons-no-alt"></span>
760
- </a>
761
- </p>
762
- </div>
763
- </div>
764
-
765
- <div ng-controller="BotListCtrl">
766
- <h2><?php esc_html_e( 'Add New Bot', 'spiderblocker' ); ?></h2>
767
-
768
- <form name="add_form" ng-submit="add()">
769
- <table class="form-table">
770
- <tbody>
771
- <tr>
772
- <th scope="row"><label><?php esc_html_e( 'User Agent', 'spiderblocker' ); ?></label></th>
773
- <td><input bots="bots" ng-model='bot.re' class="regular-text" required/></td>
774
- </tr>
775
- <tr>
776
- <th scope="row"><label><?php esc_html_e( 'Bot Name', 'spiderblocker' ); ?></label></th>
777
- <td><input type="text" ng-model='bot.name' class="regular-text" required/></td>
778
- </tr>
779
- <tr>
780
- <tr>
781
- <th scope="row"><label><?php esc_html_e( 'Bot Description URL', 'spiderblocker' ); ?></label></th>
782
- <td><input type="url" ng-model='bot.desc' class="regular-text" placeholder="http://"/>
783
- </td>
784
- </tr>
785
- </tbody>
786
- </table>
787
-
788
- <p class="submit"><input ng-disabled="add_form.$invalid" type="submit" class="button button-primary" value="<?php esc_attr_e( 'Add Bot', 'spiderblocker' ); ?>"></p>
789
- </form>
790
-
791
- <h2><?php esc_html_e( 'List of bots', 'spiderblocker' ); ?></h2>
792
- <ng-form class="search-box">
793
- <input size="35" type="search" id="ua-search-input" ng-model="query" placeholder="<?php esc_attr_e( 'Filter...', 'spiderblocker' ); ?>">
794
- </ng-form>
795
-
796
- <table class="wp-list-table widefat bots">
797
- <thead>
798
- <tr>
799
- <th scope="col" class="manage-column column-description">
800
- <a href="" ng-click="predicate = 're'; reverse=false"><?php esc_html_e( 'User Agent', 'spiderblocker' ); ?> <span class="dashicons dashicons-sort"></span></a>
801
- </th>
802
- <th scope="col" class="manage-column column-name"><?php esc_html_e( 'Name', 'spiderblocker' ); ?></th>
803
- <th scope="col" class="manage-column column-state">
804
- <a href="" ng-click="predicate = 'state'; reverse=false"><?php esc_html_e( 'State', 'spiderblocker' ); ?> <span class="dashicons dashicons-sort"></span></a>
805
- </th>
806
- <th scope="col" id="action" class="manage-column column-action"><?php esc_html_e( 'Action', 'spiderblocker' ); ?></th>
807
- </tr>
808
- </thead>
809
-
810
- <tfoot>
811
- <tr>
812
- <th scope="col" class="manage-column column-description"><a href="" ng-click="predicate = 're'; reverse=false"><?php esc_html_e( 'User Agent', 'spiderblocker' ); ?></a></th>
813
- <th scope="col" class="manage-column column-name"><?php esc_html_e( 'Name', 'spiderblocker' ); ?></th>
814
- <th scope="col" class="manage-column column-state"><a href="" ng-click="predicate = 'state'; reverse=false"><?php esc_html_e( 'State', 'spiderblocker' ); ?></a>
815
- </th>
816
- <th scope="col" id="action" class="manage-column column-action"><?php esc_html_e( 'Action', 'spiderblocker' ); ?></th>
817
- </tr>
818
- </tfoot>
819
-
820
- <tbody id="the-list">
821
- <tr id="spider-blocker" ng-repeat="bot in bots | filter:query | orderBy:predicate:reverse"
822
- ng-class="{'active': bot.state}">
823
-
824
- <th class="bot-re"> {{ bot.re }}</th>
825
- <td class="bot-title"><strong>{{ bot.name }}</strong> <a target="_blank" ng-href="{{bot.desc}}">{{ bot.desc }}</a></td>
826
- <th class="expression" ng-class="{'blocked':bot.state}"> {{ bot.state?"Blocked":"Allowed" }}</th>
827
- <td class="actions">
828
- <input ng-hide="bot.state" type="button" ng-click="bot.state=true" class="button button-primary" value="Block">
829
- <input ng-show="bot.state" type="button" ng-click="bot.state=false" class="button button-secondary" value="Allow">
830
- <input type="button" ng-click="remove(bot.re)" class="button button-secondary" value="Remove">
831
- </td>
832
- </tr>
833
- </tbody>
834
- </table>
835
-
836
- <div id="rules-export-import" style="display:none;">
837
- <textarea style="-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;width: 100%;height: 99%;" json-text ng-model="bots"></textarea>
838
- </div>
839
-
840
- <p class="submit">
841
- <input type="button" class="button button-primary" ng-click="save()" value="<?php esc_attr_e( 'Save', 'spiderblocker' ); ?>">
842
- <input type="button" class="button button-primary" ng-click="reset()" value="<?php esc_attr_e( 'Reset to Defaults', 'spiderblocker' ); ?>">
843
- <a href="#TB_inline?width=540&height=360&inlineId=rules-export-import" class="thickbox button button-secondary"><?php esc_html_e( 'Import/Export Definitions', 'spiderblocker' ); ?></a>
844
- </p>
845
- </div>
846
- </div>
847
  <?php
848
  }
849
 
850
  /**
851
- * Adds action for admin scripts.
 
 
852
  */
853
- public function view_handler_load() {
854
- add_action( 'admin_enqueue_scripts', array( &$this, 'view_handler_scripts' ) );
855
  }
856
 
857
  /**
858
- * Registers & Enqueues the admin scripts for the view_handler() function.
 
 
859
  */
860
- public function view_handler_scripts() {
861
- wp_register_script( 'spiderblocker-angular', 'https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js', array( 'jquery' ), '1.0.18', false );
862
- wp_enqueue_script( 'spiderblocker-angular' );
 
 
 
 
863
 
864
- wp_enqueue_script( 'thickbox' );
865
- wp_enqueue_style( 'thickbox' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
866
  }
867
 
868
  }
869
 
870
- // Initialize Plugin.
871
  if ( defined( 'ABSPATH' ) ) {
872
- $niteo_spider_blocker = new SpiderBlocker();
873
-
874
- add_action( 'upgrader_process_complete', array( &$niteo_spider_blocker, 'on_plugin_upgrade' ), 10, 2 );
875
 
876
- // Activation Hook.
877
- register_activation_hook( __FILE__, array( &$niteo_spider_blocker, 'activate_plugin' ) );
878
 
879
- // Deactivation Hook.
880
- register_deactivation_hook( __FILE__, array( &$niteo_spider_blocker, 'remove_block_rules' ) );
 
881
  }
5
  /**
6
  * Plugin Name: Spider Blocker
7
  * Description: Spider Blocker will block most common bots that consume bandwidth and slow down your server.
8
+ * Version: 1.2.5
9
  * Runtime: 5.6+
10
  * Author: Easy Blog Networks
11
  * Text Domain: spiderblocker
13
  * Author URI: www.easyblognetworks.com
14
  */
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  /**
17
  * Spiderblocker class where all the action happens.
18
  *
21
  */
22
  class SpiderBlocker {
23
 
24
+ /**
25
+ * @var string
26
+ */
27
+ public const PLUGIN_NAME = 'Spider Blocker';
28
+
29
+ /**
30
+ * @var string
31
+ */
32
+ public const PLUGIN_BASE = 'spiderblocker/index.php';
33
+
34
+ /**
35
+ * @var string
36
+ */
37
+ public const PLUGIN_VERSION = '1.2.5';
38
+
39
+ /**
40
+ * @var string
41
+ */
42
+ public const MINIMUM_PHP_VERSION = '5.6';
43
+
44
+ /**
45
+ * @var string
46
+ */
47
+ public const MINIMUM_WP_VERSION = '4.2.0';
48
+
49
+ /**
50
+ * @var string
51
+ */
52
+ public const OPTIONNAME = 'Niteoweb.SpiderBlocker.Bots';
53
+
54
+ /**
55
+ * @var string
56
+ */
57
+ public const NONCE = 'Niteoweb.SpiderBlocker.Nonce';
58
+
59
+ /**
60
+ * @var string
61
+ */
62
+ public const CHECKHOOK = 'Niteoweb.SpiderBlocker.CheckHook';
63
+
64
+ /**
65
+ * @var array
66
+ */
67
+ public $notices = array();
68
 
69
  /**
70
  * Bots which can be blocked by the spiderblocker plugin
312
  * Class Constructor.
313
  */
314
  public function __construct() {
315
+ add_filter( 'robots_txt', array( &$this, 'robots_file' ), ~PHP_INT_MAX, 2 );
316
+
317
+ add_action( 'admin_init', array( $this, 'check_environment' ) );
318
+ add_action( 'admin_init', array( $this, 'check_server' ) );
319
+ add_action( 'admin_init', array( $this, 'add_plugin_notices' ) );
320
+ add_action( 'admin_notices', array( $this, 'admin_notices' ), 15 );
321
+
322
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
323
+ add_action( 'wp_ajax_NSB-get_list', array( $this, 'load_list' ) );
324
+ add_action( 'wp_ajax_NSB-set_list', array( $this, 'save_list' ) );
325
+ add_action( 'wp_ajax_NSB-reset_list', array( $this, 'reset_list' ) );
326
+ add_action( 'generate_rewrite_rules', array( $this, 'generate_rewrite_rules' ) );
327
+ }
328
+
329
+ /**
330
+ * Checks the environment on loading WordPress, just in case the environment changes after activation.
331
+ */
332
+ public function check_environment() {
333
+ if ( $this->is_environment_compatible() ) {
334
+ return;
335
  }
336
 
337
+ $this->deactivate_plugin();
338
+ $this->add_admin_notice( 'bad_environment', 'error', $this->get_plugin_name() . ' has been deactivated. ' . $this->get_environment_message() );
339
+ }
340
 
341
+ /**
342
+ * Checks for server and .htaccess write permissions.
343
+ */
344
+ public function check_server() {
345
+ // Check Apache version
346
+ if ( ! $this->get_server_software( 'Apache' ) && ! $this->get_server_software( 'LiteSpeed' ) ) {
347
+ $this->deactivate_plugin();
348
+ $this->add_admin_notice(
349
+ 'no_apache',
350
+ 'error',
351
+ sprintf(
352
+ esc_html__( '%s requires Apache2 or LiteSpeed server with mod_rewrite support. Please contact your hosting provider about upgrading your server software.', 'spiderblocker' ),
353
+ $this->get_plugin_name()
354
+ )
355
+ );
356
+ }
357
+
358
+ // Write permission for .htaccess
359
+ if ( ! $this->is_htaccess_writable() || ! $this->chmod_htaccess() ) {
360
+ $this->deactivate_plugin();
361
+ $this->add_admin_notice(
362
+ 'no_htaccess',
363
+ 'error',
364
+ sprintf(
365
+ esc_html__( '%s requires .htaccess file that is writable by the server. Please enable write access for the file.', 'spiderblocker' ),
366
+ $this->get_plugin_name()
367
+ )
368
+ );
369
+ }
370
+ }
371
+
372
+ /**
373
+ * Adds notices for out-of-date WordPress and/or WooCommerce versions.
374
+ */
375
+ public function add_plugin_notices() {
376
+ // Check for WP version
377
+ if ( ! $this->is_wp_compatible() ) {
378
+ $this->add_admin_notice(
379
+ 'update_wordpress',
380
+ 'error',
381
+ sprintf(
382
+ esc_html__( '%1$s requires WordPress version %2$s or higher. Please %3$supdate WordPress &raquo;%4$s', 'spiderblocker' ),
383
+ $this->get_plugin_name(),
384
+ $this->get_wp_version(),
385
+ '<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
386
+ '</a>'
387
+ )
388
+ );
389
+ }
390
+
391
+ // Check for plugin activation
392
+ if ( $this->activate_plugin_notice() ) {
393
+ $this->add_admin_notice(
394
+ 'plugin_activated',
395
+ 'success',
396
+ sprintf(
397
+ esc_html__( '%1$s plugin has enabled blocking of some bots, please review settings by visiting %2$sSettings page%3$s!', 'spiderblocker' ),
398
+ $this->get_plugin_name(),
399
+ '<a href="' . esc_url( admin_url( 'tools.php?page=ni_spider_block' ) ) . '">',
400
+ '</a>'
401
+ )
402
+ );
403
+ }
404
+ }
405
+
406
+ /**
407
+ * Admin notice which gets fired on plugin activation.
408
+ */
409
+ public function activate_plugin_notice() {
410
+ if ( get_option( self::OPTIONNAME, false ) ) {
411
+ return false;
412
+ }
413
+
414
+ // Add option to DB and return true
415
+ update_option( self::OPTIONNAME, $this->default_bots );
416
+
417
+ return true;
418
+ }
419
+
420
+ /**
421
+ * Displays any admin notices added with add_admin_notice()
422
+ */
423
+ public function admin_notices() {
424
+ foreach ( (array) $this->notices as $notice_key => $notice ) {
425
+ echo '<div class="notice notice-' . esc_attr( $notice['class'] ) . '">';
426
+ echo '<p>' . wp_kses( $notice['message'], array( 'a' => array( 'href' => array() ) ) ) . '</p>';
427
+ echo '</div>';
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Adds an admin notice to be displayed.
433
+ *
434
+ * @param string $slug the slug for the notice
435
+ * @param string $class the css class for the notice
436
+ * @param string $message the notice message
437
+ */
438
+ private function add_admin_notice( $slug, $class, $message ) {
439
+ $this->notices[ $slug ] = array(
440
+ 'class' => $class,
441
+ 'message' => $message,
442
+ );
443
  }
444
 
445
  /**
457
  * Fetch Plugin URL.
458
  *
459
  * @return string
 
460
  */
461
+ public function plugin_url() {
462
  $url = wp_make_link_relative( plugin_dir_url( __FILE__ ) );
463
  $url = ltrim( $url, '/' );
464
 
480
  add_action( 'load-' . $menu, array( &$this, 'view_handler_load' ) );
481
  }
482
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
483
  /**
484
  * Generate block rules when the download process for a plugin
485
  * install or update finishes.
496
  * @codeCoverageIgnore
497
  */
498
  public function activate_plugin() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
499
  $this->generate_block_rules();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500
  }
501
 
502
  /**
594
  */
595
  public function save_list() {
596
  check_ajax_referer( self::NONCE, 'nonce' );
 
 
 
 
 
 
 
 
 
 
597
 
598
+ if ( ! isset( $_POST['data'] ) ) {
599
+ wp_send_json_error( esc_html__( 'Unable to process the request as no data has been received.', 'spiderblocker' ) );
600
+ return;
601
+ }
 
602
 
603
+ if ( empty( $_POST['data'] ) ) {
 
 
 
604
  wp_send_json_error( esc_html__( 'Unable to process the request as no data has been received.', 'spiderblocker' ) );
605
+ return;
606
  }
607
+
608
+ $data = json_decode( stripcslashes( $_POST['data'] ), true );
609
+
610
+ if ( json_last_error() ) {
611
+ wp_send_json_error( esc_html__( 'Failed parsing JSON data.', 'spiderblocker' ) );
612
+ return;
613
+ }
614
+
615
+ update_option( self::OPTIONNAME, maybe_serialize( $data ), 'no' );
616
+
617
+ // Add rule to .htaccess file
618
+ $this->generate_block_rules();
619
+
620
+ // Update robots_txt file
621
+ add_filter( 'robots_txt', array( &$this, 'robots_file' ), ~PHP_INT_MAX, 2 );
622
+
623
+ // Send success response
624
+ wp_send_json_success( $this->get_bots() );
625
  }
626
 
627
  /**
653
  * @codeCoverageIgnore
654
  */
655
  public function view_handler() {
656
+ // Load admin assets
657
+ $this->admin_css();
658
+ $this->admin_js();
 
 
 
 
659
 
660
+ include __DIR__ . '/inc/templates/settings.php';
661
+ }
 
662
 
663
+ /**
664
+ * Adds action for admin scripts.
665
+ */
666
+ public function view_handler_load() {
667
+ add_action( 'admin_enqueue_scripts', array( &$this, 'view_handler_scripts' ) );
668
+ }
669
+
670
+ /**
671
+ * Registers & Enqueues the admin scripts for the view_handler() function.
672
+ */
673
+ public function view_handler_scripts() {
674
+ wp_enqueue_script( 'spiderblocker-admin', 'https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js', array( 'jquery' ), self::PLUGIN_VERSION, false );
675
+
676
+ $localize = array(
677
+ 'nonce' => wp_create_nonce( self::NONCE ),
678
+ 'save_text' => esc_html__( 'List of bots was saved and new blocklist applied!', 'spiderblocker' ),
679
+ 'save_reset_text' => esc_html__( 'List of bots was reset to defaults!', 'spiderblocker' ),
680
+ 'bot_text' => esc_html__( 'Bot', 'spiderblocker' ),
681
+ 'added_text' => esc_html__( 'was added!', 'spiderblocker' ),
682
+ 'removed_text' => esc_html__( 'Bot was removed!', 'spiderblocker' ),
683
+ );
684
+
685
+ // Pass data to JS
686
+ wp_localize_script( 'spiderblocker-admin', 'sb_i18n', $localize );
687
+
688
+ wp_enqueue_script( 'thickbox' );
689
+ wp_enqueue_style( 'thickbox' );
690
+ }
691
+
692
+ /**
693
+ * CSS for settings panel.
694
+ *
695
+ * @codeCoverageIgnore
696
+ */
697
+ public function admin_css() {
698
+ ?>
699
+ <style type="text/css">
700
+ .spiderblocker-root {
701
+ margin-right: 20px;
702
+ }
703
+ .sb-table-top {
704
+ display: flex;
705
+ align-items: center;
706
+ }
707
+ .search-box {
708
+ margin-left: auto;
709
+ }
710
+ .form-table th {
711
+ padding: 10px 10px 10px 0;
712
+ }
713
+ .form-table td {
714
+ padding: 10px;
715
+ }
716
+ .notice.fixed {
717
+ position: fixed;
718
+ right: 1em;
719
+ top: 3.5em;
720
+ }
721
+ tr.active {
722
+ background-color: rgba(54, 204, 255, 0.05);
723
+ }
724
+ .active th.bot-re {
725
+ border-left: 4px solid #2ea2cc;
726
+ }
727
+
728
+ @media (max-width: 782px) {
729
+ .spiderblocker-root {
730
+ margin-right: 12px;
731
+ }
732
+ .form-table td {
733
+ padding: 10px 0;
734
+ }
735
+ }
736
+ </style>
737
+ <?php
738
+ }
739
 
740
+ /**
741
+ * JS for settings panel.
742
+ *
743
+ * @codeCoverageIgnore
744
+ */
745
+ public function admin_js() {
746
+ ?>
747
+ <script type="text/javascript">
748
  -(function () {
749
  var spiderBlockApp = angular.module('spiderBlockApp', []);
750
+
751
  spiderBlockApp.directive('jsonText', function () {
752
  return {
753
  restrict: 'A',
756
  function into(input) {
757
  return angular.fromJson(input);
758
  }
759
+
760
  function out(data) {
761
  return angular.toJson(data, true);
762
  }
763
+
764
  ngModel.$parsers.push(into);
765
  ngModel.$formatters.push(out);
766
  }
768
  });
769
  spiderBlockApp.controller('NotificationsCtrl', function ($scope, $rootScope, $timeout) {
770
  $scope.notifications = [];
771
+
772
  $rootScope.$on('notification', function (event, data) {
773
  $scope.notifications.push(data);
774
  $timeout(function () {
775
  $scope.removeNotification(data);
776
  }, 3000);
777
  });
778
+
779
  $scope.removeNotification = function (notification) {
780
  var index;
781
  if ($scope.notifications !== undefined) {
786
  });
787
  spiderBlockApp.controller('BotListCtrl', function ($scope, $http, $rootScope) {
788
  var wp_ajax = function (_req) {
789
+ _req.nonce = sb_i18n.nonce;
790
+
791
  return $http({
792
  method: 'POST',
793
  url: ajaxurl,
795
  headers: {'Content-Type': 'application/x-www-form-urlencoded'}
796
  })
797
  };
798
+
799
  var find_bot = function (re) {
800
  for (var i = $scope.bots.length - 1; i >= 0; i--) {
801
  if ($scope.bots[i]['re'] == re) {
806
  };
807
 
808
  $scope.bot = {"state": true};
809
+
810
  wp_ajax({
811
  action: 'NSB-get_list'
812
  }).success(function (res) {
813
  $scope.bots = res.data;
814
  });
815
+
816
  $scope.save = function () {
817
  wp_ajax({
818
  action: 'NSB-set_list',
822
  $scope.bots = res.data;
823
  $rootScope.$emit('notification', {
824
  state: 'success',
825
+ msg: sb_i18n.save_text
826
  });
827
  } else {
828
  $rootScope.$emit('notification', {state: 'errror', msg: res.data});
829
  }
830
  });
831
  };
832
+
833
  $scope.reset = function () {
834
  wp_ajax({
835
  action: 'NSB-reset_list'
837
  $scope.bots = res.data;
838
  $rootScope.$emit('notification', {
839
  state: 'success',
840
+ msg: sb_i18n.save_reset_text
841
  });
842
  });
843
  };
844
+
845
  $scope.add = function () {
846
  $scope.bots.push($scope.bot);
847
  $rootScope.$emit('notification', {
848
  state: 'success',
849
+ msg: sb_i18n.bot_text + ' ' + $scope.bot.name + ' ' + sb_i18n.added_text
850
  });
851
  $scope.bot = {"state": true};
852
  };
853
+
854
  $scope.remove = function (at) {
855
+ $rootScope.$emit('notification', {state: 'success', msg: sb_i18n.removed_text});
856
  $scope.bots.splice(find_bot(at), 1);
857
  };
858
  });
859
  })(angular, document, jQuery);
860
  </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
861
  <?php
862
  }
863
 
864
  /**
865
+ * Determines if the server environment is compatible with this plugin.
866
+ *
867
+ * @return bool
868
  */
869
+ public function is_environment_compatible() {
870
+ return version_compare( PHP_VERSION, $this->get_php_version(), '>=' );
871
  }
872
 
873
  /**
874
+ * Gets the message for display when the environment is incompatible with this plugin.
875
+ *
876
+ * @return string
877
  */
878
+ public function get_environment_message() {
879
+ return sprintf(
880
+ esc_html__( 'The minimum PHP version required for this plugin is %1$s. You are running %2$s.', 'eu-vat-b2b-taxes' ),
881
+ $this->get_php_version(),
882
+ PHP_VERSION
883
+ );
884
+ }
885
 
886
+ /**
887
+ * Determines if the WordPress compatible.
888
+ *
889
+ * @return bool
890
+ */
891
+ public function is_wp_compatible() {
892
+ if ( ! $this->get_wp_version() ) {
893
+ return true;
894
+ }
895
+
896
+ return version_compare( get_bloginfo( 'version' ), $this->get_wp_version(), '>=' );
897
+ }
898
+
899
+ /**
900
+ * Returns PLUGIN_NAME.
901
+ */
902
+ public function get_plugin_name() {
903
+ return self::PLUGIN_NAME;
904
+ }
905
+
906
+ /**
907
+ * Returns PLUGIN_BASE.
908
+ */
909
+ public function get_plugin_base() {
910
+ return self::PLUGIN_BASE;
911
+ }
912
+
913
+ /**
914
+ * Returns MINIMUM_PHP_VERSION.
915
+ */
916
+ public function get_php_version() {
917
+ return self::MINIMUM_PHP_VERSION;
918
+ }
919
+
920
+ /**
921
+ * Returns MINIMUM_WP_VERSION.
922
+ */
923
+ public function get_wp_version() {
924
+ return self::MINIMUM_WP_VERSION;
925
+ }
926
+
927
+ /**
928
+ * Fetch the Apache version.
929
+ *
930
+ * @return string|false
931
+ */
932
+ public function get_server_software( $server ) {
933
+ // Check Apache
934
+ if ( stristr( $_ENV['SERVER_SOFTWARE'], $server ) ) {
935
+ return sanitize_text_field( $_ENV['SERVER_SOFTWARE'] );
936
+ }
937
+
938
+ if ( stristr( $_SERVER['SERVER_SOFTWARE'], $server ) ) {
939
+ return sanitize_text_field( $_SERVER['SERVER_SOFTWARE'] );
940
+ }
941
+
942
+ return false;
943
+ }
944
+
945
+ /**
946
+ * Deactivates the plugin.
947
+ */
948
+ protected function deactivate_plugin() {
949
+ deactivate_plugins( $this->get_plugin_base() );
950
+
951
+ if ( isset( $_GET['activate'] ) ) {
952
+ unset( $_GET['activate'] );
953
+ }
954
+ }
955
+
956
+ /**
957
+ * Change file permission of the .htaccess file.
958
+ *
959
+ * @param int $mod octet value for chmod.
960
+ * @return bool
961
+ * @codeCoverageIgnore
962
+ */
963
+ protected function chmod_htaccess( $mod = 0644 ) {
964
+ $home_path = function_exists( 'get_home_path' ) ? get_home_path() : ABSPATH;
965
+ $htaccess_file = $home_path . '.htaccess';
966
+
967
+ return chmod( $htaccess_file, $mod );
968
+ }
969
+
970
+ /**
971
+ * Check if the .htaccess file is writable.
972
+ *
973
+ * @return bool
974
+ * @codeCoverageIgnore
975
+ */
976
+ protected function is_htaccess_writable() {
977
+ $htaccess_file = self::join_paths( ABSPATH, '.htaccess' );
978
+ return is_writable( $htaccess_file );
979
+ }
980
+
981
+ /**
982
+ * Function to join the supplied arguments together.
983
+ *
984
+ * @return string
985
+ * @codeCoverageIgnore
986
+ */
987
+ private static function join_paths() {
988
+ $paths = array();
989
+
990
+ foreach ( func_get_args() as $arg ) {
991
+ if ( '' !== $arg ) {
992
+ $paths[] = $arg;
993
+ }
994
+ }
995
+
996
+ return preg_replace( '#/+#', '/', join( '/', $paths ) );
997
  }
998
 
999
  }
1000
 
1001
+ // Initlaize if called from within WordPress
1002
  if ( defined( 'ABSPATH' ) ) {
1003
+ $spiderblocker = new SpiderBlocker();
 
 
1004
 
1005
+ // Register hooks
1006
+ add_action( 'upgrader_process_complete', array( $spiderblocker, 'on_plugin_upgrade' ), 10, 2 );
1007
 
1008
+ // Runs on plugin activation & de-activation
1009
+ register_activation_hook( __FILE__, array( $spiderblocker, 'activate_plugin' ) );
1010
+ register_deactivation_hook( __FILE__, array( $spiderblocker, 'remove_block_rules' ) );
1011
  }
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: niteoweb
3
  Tags: seo, block, bots, htaccess, apache, secure
4
  Requires at least: 4.0
5
- Tested up to: 5.3.2
6
- Stable tag: 1.2.0
7
 
8
  SpiderBlocker will block most common bots that consume bandwidth and slow down your server.
9
 
@@ -32,6 +32,10 @@ with Apache server and mod_rewrite enabled.
32
 
33
 
34
  == Changelog ==
 
 
 
 
35
  = v1.2.0 =
36
  - Code clean-up
37
  - Support for the latest version of WordPress
2
  Contributors: niteoweb
3
  Tags: seo, block, bots, htaccess, apache, secure
4
  Requires at least: 4.0
5
+ Tested up to: 5.4.2
6
+ Stable tag: 1.2.5
7
 
8
  SpiderBlocker will block most common bots that consume bandwidth and slow down your server.
9
 
32
 
33
 
34
  == Changelog ==
35
+ = v1.2.5 =
36
+ - Visual fixes and code clean-up
37
+ - Added support for LiteSpeed server
38
+
39
  = v1.2.0 =
40
  - Code clean-up
41
  - Support for the latest version of WordPress