Spider Blocker - Version 1.0.11

Version Description

Download this release

Release Info

Developer niteoweb
Plugin Icon 128x128 Spider Blocker
Version 1.0.11
Comparing to
See all releases

Code changes from version 1.0.10 to 1.0.11

Files changed (1) hide show
  1. index.php +518 -485
index.php CHANGED
@@ -3,505 +3,538 @@ namespace Niteoweb\SpiderBlocker;
3
  /**
4
  * Plugin Name: Spider Blocker
5
  * Description: Spider Blocker will block most common bots that consume bandwidth and slow down your server.
6
- * Version: 1.0.10
7
  * Runtime: 5.3+
8
  * Author: Easy Blog Networks
9
  * Author URI: www.easyblognetworks.com
10
  */
11
 
12
- if ( ! function_exists( 'apache_get_version' ) ) {
13
- function apache_get_version() {
14
- if ( stristr( $_ENV["SERVER_SOFTWARE"], 'Apache' ) ) {
15
- return $_ENV["SERVER_SOFTWARE"];
16
- }
17
- if ( stristr( $_SERVER["SERVER_SOFTWARE"], 'Apache' ) ) {
18
- return $_SERVER["SERVER_SOFTWARE"];
19
- }
20
- return false;
21
- }
 
22
  }
23
 
24
- if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) {
25
- ?>
26
- <div id="error-page">
27
- <p>This plugin requires PHP 5.3.0 or higher. Please contact your hosting provider about upgrading your
28
- server software. Your PHP version is <b><?php echo PHP_VERSION; ?></b></p>
29
- </div>
30
- <?php
31
- die();
32
  }
33
 
34
 
35
- class SpiderBlocker {
36
-
37
- public $default_bots = 'a:36:{i:0;O:8:"stdClass":4:{s:4:"name";s:10:"Ahrefs Bot";s:2:"re";s:9:"AhrefsBot";s:4:"desc";s:25:"https://ahrefs.com/robot/";s:5:"state";b:1;}i:1;O:8:"stdClass":4:{s:4:"name";s:8:"MJ12 bot";s:2:"re";s:7:"MJ12bot";s:4:"desc";s:56:"http://www.majestic12.co.uk/projects/dsearch/mj12bot.php";s:5:"state";b:1;}i:2;O:8:"stdClass":4:{s:4:"name";s:9:"Roger Bot";s:2:"re";s:8:"Rogerbot";s:4:"desc";s:40:"http://moz.com/help/pro/rogerbot-crawler";s:5:"state";b:1;}i:3;O:8:"stdClass":4:{s:4:"name";s:11:"Semrush Bot";s:2:"re";s:10:"SemrushBot";s:4:"desc";s:31:"http://www.semrush.com/bot.html";s:5:"state";b:1;}i:4;O:8:"stdClass":4:{s:4:"name";s:11:"ia_archiver";s:2:"re";s:11:"ia_archiver";s:4:"desc";s:36:"http://archive.org/about/exclude.php";s:5:"state";b:1;}i:5;O:8:"stdClass":4:{s:4:"name";s:8:"ScoutJet";s:2:"re";s:8:"ScoutJet";s:4:"desc";s:19:"http://scoutjet.com";s:5:"state";b:1;}i:6;O:8:"stdClass":4:{s:4:"name";s:7:"sistrix";s:2:"re";s:7:"sistrix";s:4:"desc";s:26:"http://crawler.sistrix.net";s:5:"state";b:1;}i:7;O:8:"stdClass":4:{s:4:"name";s:16:"SearchmetricsBot";s:2:"re";s:16:"SearchmetricsBot";s:4:"desc";s:50:"http://www.searchmetrics.com/en/searchmetrics-bot/";s:5:"state";b:1;}i:8;O:8:"stdClass":4:{s:4:"name";s:14:"SEOkicks-Robot";s:2:"re";s:14:"SEOkicks-Robot";s:4:"desc";s:33:"http://www.seokicks.de/robot.html";s:5:"state";b:1;}i:9;O:8:"stdClass":4:{s:4:"name";s:16:"Lipperhey Spider";s:2:"re";s:16:"Lipperhey Spider";s:4:"desc";s:43:"http://www.lipperhey.com/en/website-spider/";s:5:"state";b:1;}i:10;O:8:"stdClass":4:{s:4:"name";s:6:"Exabot";s:2:"re";s:6:"Exabot";s:4:"desc";s:44:"http://www.exalead.com/search/webmasterguide";s:5:"state";b:1;}i:11;O:8:"stdClass":4:{s:4:"name";s:6:"NC Bot";s:2:"re";s:5:"NCBot";s:4:"desc";s:55:"https://twitter.com/NetComber/status/334476871691550721";s:5:"state";b:1;}i:12;O:8:"stdClass":4:{s:4:"name";s:15:"BacklinkCrawler";s:2:"re";s:15:"BacklinkCrawler";s:4:"desc";s:40:"http://www.backlinktest.com/crawler.html";s:5:"state";b:1;}i:13;O:8:"stdClass":4:{s:4:"name";s:15:"archive.org Bot";s:2:"re";s:15:"archive.org_bot";s:4:"desc";s:42:"http://archive.org/details/archive.org_bot";s:5:"state";b:1;}i:14;O:8:"stdClass":4:{s:4:"name";s:12:"MeanPath Bot";s:2:"re";s:11:"meanpathbot";s:4:"desc";s:37:"https://meanpath.com/meanpathbot.html";s:5:"state";b:1;}i:15;O:8:"stdClass":4:{s:4:"name";s:18:"PagesInventory Bot";s:2:"re";s:14:"PagesInventory";s:4:"desc";s:56:"http://www.botsvsbrowsers.com/details/1002332/index.html";s:5:"state";b:1;}i:16;O:8:"stdClass":4:{s:4:"name";s:12:"Aboundex Bot";s:2:"re";s:11:"Aboundexbot";s:4:"desc";s:32:"http://www.aboundex.com/crawler/";s:5:"state";b:1;}i:17;O:8:"stdClass":4:{s:4:"name";s:15:"SeoProfiler Bot";s:2:"re";s:5:"spbot";s:4:"desc";s:31:"http://www.seoprofiler.com/bot/";s:5:"state";b:1;}i:18;O:8:"stdClass":4:{s:4:"name";s:11:"Linkdex Bot";s:2:"re";s:10:"linkdexbot";s:4:"desc";s:34:"http://www.linkdex.com/about/bots/";s:5:"state";b:1;}i:19;O:8:"stdClass":4:{s:4:"name";s:7:"Gigabot";s:2:"re";s:7:"Gigabot";s:4:"desc";s:45:"http://www.useragentstring.com/pages/Gigabot/";s:5:"state";b:1;}i:20;O:8:"stdClass":4:{s:4:"name";s:6:"DotBot";s:2:"re";s:6:"dotbot";s:4:"desc";s:35:"http://en.wikipedia.org/wiki/DotBot";s:5:"state";b:1;}i:21;O:8:"stdClass":4:{s:4:"name";s:5:"Nutch";s:2:"re";s:5:"Nutch";s:4:"desc";s:32:"http://nutch.apache.org/bot.html";s:5:"state";b:1;}i:22;O:8:"stdClass":4:{s:4:"name";s:8:"BLEX Bot";s:2:"re";s:7:"BLEXBot";s:4:"desc";s:27:"http://webmeup-crawler.com/";s:5:"state";b:1;}i:23;O:8:"stdClass":4:{s:4:"name";s:6:"Ezooms";s:2:"re";s:6:"Ezooms";s:4:"desc";s:49:"http://graphicline.co.za/blogs/what-is-ezooms-bot";s:5:"state";b:1;}i:24;O:8:"stdClass":4:{s:4:"name";s:11:"Majestic 12";s:2:"re";s:11:"Majestic-12";s:4:"desc";s:56:"http://www.majestic12.co.uk/projects/dsearch/mj12bot.php";s:5:"state";b:1;}i:25;O:8:"stdClass":4:{s:4:"name";s:12:"Majestic SEO";s:2:"re";s:12:"Majestic-SEO";s:4:"desc";s:56:"http://www.majestic12.co.uk/projects/dsearch/mj12bot.php";s:5:"state";b:1;}i:26;O:8:"stdClass":4:{s:4:"name";s:7:"DSearch";s:2:"re";s:7:"DSearch";s:4:"desc";s:56:"http://www.majestic12.co.uk/projects/dsearch/mj12bot.php";s:5:"state";b:1;}i:27;O:8:"stdClass":4:{s:4:"name";s:10:"Blekko Bot";s:2:"re";s:9:"BlekkoBot";s:4:"desc";s:33:"http://blekko.com/about/blekkobot";s:5:"state";b:1;}i:28;O:8:"stdClass":4:{s:4:"name";s:6:"Yandex";s:2:"re";s:6:"Yandex";s:4:"desc";s:41:"http://help.yandex.com/search/?id=1112030";s:5:"state";b:0;}i:29;O:8:"stdClass":4:{s:4:"name";s:10:"Google Bot";s:2:"re";s:9:"googlebot";s:4:"desc";s:57:"https://support.google.com/webmasters/answer/182072?hl=en";s:5:"state";b:0;}i:30;O:8:"stdClass":4:{s:4:"name";s:18:"Feedfetcher Google";s:2:"re";s:18:"Feedfetcher-Google";s:4:"desc";s:51:"https://support.google.com/webmasters/answer/178852";s:5:"state";b:0;}i:31;O:8:"stdClass":4:{s:4:"name";s:8:"Bing Bot";s:2:"re";s:7:"BingBot";s:4:"desc";s:36:"http://en.wikipedia.org/wiki/Bingbot";s:5:"state";b:0;}i:32;O:8:"stdClass":4:{s:4:"name";s:9:"Nerdy Bot";s:2:"re";s:8:"NerdyBot";s:4:"desc";s:20:"http://nerdybot.com/";s:5:"state";b:1;}i:33;O:8:"stdClass":4:{s:4:"name";s:9:"James BOT";s:2:"re";s:8:"JamesBOT";s:4:"desc";s:32:"http://cognitiveseo.com/bot.html";s:5:"state";b:1;}i:34;O:8:"stdClass":4:{s:4:"name";s:7:"Tin Eye";s:2:"re";s:6:"TinEye";s:4:"desc";s:34:"http://www.tineye.com/crawler.html";s:5:"state";b:1;}i:35;O:8:"stdClass":4:{s:5:"state";b:1;s:2:"re";s:11:"Baiduspider";s:4:"name";s:5:"Baidu";s:4:"desc";s:47:"http://www.baidu.com/search/robots_english.html";}}';
38
- protected $option_name = 'Niteoweb.SpiderBlocker.Bots';
39
- protected $nonce = 'Niteoweb.SpiderBlocker.Nonce';
40
-
41
- function __construct() {
42
- if ( is_admin() ) {
43
- add_action( 'admin_notices', array( &$this, 'activatePluginNotice' ) );
44
- add_action( 'admin_menu', array( &$this, 'adminMenu' ) );
45
- add_action( 'wp_ajax_NSB-get_list', array( &$this, 'loadList' ) );
46
- add_action( 'wp_ajax_NSB-set_list', array( &$this, 'saveList' ) );
47
- add_action( 'wp_ajax_NSB-reset_list', array( &$this, 'resetList' ) );
48
- }
49
- add_action( 'generate_rewrite_rules', array( &$this, "generateRewriteRules" ) );
50
-
51
- }
52
-
53
- function generateRewriteRules() {
54
- global $wp_rewrite;
55
-
56
- // Protect plugin from direct access
57
- $wp_rewrite->add_external_rule( $this->pluginURL() . 'index.php', 'index.php%{REQUEST_URI}' );
58
- $wp_rewrite->add_external_rule( $this->pluginURL() . 'readme.txt', 'index.php%{REQUEST_URI}' );
59
- $wp_rewrite->add_external_rule( $this->pluginURL(), 'index.php%{REQUEST_URI}' );
60
- }
61
-
62
- /**
63
- * @codeCoverageIgnore
64
- * @return string
65
- */
66
- private function pluginURL() {
67
- $url = wp_make_link_relative( plugin_dir_url( __FILE__ ) );
68
- $url = ltrim( $url, "/" );
69
-
70
- return $url;
71
- }
72
-
73
- function adminMenu() {
74
- add_management_page(
75
- 'SpiderBlocker', 'SpiderBlocker', 'manage_options', 'ni_spider_block', array(
76
- &$this,
77
- 'viewHandler'
78
- )
79
- );
80
- }
81
-
82
- /**
83
- * @codeCoverageIgnore
84
- */
85
- function activatePluginNotice() {
86
- if ( get_option( $this->option_name ) === false ) {
87
- update_option( $this->option_name, $this->default_bots );
88
- ?>
89
- <div class="notice notice-success">
90
- <p>SpiderBlocker plugin has enabled blocking of some bots, please review settings by visiting <a
91
- href="<?php echo admin_url( 'tools.php?page=ni_spider_block' ); ?>">Setting page</a>!</p>
92
- </div>
93
- <?php
94
- }
95
- }
96
-
97
- /**
98
- * @codeCoverageIgnore
99
- */
100
- function activatePlugin() {
101
- if ( ! apache_get_version() ) {
102
- ?>
103
- <div id="error-page">
104
- <p>This plugin requires Apache2 server with mod_rewrite support. Please contact your hosting provider
105
- about
106
- upgrading your server software. Your Apache version is <b><?php echo apache_get_version(); ?></b>
107
- </p>
108
- </div>
109
- <?php
110
- die();
111
- }
112
-
113
- if ( ! SpiderBlocker::isHtaccessWritable() ) {
114
- $state = SpiderBlocker::chmodHtaccess();
115
- if ( ! SpiderBlocker::isHtaccessWritable() || ! $state ) {
116
- ?>
117
- <div id="error-page">
118
- <p>This plugin requires <b>.htaccess</b> file that is writable by the server. Please enable write
119
- access
120
- for file <b><?php echo ABSPATH . '.htaccess'; ?></b>.</p>
121
- </div>
122
- <?php
123
- die();
124
- }
125
- }
126
- $this->generateBlockRules();
127
-
128
- }
129
-
130
- /**
131
- * @codeCoverageIgnore
132
- * @return bool
133
- */
134
- static function isHtaccessWritable() {
135
- $home_path = function_exists( 'get_home_path' ) ? get_home_path() : ABSPATH;
136
- $htaccess_file = $home_path . '.htaccess';
137
-
138
- return is_writable( $htaccess_file );
139
- }
140
-
141
- /**
142
- * @codeCoverageIgnore
143
- *
144
- * @param int $mod octet value for chmod
145
- *
146
- * @return bool
147
- */
148
- static function chmodHtaccess( $mod = 0644 ) {
149
- $home_path = function_exists( 'get_home_path' ) ? get_home_path() : ABSPATH;
150
- $htaccess_file = $home_path . '.htaccess';
151
-
152
- return chmod( $htaccess_file, $mod );
153
- }
154
-
155
- function generateBlockRules() {
156
- global $wp_rewrite;
157
-
158
- $home_path = function_exists( 'get_home_path' ) ? get_home_path() : ABSPATH;
159
- $htaccess_file = $home_path . '.htaccess';
160
-
161
- if ( ( ! file_exists( $htaccess_file ) && is_writable( $home_path ) ) || is_writable( $htaccess_file ) ) {
162
- insert_with_markers( $htaccess_file, 'NiteowebSpiderBlocker', $this->getRules() );
163
- }
164
-
165
- $wp_rewrite->flush_rules();
166
- }
167
-
168
- /**
169
- * Generate block rules based on enabled bots
170
- *
171
- * @return array
172
- */
173
- function getRules() {
174
- $list = array();
175
- foreach ( $this->getBots() as $bot ) {
176
- if ( $bot->state ) {
177
- $list[] = 'SetEnvIfNoCase User-Agent "' . $bot->re . '" block_bot';
178
- }
179
-
180
- }
181
- $list[] = "<Limit GET POST HEAD>";
182
- $list[] = "Order Allow,Deny";
183
- $list[] = "Allow from all";
184
- $list[] = "Deny from env=block_bot";
185
- $list[] = "</Limit>";
186
-
187
- return $list;
188
- }
189
-
190
- private function getBots() {
191
- return maybe_unserialize( get_option( $this->option_name, $this->default_bots ) );
192
- }
193
-
194
- function loadList() {
195
- check_ajax_referer( $this->nonce, 'nonce' );
196
- wp_send_json_success( $this->getBots() );
197
- }
198
-
199
- function resetList() {
200
- check_ajax_referer( $this->nonce, 'nonce' );
201
- delete_option( $this->option_name );
202
- $this->generateBlockRules();
203
- wp_send_json_success( $this->getBots() );
204
- }
205
-
206
- function removeBlockRules() {
207
- global $wp_rewrite;
208
- delete_option( $this->option_name );
209
- $home_path = function_exists( 'get_home_path' ) ? get_home_path() : ABSPATH;
210
- $htaccess_file = $home_path . '.htaccess';
211
- $empty = array();
212
- if ( ( ! file_exists( $htaccess_file ) && is_writable( $home_path ) ) || is_writable( $htaccess_file ) ) {
213
- insert_with_markers( $htaccess_file, 'NiteowebSpiderBlocker', $empty );
214
- }
215
-
216
- $wp_rewrite->flush_rules();
217
- }
218
-
219
- function saveList() {
220
-
221
- check_ajax_referer( $this->nonce, 'nonce' );
222
- $data = json_decode( stripcslashes( $_POST['data'] ) );
223
-
224
- if ( json_last_error() ) {
225
- if ( function_exists( 'json_last_error_msg' ) ) {
226
- wp_send_json_error( json_last_error_msg() );
227
- } else {
228
- wp_send_json_error( 'Failed parsing JSON' );
229
- }
230
-
231
- }
232
- if ( get_option( $this->option_name ) !== false ) {
233
- update_option( $this->option_name, maybe_serialize( $data ) );
234
- } else {
235
- add_option( $this->option_name, maybe_serialize( $data ), null, 'no' );
236
- }
237
-
238
- $this->generateBlockRules();
239
- wp_send_json_success( $this->getBots() );
240
-
241
- }
242
-
243
- /**
244
- * @codeCoverageIgnore
245
- */
246
- function viewHandler() {
247
-
248
- add_thickbox();
249
- var_dump($this->pluginURL());
250
- ?>
251
- <style>
252
- .notice.fixed {
253
- position: fixed;
254
- right: 1em;
255
- top: 3.5em;
256
- }
257
-
258
- tr.active {
259
- background-color: rgba(54, 204, 255, 0.05);
260
- }
261
-
262
- .active th.bot-re {
263
- border-left: 4px solid #2ea2cc;
264
- }
265
- </style>
266
- <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js" type="text/javascript"></script>
267
- <script>
268
- window.sb_nonce = "<?php echo wp_create_nonce($this->nonce); ?>";
269
- -(function () {
270
- var spiderBlockApp = angular.module('spiderBlockApp', []);
271
-
272
- spiderBlockApp.directive('jsonText', function () {
273
- return {
274
- restrict: 'A',
275
- require: 'ngModel',
276
- link: function (scope, element, attr, ngModel) {
277
- function into(input) {
278
- return angular.fromJson(input);
279
- }
280
-
281
- function out(data) {
282
- return angular.toJson(data, true);
283
- }
284
-
285
- ngModel.$parsers.push(into);
286
- ngModel.$formatters.push(out);
287
- }
288
- };
289
- });
290
- spiderBlockApp.controller('NotificationsCtrl', function ($scope, $rootScope, $timeout) {
291
- $scope.notifications = [];
292
-
293
- $rootScope.$on('notification', function (event, data) {
294
- $scope.notifications.push(data);
295
- $timeout(function () {
296
- $scope.removeNotification(data);
297
- }, 3000);
298
- });
299
-
300
- $scope.removeNotification = function (notification) {
301
- var index;
302
- if ($scope.notifications !== undefined) {
303
- index = $scope.notifications.indexOf(notification);
304
- $scope.notifications.splice(index, 1);
305
- }
306
- }
307
- });
308
- spiderBlockApp.controller('BotListCtrl', function ($scope, $http, $rootScope) {
309
- var wp_ajax = function (_req) {
310
- _req.nonce = window.sb_nonce;
311
- return $http({
312
- method: 'POST',
313
- url: ajaxurl,
314
- data: jQuery.param(_req),
315
- headers: {'Content-Type': 'application/x-www-form-urlencoded'}
316
- })
317
- };
318
-
319
- var find_bot = function (re) {
320
- for (var i = $scope.bots.length - 1; i >= 0; i--) {
321
- if ($scope.bots[i]['re'] == re) {
322
- return i;
323
- }
324
- }
325
- return null;
326
- };
327
-
328
- $scope.bot = {"state": true};
329
-
330
- wp_ajax({
331
- action: 'NSB-get_list'
332
- }).success(function (res) {
333
- $scope.bots = res.data;
334
- });
335
-
336
- $scope.save = function () {
337
- wp_ajax({
338
- action: 'NSB-set_list',
339
- data: angular.toJson($scope.bots)
340
- }).success(function (res) {
341
- if (res.success) {
342
- $scope.bots = res.data;
343
- $rootScope.$emit('notification', {
344
- state: 'success',
345
- msg: 'List of bots was saved and new blocklist applied!'
346
- });
347
- } else {
348
- $rootScope.$emit('notification', {state: 'errror', msg: res.data});
349
- }
350
- });
351
- };
352
-
353
- $scope.reset = function () {
354
- wp_ajax({
355
- action: 'NSB-reset_list'
356
- }).success(function (res) {
357
- $scope.bots = res.data;
358
- $rootScope.$emit('notification', {
359
- state: 'success',
360
- msg: 'List of bots was reset to defaults!'
361
- });
362
- });
363
- };
364
-
365
- $scope.add = function () {
366
- $scope.bots.push($scope.bot);
367
- $rootScope.$emit('notification', {
368
- state: 'success',
369
- msg: 'Bot ' + $scope.bot.name + ' was added!'
370
- });
371
- $scope.bot = {"state": true};
372
- };
373
-
374
- $scope.remove = function (at) {
375
- $rootScope.$emit('notification', {state: 'success', msg: 'Bot was removed!'});
376
- $scope.bots.splice(find_bot(at), 1);
377
- };
378
- });
379
- })(angular, document, jQuery);
380
- </script>
381
- <h1>Spider Blocker</h1>
382
- <hr/>
383
- <div ng-app="spiderBlockApp">
384
- <div ng-controller="NotificationsCtrl">
385
- <div class="notice notice-{{ n.state }} fixed" ng-repeat="n in notifications"
386
- style="top: {{3.5*($index+1)}}em">
387
- <p>{{n.msg}}
388
- <a ng-click="removeNotification(notification)">
389
- <span class="dashicons dashicons-no-alt"></span>
390
- </a>
391
- </p>
392
- </div>
393
- </div>
394
-
395
-
396
- <div ng-controller="BotListCtrl">
397
- <h2>Add New Bot</h2>
398
-
399
- <form name="add_form" ng-submit="add()">
400
- <table class="form-table">
401
- <tbody>
402
- <tr>
403
- <th scope="row"><label>User Agent</label></th>
404
- <td><input bots="bots" ng-model='bot.re' class="regular-text"
405
- required/></td>
406
- </tr>
407
- <tr>
408
- <th scope="row"><label>Bot Name</label></th>
409
- <td><input type="text" ng-model='bot.name' class="regular-text" required/></td>
410
- </tr>
411
- <tr>
412
- <tr>
413
- <th scope="row"><label>Bot Description URL</label></th>
414
- <td><input type="url" ng-model='bot.desc' class="regular-text" placeholder="http://"/>
415
- </td>
416
- </tr>
417
- </tbody>
418
- </table>
419
- <p class="submit"><input ng-disabled="add_form.$invalid" type="submit"
420
- class="button button-primary" value="Add Bot"></p>
421
- </form>
422
- <h2>List of bots</h2>
423
- <ng-form class="search-box">
424
- <input size="35" type="search" id="ua-search-input" ng-model="query" placeholder="Filter...">
425
- </ng-form>
426
- <table class="wp-list-table widefat bots">
427
- <thead>
428
- <tr>
429
-
430
- <th scope="col" class="manage-column column-description">
431
- <a href=""
432
- ng-click="predicate = 're'; reverse=false">User
433
- Agent <span class="dashicons dashicons-sort"></span></a></th>
434
-
435
- <th scope="col" class="manage-column column-name">Name</th>
436
- <th scope="col" class="manage-column column-state">
437
- <a href=""
438
- ng-click="predicate = 'state'; reverse=false">State <span
439
- class="dashicons dashicons-sort"></span></a>
440
- </th>
441
- <th scope="col" id="action" class="manage-column column-action">Action</th>
442
- </tr>
443
- </thead>
444
-
445
- <tfoot>
446
- <tr>
447
-
448
- <th scope="col" class="manage-column column-description"><a href=""
449
- ng-click="predicate = 're'; reverse=false">User
450
- Agent</a></th>
451
-
452
- <th scope="col" class="manage-column column-name">Name</th>
453
- <th scope="col" class="manage-column column-state"><a href=""
454
- ng-click="predicate = 'state'; reverse=false">State</a>
455
- </th>
456
- <th scope="col" id="action" class="manage-column column-action">Action</th>
457
- </tr>
458
- </tfoot>
459
-
460
- <tbody id="the-list">
461
- <tr id="spider-blocker" ng-repeat="bot in bots | filter:query | orderBy:predicate:reverse"
462
- ng-class="{'active': bot.state}">
463
-
464
- <th class="bot-re"> {{ bot.re }}</th>
465
- <td class="bot-title"><strong>{{ bot.name }}</strong> <a target="_blank"
466
- ng-href="{{bot.desc}}">{{
467
- bot.desc }}</a></td>
468
- <th class="expression" ng-class="{'blocked':bot.state}"> {{ bot.state?"Blocked":"Allowed"
469
- }}
470
- </th>
471
- <td class="actions">
472
- <input ng-hide="bot.state" type="button" ng-click="bot.state=true"
473
- class="button button-primary" value="Block">
474
- <input ng-show="bot.state" type="button" ng-click="bot.state=false"
475
- class="button button-secondary" value="Allow">
476
- <input type="button" ng-click="remove(bot.re)" class="button button-secondary"
477
- value="Remove">
478
- </td>
479
- </tr>
480
- </tbody>
481
- </table>
482
- <div id="rules-export-import" style="display:none;">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
483
  <textarea
484
- style="-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;width: 100%;height: 99%;"
485
- json-text ng-model="bots"></textarea>
486
- </div>
487
- <p class="submit">
488
- <input type="button" class="button button-primary" ng-click="save()" value="Save">
489
- <input type="button" class="button button-primary" ng-click="reset()" value="Reset to Defaults">
490
- <a href="#TB_inline?width=540&height=360&inlineId=rules-export-import"
491
- class="thickbox button button-secondary">Import/Export Definitions</a>
492
- </p>
493
-
494
- </div>
495
- </div>
496
- <?php
497
- }
498
 
499
 
500
  }
501
 
502
  // Inside WordPress
503
- if ( defined( 'ABSPATH' ) ) {
504
- $NiteowebSpiderBlocker_ins = new SpiderBlocker;
505
- register_activation_hook( __FILE__, array( &$NiteowebSpiderBlocker_ins, 'activatePlugin' ) );
506
- register_deactivation_hook( __FILE__, array( &$NiteowebSpiderBlocker_ins, 'removeBlockRules' ) );
507
  }
3
  /**
4
  * Plugin Name: Spider Blocker
5
  * Description: Spider Blocker will block most common bots that consume bandwidth and slow down your server.
6
+ * Version: 1.0.11
7
  * Runtime: 5.3+
8
  * Author: Easy Blog Networks
9
  * Author URI: www.easyblognetworks.com
10
  */
11
 
12
+ if (!function_exists('apache_get_version')) {
13
+ function apache_get_version()
14
+ {
15
+ if (stristr($_ENV["SERVER_SOFTWARE"], 'Apache')) {
16
+ return $_ENV["SERVER_SOFTWARE"];
17
+ }
18
+ if (stristr($_SERVER["SERVER_SOFTWARE"], 'Apache')) {
19
+ return $_SERVER["SERVER_SOFTWARE"];
20
+ }
21
+ return false;
22
+ }
23
  }
24
 
25
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
26
+ ?>
27
+ <div id="error-page">
28
+ <p>This plugin requires PHP 5.3.0 or higher. Please contact your hosting provider about upgrading your
29
+ server software. Your PHP version is <b><?php echo PHP_VERSION; ?></b></p>
30
+ </div>
31
+ <?php
32
+ die();
33
  }
34
 
35
 
36
+ class SpiderBlocker
37
+ {
38
+
39
+ public $default_bots = 'a:36:{i:0;O:8:"stdClass":4:{s:4:"name";s:10:"Ahrefs Bot";s:2:"re";s:9:"AhrefsBot";s:4:"desc";s:25:"https://ahrefs.com/robot/";s:5:"state";b:1;}i:1;O:8:"stdClass":4:{s:4:"name";s:8:"MJ12 bot";s:2:"re";s:7:"MJ12bot";s:4:"desc";s:56:"http://www.majestic12.co.uk/projects/dsearch/mj12bot.php";s:5:"state";b:1;}i:2;O:8:"stdClass":4:{s:4:"name";s:9:"Roger Bot";s:2:"re";s:8:"Rogerbot";s:4:"desc";s:40:"http://moz.com/help/pro/rogerbot-crawler";s:5:"state";b:1;}i:3;O:8:"stdClass":4:{s:4:"name";s:11:"Semrush Bot";s:2:"re";s:10:"SemrushBot";s:4:"desc";s:31:"http://www.semrush.com/bot.html";s:5:"state";b:1;}i:4;O:8:"stdClass":4:{s:4:"name";s:11:"ia_archiver";s:2:"re";s:11:"ia_archiver";s:4:"desc";s:36:"http://archive.org/about/exclude.php";s:5:"state";b:1;}i:5;O:8:"stdClass":4:{s:4:"name";s:8:"ScoutJet";s:2:"re";s:8:"ScoutJet";s:4:"desc";s:19:"http://scoutjet.com";s:5:"state";b:1;}i:6;O:8:"stdClass":4:{s:4:"name";s:7:"sistrix";s:2:"re";s:7:"sistrix";s:4:"desc";s:26:"http://crawler.sistrix.net";s:5:"state";b:1;}i:7;O:8:"stdClass":4:{s:4:"name";s:16:"SearchmetricsBot";s:2:"re";s:16:"SearchmetricsBot";s:4:"desc";s:50:"http://www.searchmetrics.com/en/searchmetrics-bot/";s:5:"state";b:1;}i:8;O:8:"stdClass":4:{s:4:"name";s:14:"SEOkicks-Robot";s:2:"re";s:14:"SEOkicks-Robot";s:4:"desc";s:33:"http://www.seokicks.de/robot.html";s:5:"state";b:1;}i:9;O:8:"stdClass":4:{s:4:"name";s:16:"Lipperhey Spider";s:2:"re";s:16:"Lipperhey Spider";s:4:"desc";s:43:"http://www.lipperhey.com/en/website-spider/";s:5:"state";b:1;}i:10;O:8:"stdClass":4:{s:4:"name";s:6:"Exabot";s:2:"re";s:6:"Exabot";s:4:"desc";s:44:"http://www.exalead.com/search/webmasterguide";s:5:"state";b:1;}i:11;O:8:"stdClass":4:{s:4:"name";s:6:"NC Bot";s:2:"re";s:5:"NCBot";s:4:"desc";s:55:"https://twitter.com/NetComber/status/334476871691550721";s:5:"state";b:1;}i:12;O:8:"stdClass":4:{s:4:"name";s:15:"BacklinkCrawler";s:2:"re";s:15:"BacklinkCrawler";s:4:"desc";s:40:"http://www.backlinktest.com/crawler.html";s:5:"state";b:1;}i:13;O:8:"stdClass":4:{s:4:"name";s:15:"archive.org Bot";s:2:"re";s:15:"archive.org_bot";s:4:"desc";s:42:"http://archive.org/details/archive.org_bot";s:5:"state";b:1;}i:14;O:8:"stdClass":4:{s:4:"name";s:12:"MeanPath Bot";s:2:"re";s:11:"meanpathbot";s:4:"desc";s:37:"https://meanpath.com/meanpathbot.html";s:5:"state";b:1;}i:15;O:8:"stdClass":4:{s:4:"name";s:18:"PagesInventory Bot";s:2:"re";s:14:"PagesInventory";s:4:"desc";s:56:"http://www.botsvsbrowsers.com/details/1002332/index.html";s:5:"state";b:1;}i:16;O:8:"stdClass":4:{s:4:"name";s:12:"Aboundex Bot";s:2:"re";s:11:"Aboundexbot";s:4:"desc";s:32:"http://www.aboundex.com/crawler/";s:5:"state";b:1;}i:17;O:8:"stdClass":4:{s:4:"name";s:15:"SeoProfiler Bot";s:2:"re";s:5:"spbot";s:4:"desc";s:31:"http://www.seoprofiler.com/bot/";s:5:"state";b:1;}i:18;O:8:"stdClass":4:{s:4:"name";s:11:"Linkdex Bot";s:2:"re";s:10:"linkdexbot";s:4:"desc";s:34:"http://www.linkdex.com/about/bots/";s:5:"state";b:1;}i:19;O:8:"stdClass":4:{s:4:"name";s:7:"Gigabot";s:2:"re";s:7:"Gigabot";s:4:"desc";s:45:"http://www.useragentstring.com/pages/Gigabot/";s:5:"state";b:1;}i:20;O:8:"stdClass":4:{s:4:"name";s:6:"DotBot";s:2:"re";s:6:"dotbot";s:4:"desc";s:35:"http://en.wikipedia.org/wiki/DotBot";s:5:"state";b:1;}i:21;O:8:"stdClass":4:{s:4:"name";s:5:"Nutch";s:2:"re";s:5:"Nutch";s:4:"desc";s:32:"http://nutch.apache.org/bot.html";s:5:"state";b:1;}i:22;O:8:"stdClass":4:{s:4:"name";s:8:"BLEX Bot";s:2:"re";s:7:"BLEXBot";s:4:"desc";s:27:"http://webmeup-crawler.com/";s:5:"state";b:1;}i:23;O:8:"stdClass":4:{s:4:"name";s:6:"Ezooms";s:2:"re";s:6:"Ezooms";s:4:"desc";s:49:"http://graphicline.co.za/blogs/what-is-ezooms-bot";s:5:"state";b:1;}i:24;O:8:"stdClass":4:{s:4:"name";s:11:"Majestic 12";s:2:"re";s:11:"Majestic-12";s:4:"desc";s:56:"http://www.majestic12.co.uk/projects/dsearch/mj12bot.php";s:5:"state";b:1;}i:25;O:8:"stdClass":4:{s:4:"name";s:12:"Majestic SEO";s:2:"re";s:12:"Majestic-SEO";s:4:"desc";s:56:"http://www.majestic12.co.uk/projects/dsearch/mj12bot.php";s:5:"state";b:1;}i:26;O:8:"stdClass":4:{s:4:"name";s:7:"DSearch";s:2:"re";s:7:"DSearch";s:4:"desc";s:56:"http://www.majestic12.co.uk/projects/dsearch/mj12bot.php";s:5:"state";b:1;}i:27;O:8:"stdClass":4:{s:4:"name";s:10:"Blekko Bot";s:2:"re";s:9:"BlekkoBot";s:4:"desc";s:33:"http://blekko.com/about/blekkobot";s:5:"state";b:1;}i:28;O:8:"stdClass":4:{s:4:"name";s:6:"Yandex";s:2:"re";s:6:"Yandex";s:4:"desc";s:41:"http://help.yandex.com/search/?id=1112030";s:5:"state";b:0;}i:29;O:8:"stdClass":4:{s:4:"name";s:10:"Google Bot";s:2:"re";s:9:"googlebot";s:4:"desc";s:57:"https://support.google.com/webmasters/answer/182072?hl=en";s:5:"state";b:0;}i:30;O:8:"stdClass":4:{s:4:"name";s:18:"Feedfetcher Google";s:2:"re";s:18:"Feedfetcher-Google";s:4:"desc";s:51:"https://support.google.com/webmasters/answer/178852";s:5:"state";b:0;}i:31;O:8:"stdClass":4:{s:4:"name";s:8:"Bing Bot";s:2:"re";s:7:"BingBot";s:4:"desc";s:36:"http://en.wikipedia.org/wiki/Bingbot";s:5:"state";b:0;}i:32;O:8:"stdClass":4:{s:4:"name";s:9:"Nerdy Bot";s:2:"re";s:8:"NerdyBot";s:4:"desc";s:20:"http://nerdybot.com/";s:5:"state";b:1;}i:33;O:8:"stdClass":4:{s:4:"name";s:9:"James BOT";s:2:"re";s:8:"JamesBOT";s:4:"desc";s:32:"http://cognitiveseo.com/bot.html";s:5:"state";b:1;}i:34;O:8:"stdClass":4:{s:4:"name";s:7:"Tin Eye";s:2:"re";s:6:"TinEye";s:4:"desc";s:34:"http://www.tineye.com/crawler.html";s:5:"state";b:1;}i:35;O:8:"stdClass":4:{s:5:"state";b:1;s:2:"re";s:11:"Baiduspider";s:4:"name";s:5:"Baidu";s:4:"desc";s:47:"http://www.baidu.com/search/robots_english.html";}}';
40
+ protected $option_name = 'Niteoweb.SpiderBlocker.Bots';
41
+ protected $nonce = 'Niteoweb.SpiderBlocker.Nonce';
42
+
43
+ function __construct()
44
+ {
45
+ if (is_admin()) {
46
+ add_action('admin_notices', array(&$this, 'activatePluginNotice'));
47
+ add_action('admin_menu', array(&$this, 'adminMenu'));
48
+ add_action('wp_ajax_NSB-get_list', array(&$this, 'loadList'));
49
+ add_action('wp_ajax_NSB-set_list', array(&$this, 'saveList'));
50
+ add_action('wp_ajax_NSB-reset_list', array(&$this, 'resetList'));
51
+ }
52
+ add_action('generate_rewrite_rules', array(&$this, "generateRewriteRules"));
53
+
54
+ }
55
+
56
+ function generateRewriteRules()
57
+ {
58
+ global $wp_rewrite;
59
+
60
+ // Protect plugin from direct access
61
+ $wp_rewrite->add_external_rule($this->pluginURL() . 'index.php', 'index.php%{REQUEST_URI}');
62
+ $wp_rewrite->add_external_rule($this->pluginURL() . 'readme.txt', 'index.php%{REQUEST_URI}');
63
+ $wp_rewrite->add_external_rule($this->pluginURL(), 'index.php%{REQUEST_URI}');
64
+ }
65
+
66
+ /**
67
+ * @codeCoverageIgnore
68
+ * @return string
69
+ */
70
+ private function pluginURL()
71
+ {
72
+ $url = wp_make_link_relative(plugin_dir_url(__FILE__));
73
+ $url = ltrim($url, "/");
74
+
75
+ return $url;
76
+ }
77
+
78
+ function adminMenu()
79
+ {
80
+ add_management_page(
81
+ 'SpiderBlocker', 'SpiderBlocker', 'manage_options', 'ni_spider_block', array(
82
+ &$this,
83
+ 'viewHandler'
84
+ )
85
+ );
86
+ }
87
+
88
+ /**
89
+ * @codeCoverageIgnore
90
+ */
91
+ function activatePluginNotice()
92
+ {
93
+ if (get_option($this->option_name) === false) {
94
+ update_option($this->option_name, $this->default_bots);
95
+ ?>
96
+ <div class="notice notice-success">
97
+ <p>SpiderBlocker plugin has enabled blocking of some bots, please review settings by visiting <a
98
+ href="<?php echo admin_url('tools.php?page=ni_spider_block'); ?>">Setting page</a>!</p>
99
+ </div>
100
+ <?php
101
+ }
102
+ }
103
+
104
+ /**
105
+ * @codeCoverageIgnore
106
+ */
107
+ function activatePlugin()
108
+ {
109
+ if (!apache_get_version()) {
110
+ ?>
111
+ <div id="error-page">
112
+ <p>This plugin requires Apache2 server with mod_rewrite support. Please contact your hosting provider
113
+ about
114
+ upgrading your server software. Your Apache version is <b><?php echo apache_get_version(); ?></b>
115
+ </p>
116
+ </div>
117
+ <?php
118
+ die();
119
+ }
120
+
121
+ if (!SpiderBlocker::isHtaccessWritable()) {
122
+ $state = SpiderBlocker::chmodHtaccess();
123
+ if (!SpiderBlocker::isHtaccessWritable() || !$state) {
124
+ ?>
125
+ <div id="error-page">
126
+ <p>This plugin requires <b>.htaccess</b> file that is writable by the server. Please enable write
127
+ access
128
+ for file <b><?php echo ABSPATH . '.htaccess'; ?></b>.</p>
129
+ </div>
130
+ <?php
131
+ die();
132
+ }
133
+ }
134
+ $this->generateBlockRules();
135
+
136
+ }
137
+
138
+ /**
139
+ * @codeCoverageIgnore
140
+ * @return bool
141
+ */
142
+ static function isHtaccessWritable()
143
+ {
144
+ $htaccess_file = SpiderBlocker::joinPaths(ABSPATH, '.htaccess');
145
+ return is_writable($htaccess_file);
146
+ }
147
+
148
+ /**
149
+ * @codeCoverageIgnore
150
+ * @return string
151
+ */
152
+ static function joinPaths()
153
+ {
154
+ $paths = array();
155
+
156
+ foreach (func_get_args() as $arg) {
157
+ if ($arg !== '') {
158
+ $paths[] = $arg;
159
+ }
160
+ }
161
+
162
+ return preg_replace('#/+#', '/', join('/', $paths));
163
+ }
164
+
165
+ /**
166
+ * @codeCoverageIgnore
167
+ *
168
+ * @param int $mod octet value for chmod
169
+ *
170
+ * @return bool
171
+ */
172
+ static function chmodHtaccess($mod = 0644)
173
+ {
174
+ $home_path = function_exists('get_home_path') ? get_home_path() : ABSPATH;
175
+ $htaccess_file = $home_path . '.htaccess';
176
+
177
+ return chmod($htaccess_file, $mod);
178
+ }
179
+
180
+ function generateBlockRules()
181
+ {
182
+ global $wp_rewrite;
183
+
184
+ $home_path = function_exists('get_home_path') ? get_home_path() : ABSPATH;
185
+ $htaccess_file = $home_path . '.htaccess';
186
+
187
+ if ((!file_exists($htaccess_file) && is_writable($home_path)) || is_writable($htaccess_file)) {
188
+ insert_with_markers($htaccess_file, 'NiteowebSpiderBlocker', $this->getRules());
189
+ }
190
+
191
+ $wp_rewrite->flush_rules();
192
+ }
193
+
194
+ /**
195
+ * Generate block rules based on enabled bots
196
+ *
197
+ * @return array
198
+ */
199
+ function getRules()
200
+ {
201
+ $list = array();
202
+ foreach ($this->getBots() as $bot) {
203
+ if ($bot->state) {
204
+ $list[] = 'SetEnvIfNoCase User-Agent "' . $bot->re . '" block_bot';
205
+ }
206
+
207
+ }
208
+ $list[] = "<Limit GET POST HEAD>";
209
+ $list[] = "Order Allow,Deny";
210
+ $list[] = "Allow from all";
211
+ $list[] = "Deny from env=block_bot";
212
+ $list[] = "</Limit>";
213
+
214
+ return $list;
215
+ }
216
+
217
+ private function getBots()
218
+ {
219
+ return maybe_unserialize(get_option($this->option_name, $this->default_bots));
220
+ }
221
+
222
+ function loadList()
223
+ {
224
+ check_ajax_referer($this->nonce, 'nonce');
225
+ wp_send_json_success($this->getBots());
226
+ }
227
+
228
+ function resetList()
229
+ {
230
+ check_ajax_referer($this->nonce, 'nonce');
231
+ delete_option($this->option_name);
232
+ $this->generateBlockRules();
233
+ wp_send_json_success($this->getBots());
234
+ }
235
+
236
+ function removeBlockRules()
237
+ {
238
+ global $wp_rewrite;
239
+ delete_option($this->option_name);
240
+ $home_path = function_exists('get_home_path') ? get_home_path() : ABSPATH;
241
+ $htaccess_file = $home_path . '.htaccess';
242
+ $empty = array();
243
+ if ((!file_exists($htaccess_file) && is_writable($home_path)) || is_writable($htaccess_file)) {
244
+ insert_with_markers($htaccess_file, 'NiteowebSpiderBlocker', $empty);
245
+ }
246
+
247
+ $wp_rewrite->flush_rules();
248
+ }
249
+
250
+ function saveList()
251
+ {
252
+
253
+ check_ajax_referer($this->nonce, 'nonce');
254
+ $data = json_decode(stripcslashes($_POST['data']));
255
+
256
+ if (json_last_error()) {
257
+ if (function_exists('json_last_error_msg')) {
258
+ wp_send_json_error(json_last_error_msg());
259
+ } else {
260
+ wp_send_json_error('Failed parsing JSON');
261
+ }
262
+
263
+ }
264
+ if (get_option($this->option_name) !== false) {
265
+ update_option($this->option_name, maybe_serialize($data));
266
+ } else {
267
+ add_option($this->option_name, maybe_serialize($data), null, 'no');
268
+ }
269
+
270
+ $this->generateBlockRules();
271
+ wp_send_json_success($this->getBots());
272
+
273
+ }
274
+
275
+ /**
276
+ * @codeCoverageIgnore
277
+ */
278
+ function viewHandler()
279
+ {
280
+
281
+ add_thickbox();
282
+ ?>
283
+ <style>
284
+ .notice.fixed {
285
+ position: fixed;
286
+ right: 1em;
287
+ top: 3.5em;
288
+ }
289
+
290
+ tr.active {
291
+ background-color: rgba(54, 204, 255, 0.05);
292
+ }
293
+
294
+ .active th.bot-re {
295
+ border-left: 4px solid #2ea2cc;
296
+ }
297
+ </style>
298
+ <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"
299
+ type="text/javascript"></script>
300
+ <script>
301
+ window.sb_nonce = "<?php echo wp_create_nonce($this->nonce); ?>";
302
+ -(function () {
303
+ var spiderBlockApp = angular.module('spiderBlockApp', []);
304
+
305
+ spiderBlockApp.directive('jsonText', function () {
306
+ return {
307
+ restrict: 'A',
308
+ require: 'ngModel',
309
+ link: function (scope, element, attr, ngModel) {
310
+ function into(input) {
311
+ return angular.fromJson(input);
312
+ }
313
+
314
+ function out(data) {
315
+ return angular.toJson(data, true);
316
+ }
317
+
318
+ ngModel.$parsers.push(into);
319
+ ngModel.$formatters.push(out);
320
+ }
321
+ };
322
+ });
323
+ spiderBlockApp.controller('NotificationsCtrl', function ($scope, $rootScope, $timeout) {
324
+ $scope.notifications = [];
325
+
326
+ $rootScope.$on('notification', function (event, data) {
327
+ $scope.notifications.push(data);
328
+ $timeout(function () {
329
+ $scope.removeNotification(data);
330
+ }, 3000);
331
+ });
332
+
333
+ $scope.removeNotification = function (notification) {
334
+ var index;
335
+ if ($scope.notifications !== undefined) {
336
+ index = $scope.notifications.indexOf(notification);
337
+ $scope.notifications.splice(index, 1);
338
+ }
339
+ }
340
+ });
341
+ spiderBlockApp.controller('BotListCtrl', function ($scope, $http, $rootScope) {
342
+ var wp_ajax = function (_req) {
343
+ _req.nonce = window.sb_nonce;
344
+ return $http({
345
+ method: 'POST',
346
+ url: ajaxurl,
347
+ data: jQuery.param(_req),
348
+ headers: {'Content-Type': 'application/x-www-form-urlencoded'}
349
+ })
350
+ };
351
+
352
+ var find_bot = function (re) {
353
+ for (var i = $scope.bots.length - 1; i >= 0; i--) {
354
+ if ($scope.bots[i]['re'] == re) {
355
+ return i;
356
+ }
357
+ }
358
+ return null;
359
+ };
360
+
361
+ $scope.bot = {"state": true};
362
+
363
+ wp_ajax({
364
+ action: 'NSB-get_list'
365
+ }).success(function (res) {
366
+ $scope.bots = res.data;
367
+ });
368
+
369
+ $scope.save = function () {
370
+ wp_ajax({
371
+ action: 'NSB-set_list',
372
+ data: angular.toJson($scope.bots)
373
+ }).success(function (res) {
374
+ if (res.success) {
375
+ $scope.bots = res.data;
376
+ $rootScope.$emit('notification', {
377
+ state: 'success',
378
+ msg: 'List of bots was saved and new blocklist applied!'
379
+ });
380
+ } else {
381
+ $rootScope.$emit('notification', {state: 'errror', msg: res.data});
382
+ }
383
+ });
384
+ };
385
+
386
+ $scope.reset = function () {
387
+ wp_ajax({
388
+ action: 'NSB-reset_list'
389
+ }).success(function (res) {
390
+ $scope.bots = res.data;
391
+ $rootScope.$emit('notification', {
392
+ state: 'success',
393
+ msg: 'List of bots was reset to defaults!'
394
+ });
395
+ });
396
+ };
397
+
398
+ $scope.add = function () {
399
+ $scope.bots.push($scope.bot);
400
+ $rootScope.$emit('notification', {
401
+ state: 'success',
402
+ msg: 'Bot ' + $scope.bot.name + ' was added!'
403
+ });
404
+ $scope.bot = {"state": true};
405
+ };
406
+
407
+ $scope.remove = function (at) {
408
+ $rootScope.$emit('notification', {state: 'success', msg: 'Bot was removed!'});
409
+ $scope.bots.splice(find_bot(at), 1);
410
+ };
411
+ });
412
+ })(angular, document, jQuery);
413
+ </script>
414
+ <h1>Spider Blocker</h1>
415
+ <hr/>
416
+ <div ng-app="spiderBlockApp">
417
+ <div ng-controller="NotificationsCtrl">
418
+ <div class="notice notice-{{ n.state }} fixed" ng-repeat="n in notifications"
419
+ style="top: {{3.5*($index+1)}}em">
420
+ <p>{{n.msg}}
421
+ <a ng-click="removeNotification(notification)">
422
+ <span class="dashicons dashicons-no-alt"></span>
423
+ </a>
424
+ </p>
425
+ </div>
426
+ </div>
427
+
428
+
429
+ <div ng-controller="BotListCtrl">
430
+ <h2>Add New Bot</h2>
431
+
432
+ <form name="add_form" ng-submit="add()">
433
+ <table class="form-table">
434
+ <tbody>
435
+ <tr>
436
+ <th scope="row"><label>User Agent</label></th>
437
+ <td><input bots="bots" ng-model='bot.re' class="regular-text"
438
+ required/></td>
439
+ </tr>
440
+ <tr>
441
+ <th scope="row"><label>Bot Name</label></th>
442
+ <td><input type="text" ng-model='bot.name' class="regular-text" required/></td>
443
+ </tr>
444
+ <tr>
445
+ <tr>
446
+ <th scope="row"><label>Bot Description URL</label></th>
447
+ <td><input type="url" ng-model='bot.desc' class="regular-text" placeholder="http://"/>
448
+ </td>
449
+ </tr>
450
+ </tbody>
451
+ </table>
452
+ <p class="submit"><input ng-disabled="add_form.$invalid" type="submit"
453
+ class="button button-primary" value="Add Bot"></p>
454
+ </form>
455
+ <h2>List of bots</h2>
456
+ <ng-form class="search-box">
457
+ <input size="35" type="search" id="ua-search-input" ng-model="query" placeholder="Filter...">
458
+ </ng-form>
459
+ <table class="wp-list-table widefat bots">
460
+ <thead>
461
+ <tr>
462
+
463
+ <th scope="col" class="manage-column column-description">
464
+ <a href=""
465
+ ng-click="predicate = 're'; reverse=false">User
466
+ Agent <span class="dashicons dashicons-sort"></span></a></th>
467
+
468
+ <th scope="col" class="manage-column column-name">Name</th>
469
+ <th scope="col" class="manage-column column-state">
470
+ <a href=""
471
+ ng-click="predicate = 'state'; reverse=false">State <span
472
+ class="dashicons dashicons-sort"></span></a>
473
+ </th>
474
+ <th scope="col" id="action" class="manage-column column-action">Action</th>
475
+ </tr>
476
+ </thead>
477
+
478
+ <tfoot>
479
+ <tr>
480
+
481
+ <th scope="col" class="manage-column column-description"><a href=""
482
+ ng-click="predicate = 're'; reverse=false">User
483
+ Agent</a></th>
484
+
485
+ <th scope="col" class="manage-column column-name">Name</th>
486
+ <th scope="col" class="manage-column column-state"><a href=""
487
+ ng-click="predicate = 'state'; reverse=false">State</a>
488
+ </th>
489
+ <th scope="col" id="action" class="manage-column column-action">Action</th>
490
+ </tr>
491
+ </tfoot>
492
+
493
+ <tbody id="the-list">
494
+ <tr id="spider-blocker" ng-repeat="bot in bots | filter:query | orderBy:predicate:reverse"
495
+ ng-class="{'active': bot.state}">
496
+
497
+ <th class="bot-re"> {{ bot.re }}</th>
498
+ <td class="bot-title"><strong>{{ bot.name }}</strong> <a target="_blank"
499
+ ng-href="{{bot.desc}}">{{
500
+ bot.desc }}</a></td>
501
+ <th class="expression" ng-class="{'blocked':bot.state}"> {{ bot.state?"Blocked":"Allowed"
502
+ }}
503
+ </th>
504
+ <td class="actions">
505
+ <input ng-hide="bot.state" type="button" ng-click="bot.state=true"
506
+ class="button button-primary" value="Block">
507
+ <input ng-show="bot.state" type="button" ng-click="bot.state=false"
508
+ class="button button-secondary" value="Allow">
509
+ <input type="button" ng-click="remove(bot.re)" class="button button-secondary"
510
+ value="Remove">
511
+ </td>
512
+ </tr>
513
+ </tbody>
514
+ </table>
515
+ <div id="rules-export-import" style="display:none;">
516
  <textarea
517
+ style="-webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box;width: 100%;height: 99%;"
518
+ json-text ng-model="bots"></textarea>
519
+ </div>
520
+ <p class="submit">
521
+ <input type="button" class="button button-primary" ng-click="save()" value="Save">
522
+ <input type="button" class="button button-primary" ng-click="reset()" value="Reset to Defaults">
523
+ <a href="#TB_inline?width=540&height=360&inlineId=rules-export-import"
524
+ class="thickbox button button-secondary">Import/Export Definitions</a>
525
+ </p>
526
+
527
+ </div>
528
+ </div>
529
+ <?php
530
+ }
531
 
532
 
533
  }
534
 
535
  // Inside WordPress
536
+ if (defined('ABSPATH')) {
537
+ $NiteowebSpiderBlocker_ins = new SpiderBlocker;
538
+ register_activation_hook(__FILE__, array(&$NiteowebSpiderBlocker_ins, 'activatePlugin'));
539
+ register_deactivation_hook(__FILE__, array(&$NiteowebSpiderBlocker_ins, 'removeBlockRules'));
540
  }