Defender Security – Malware Scanner, Login Security & Firewall - Version 1.7.1

Version Description

Download this release

Release Info

Developer hoang1213
Plugin Icon 128x128 Defender Security – Malware Scanner, Login Security & Firewall
Version 1.7.1
Comparing to
See all releases

Code changes from version 1.7.0.1 to 1.7.1

Files changed (57) hide show
  1. app/behavior/utils.php +150 -17
  2. app/controller/dashboard.php +1 -0
  3. app/module/advanced-tools/behavior/at-widget.php +57 -0
  4. app/module/advanced-tools/component/auth-api.php +1 -0
  5. app/module/advanced-tools/controller/main.php +1 -1
  6. app/module/advanced-tools/view/login/otp.php +1 -1
  7. app/module/hardener/behavior/widget.php +2 -2
  8. app/module/hardener/component/hide-error-service.php +2 -1
  9. app/module/hardener/component/login-duration.php +8 -4
  10. app/module/hardener/js/scripts.js +16 -1
  11. app/module/hardener/readme +0 -1
  12. app/module/hardener/view/ignore.php +1 -1
  13. app/module/hardener/view/issues.php +1 -1
  14. app/module/hardener/view/layouts/layout.php +51 -47
  15. app/module/hardener/view/rules/change-admin.php +2 -2
  16. app/module/hardener/view/rules/db-prefix.php +2 -2
  17. app/module/hardener/view/rules/disable-file-editor.php +2 -2
  18. app/module/hardener/view/rules/disable-trackback.php +2 -2
  19. app/module/hardener/view/rules/hide-error.php +3 -3
  20. app/module/hardener/view/rules/login-duration.php +3 -3
  21. app/module/hardener/view/rules/php-version.php +2 -2
  22. app/module/hardener/view/rules/prevent-php-executed.php +2 -2
  23. app/module/hardener/view/rules/protect-information.php +3 -10
  24. app/module/hardener/view/rules/security-key.php +2 -2
  25. app/module/hardener/view/rules/wp-version.php +2 -2
  26. app/module/ip-lockout/behavior/widget.php +1 -1
  27. app/module/ip-lockout/component/ip-api.php +150 -0
  28. app/module/ip-lockout/component/login-protection-api.php +73 -3
  29. app/module/ip-lockout/component/logs-table.php +69 -0
  30. app/module/ip-lockout/controller/main.php +39 -12
  31. app/module/ip-lockout/model/ip-model.php +68 -0
  32. app/module/ip-lockout/model/log-model.php +1 -0
  33. app/module/ip-lockout/model/settings.php +7 -1
  34. app/module/ip-lockout/view/notification/enabled.php +60 -1
  35. app/module/scan.php +8 -0
  36. app/module/scan/component/result-table.php +2 -2
  37. app/module/scan/component/scan-api.php +2 -0
  38. app/module/scan/model/settings.php +1 -1
  39. app/module/scan/view/cleaned.php +1 -1
  40. app/module/scan/view/ignored.php +1 -1
  41. app/module/scan/view/issues.php +1 -1
  42. app/module/scan/view/layouts/layout.php +66 -62
  43. app/module/scan/view/pro-feature.php +4 -4
  44. app/module/scan/view/scanning.php +1 -1
  45. app/module/scan/view/setting-free.php +16 -18
  46. app/module/scan/view/setting.php +49 -23
  47. app/view/dashboard.php +20 -14
  48. assets/css/styles.css +21 -5
  49. changelog.txt +10 -1
  50. languages/wpdef-default.pot +325 -203
  51. main-activator.php +16 -6
  52. readme.txt +6 -0
  53. uninstall.php +3 -1
  54. vendor/hammer/base/model.php +4 -0
  55. vendor/hammer/bootstrap.php +1 -1
  56. vendor/hammer/vendor/wixel/gump/gump.class.php +2011 -2056
  57. wp-defender.php +2 -1
app/behavior/utils.php CHANGED
@@ -8,7 +8,9 @@ namespace WP_Defender\Behavior;
8
  use Hammer\Base\Behavior;
9
  use Hammer\Helper\Log_Helper;
10
  use Hammer\Helper\WP_Helper;
 
11
  use WP_Defender\Module\Hardener\Model\Settings;
 
12
  use WP_Defender\Module\Scan\Component\Scan_Api;
13
  use WP_Defender\Module\Scan\Model\Result_Item;
14
 
@@ -43,10 +45,9 @@ class Utils extends Behavior {
43
 
44
  $headers = isset( $post_vars['headers'] ) ? $post_vars['headers'] : array();
45
 
46
- $post_vars['headers'] = array_merge( $headers, array(
47
  'Authorization' => 'Basic ' . $api_key
48
  ) );
49
- $post_vars['headers']['user-agent'] = 'http://asdc.com';
50
 
51
  $post_vars = array_merge( $post_vars, $requestArgs );
52
 
@@ -101,9 +102,13 @@ class Utils extends Behavior {
101
  //this is version 4+
102
  //instanize once
103
  \WPMUDEV_Dashboard::instance();
104
- $api_key = \WPMUDEV_Dashboard::$api->get_key();
105
 
106
- return $api_key;
 
 
 
 
107
  } else {
108
  global $wpmudev_un;
109
  $api_key = $wpmudev_un->get_apikey();
@@ -337,7 +342,13 @@ class Utils extends Behavior {
337
  $offset = implode( ':', $timezone );
338
  list( $hours, $minutes ) = explode( ':', $offset );
339
  $seconds = $hours * 60 * 60 + $minutes * 60;
340
- $tz = timezone_name_from_abbr( '', $seconds, 1 );
 
 
 
 
 
 
341
  if ( $tz === false ) {
342
  $tz = timezone_name_from_abbr( '', $seconds, 0 );
343
  }
@@ -362,14 +373,130 @@ class Utils extends Behavior {
362
  return apply_filters( 'wd_scan_get_days_of_week', $days );
363
  }
364
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
365
  /**
366
  * A shorhand function to get user IP
367
  * @return mixed|string
368
  */
369
  public function getUserIp() {
370
- $client = isset( $_SERVER['HTTP_CLIENT_IP'] ) ? $_SERVER['HTTP_CLIENT_IP'] : null;
371
- $forward = isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : null;
372
- $remote = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : null;
 
 
 
 
 
 
 
 
373
  $client_real = isset( $_SERVER['HTTP_X_REAL_IP'] ) ? $_SERVER['HTTP_X_REAL_IP'] : null;
374
  $ret = $remote;
375
  if ( filter_var( $client, FILTER_VALIDATE_IP ) ) {
@@ -413,8 +540,14 @@ class Utils extends Behavior {
413
  return new Utils();
414
  }
415
 
416
- public function determineServer() {
417
- $url = home_url();
 
 
 
 
 
 
418
  $server_type = get_site_transient( 'wd_util_server' );
419
  if ( ! is_array( $server_type ) ) {
420
  $server_type = array();
@@ -484,6 +617,13 @@ class Utils extends Behavior {
484
  return $defDir;
485
  }
486
 
 
 
 
 
 
 
 
487
  /**
488
  * @param null $result
489
  *
@@ -561,11 +701,4 @@ class Utils extends Behavior {
561
 
562
  return apply_filters( 'defender_current_page_url', $url );
563
  }
564
-
565
- /**
566
- * Blank function
567
- */
568
- public function submitStatsToDev() {
569
- return;
570
- }
571
  }
8
  use Hammer\Base\Behavior;
9
  use Hammer\Helper\Log_Helper;
10
  use Hammer\Helper\WP_Helper;
11
+ use WP_Defender\Module\Advanced_Tools\Model\Auth_Settings;
12
  use WP_Defender\Module\Hardener\Model\Settings;
13
+ use WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api;
14
  use WP_Defender\Module\Scan\Component\Scan_Api;
15
  use WP_Defender\Module\Scan\Model\Result_Item;
16
 
45
 
46
  $headers = isset( $post_vars['headers'] ) ? $post_vars['headers'] : array();
47
 
48
+ $post_vars['headers'] = array_merge( $headers, array(
49
  'Authorization' => 'Basic ' . $api_key
50
  ) );
 
51
 
52
  $post_vars = array_merge( $post_vars, $requestArgs );
53
 
102
  //this is version 4+
103
  //instanize once
104
  \WPMUDEV_Dashboard::instance();
105
+ $membeshipStatus = \WPMUDEV_Dashboard::$api->get_membership_data();
106
 
107
+ if ( $membeshipStatus['membership'] != 'free' ) {
108
+ return \WPMUDEV_Dashboard::$api->get_key();
109
+ } else {
110
+ return false;
111
+ }
112
  } else {
113
  global $wpmudev_un;
114
  $api_key = $wpmudev_un->get_apikey();
342
  $offset = implode( ':', $timezone );
343
  list( $hours, $minutes ) = explode( ':', $offset );
344
  $seconds = $hours * 60 * 60 + $minutes * 60;
345
+ $lc = localtime( time(), true );
346
+ if ( isset( $lc['tm_isdst'] ) ) {
347
+ $isdst = $lc['tm_isdst'];
348
+ } else {
349
+ $isdst = 0;
350
+ }
351
+ $tz = timezone_name_from_abbr( '', $seconds, $isdst );
352
  if ( $tz === false ) {
353
  $tz = timezone_name_from_abbr( '', $seconds, 0 );
354
  }
373
  return apply_filters( 'wd_scan_get_days_of_week', $days );
374
  }
375
 
376
+ /**
377
+ * Validates that the IP that made the request is from cloudflare
378
+ *
379
+ * @param String $ip - the ip to check
380
+ *
381
+ * @return bool
382
+ */
383
+ private function _validateCloudflareIP( $ip ) {
384
+ $cloudflare_ips = array(
385
+ '199.27.128.0/21',
386
+ '173.245.48.0/20',
387
+ '103.21.244.0/22',
388
+ '103.22.200.0/22',
389
+ '103.31.4.0/22',
390
+ '141.101.64.0/18',
391
+ '108.162.192.0/18',
392
+ '190.93.240.0/20',
393
+ '188.114.96.0/20',
394
+ '197.234.240.0/22',
395
+ '198.41.128.0/17',
396
+ '162.158.0.0/15',
397
+ '104.16.0.0/12',
398
+ );
399
+ $is_cf_ip = false;
400
+ foreach ( $cloudflare_ips as $cloudflare_ip ) {
401
+ if ( $this->_cloudflareIpInRange( $ip, $cloudflare_ip ) ) {
402
+ $is_cf_ip = true;
403
+ break;
404
+ }
405
+ }
406
+
407
+ return $is_cf_ip;
408
+ }
409
+
410
+ /**
411
+ * Check if the cloudflare IP is in range
412
+ *
413
+ * @param String $ip - the current IP
414
+ * @param String $range - the allowed range of cloudflare ips
415
+ *
416
+ * @return bool
417
+ */
418
+ function _cloudflareIpInRange( $ip, $range ) {
419
+ if ( strpos( $range, '/' ) == false ) {
420
+ $range .= '/32';
421
+ }
422
+
423
+ // $range is in IP/CIDR format eg 127.0.0.1/24
424
+ list( $range, $netmask ) = explode( '/', $range, 2 );
425
+ $range_decimal = ip2long( $range );
426
+ $ip_decimal = ip2long( $ip );
427
+ $wildcard_decimal = pow( 2, ( 32 - $netmask ) ) - 1;
428
+ $netmask_decimal = ~$wildcard_decimal;
429
+
430
+ return ( ( $ip_decimal & $netmask_decimal ) == ( $range_decimal & $netmask_decimal ) );
431
+ }
432
+
433
+ /**
434
+ * Check if there are any cloudflare headers in the request
435
+ *
436
+ * @return bool
437
+ */
438
+ function _cloudflareRequestsCheck() {
439
+ $flag = true;
440
+
441
+ if ( ! isset( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
442
+ $flag = false;
443
+ }
444
+ if ( ! isset( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) {
445
+ $flag = false;
446
+ }
447
+ if ( ! isset( $_SERVER['HTTP_CF_RAY'] ) ) {
448
+ $flag = false;
449
+ }
450
+ if ( ! isset( $_SERVER['HTTP_CF_VISITOR'] ) ) {
451
+ $flag = false;
452
+ }
453
+
454
+ return $flag;
455
+ }
456
+
457
+ /**
458
+ * Check if the request is from cloudflare. If it is, we get the IP
459
+ *
460
+ * @return bool
461
+ */
462
+ function isCloudflare() {
463
+ if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) ) {
464
+ $ip = $_SERVER['HTTP_CLIENT_IP'];
465
+ } elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
466
+ $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
467
+ } else {
468
+ $ip = $_SERVER['REMOTE_ADDR'];
469
+ }
470
+ if ( isset( $ip ) ) {
471
+ $request_check = $this->_cloudflareRequestsCheck();
472
+ if ( ! $request_check ) {
473
+ return false;
474
+ }
475
+
476
+ $ip_check = $this->_validateCloudflareIP( $ip );
477
+
478
+ return $ip_check;
479
+ }
480
+
481
+ return false;
482
+ }
483
+
484
  /**
485
  * A shorhand function to get user IP
486
  * @return mixed|string
487
  */
488
  public function getUserIp() {
489
+ $client = isset( $_SERVER['HTTP_CLIENT_IP'] ) ? $_SERVER['HTTP_CLIENT_IP'] : null;
490
+ $forward = isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : null;
491
+ $is_cf = $this->isCloudflare(); //Check if request is from CloudFlare
492
+ if ( $is_cf ) {
493
+ $cf_ip = $_SERVER['HTTP_CF_CONNECTING_IP']; //We already make sure this is set in the checks
494
+ if ( filter_var( $cf_ip, FILTER_VALIDATE_IP ) ) {
495
+ return apply_filters( 'defender_user_ip', $cf_ip );
496
+ }
497
+ } else {
498
+ $remote = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : null;
499
+ }
500
  $client_real = isset( $_SERVER['HTTP_X_REAL_IP'] ) ? $_SERVER['HTTP_X_REAL_IP'] : null;
501
  $ret = $remote;
502
  if ( filter_var( $client, FILTER_VALIDATE_IP ) ) {
540
  return new Utils();
541
  }
542
 
543
+ /**
544
+ * Determine the server
545
+ * Incase we are using a hybrid server and need to know where static files are houses, pass true as a param
546
+ *
547
+ * @param $useStaticPath - use static path instead of home url. This is the path to Defender changelog
548
+ */
549
+ public function determineServer( $useStaticPath = false ) {
550
+ $url = ( $useStaticPath ) ? wp_defender()->getPluginUrl() . 'changelog.txt' : home_url();
551
  $server_type = get_site_transient( 'wd_util_server' );
552
  if ( ! is_array( $server_type ) ) {
553
  $server_type = array();
617
  return $defDir;
618
  }
619
 
620
+ /**
621
+ * @return array|void
622
+ */
623
+ public function submitStatsToDev() {
624
+ return false;
625
+ }
626
+
627
  /**
628
  * @param null $result
629
  *
701
 
702
  return apply_filters( 'defender_current_page_url', $url );
703
  }
 
 
 
 
 
 
 
704
  }
app/controller/dashboard.php CHANGED
@@ -360,6 +360,7 @@ class Dashboard extends Controller {
360
  'audit' => wp_defender()->isFree ? '\WP_Defender\Module\Audit\Behavior\Audit_Free' : '\WP_Defender\Module\Audit\Behavior\Audit',
361
  'blacklist' => wp_defender()->isFree ? '\WP_Defender\Behavior\Blacklist_Free' : '\WP_Defender\Behavior\Blacklist',
362
  'report' => wp_defender()->isFree ? '\WP_Defender\Behavior\Report_Free' : '\WP_Defender\Behavior\Report',
 
363
  );
364
  }
365
  }
360
  'audit' => wp_defender()->isFree ? '\WP_Defender\Module\Audit\Behavior\Audit_Free' : '\WP_Defender\Module\Audit\Behavior\Audit',
361
  'blacklist' => wp_defender()->isFree ? '\WP_Defender\Behavior\Blacklist_Free' : '\WP_Defender\Behavior\Blacklist',
362
  'report' => wp_defender()->isFree ? '\WP_Defender\Behavior\Report_Free' : '\WP_Defender\Behavior\Report',
363
+ 'at' => '\WP_Defender\Module\Advanced_Tools\Behavior\AT_Widget'
364
  );
365
  }
366
  }
app/module/advanced-tools/behavior/at-widget.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Author: Hoang Ngo
4
+ */
5
+
6
+ namespace WP_Defender\Module\Advanced_Tools\Behavior;
7
+
8
+ use Hammer\Base\Behavior;
9
+ use WP_Defender\Module\Advanced_Tools\Model\Auth_Settings;
10
+
11
+ class AT_Widget extends Behavior {
12
+ public function renderATWidget() {
13
+ ?>
14
+ <div class="dev-box advanced-tools">
15
+ <div class="box-title">
16
+ <span class="span-icon icon-scan"></span>
17
+ <h3><?php _e( "Advanced Tools", wp_defender()->domain ) ?>
18
+ </h3>
19
+
20
+ </div>
21
+ <div class="box-content">
22
+ <p class="line end">
23
+ <?php _e( "Enable advanced tools for enhanced protection against even the most aggressive of hackers and bots.", wp_defender()->domain ) ?>
24
+ </p>
25
+ <div class="at-line">
26
+ <strong>
27
+ <?php _e( "2 Factor Authentication", wp_defender()->domain ) ?>
28
+ </strong>
29
+ <span>
30
+ <?php
31
+ _e( "Protect your user accounts by requiring a second passcode sent to users phones in order to get past your login screen", wp_defender()->domain )
32
+ ?>
33
+ </span>
34
+ <?php
35
+ $settings = Auth_Settings::instance();
36
+ if ( $settings->enabled ):
37
+ ?>
38
+ <div class="well well-green with-cap">
39
+ <i class="def-icon icon-tick"></i>
40
+ <?php _e( "2 factor authentication is active.", wp_defender()->domain ) ?>
41
+ </div>
42
+ <?php else: ?>
43
+ <form method="post" id="advanced-settings-frm" class="advanced-settings-frm">
44
+ <input type="hidden" name="action" value="saveAdvancedSettings"/>
45
+ <?php wp_nonce_field( 'saveAdvancedSettings' ) ?>
46
+ <input type="hidden" name="enabled" value="1"/>
47
+ <button type="submit" class="button button-primary button-small">
48
+ <?php _e( "Activate", wp_defender()->domain ) ?>
49
+ </button>
50
+ </form>
51
+ <?php endif; ?>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ <?php
56
+ }
57
+ }
app/module/advanced-tools/component/auth-api.php CHANGED
@@ -106,6 +106,7 @@ class Auth_API extends Component {
106
  }
107
  }
108
 
 
109
  return false;
110
  }
111
 
106
  }
107
  }
108
 
109
+
110
  return false;
111
  }
112
 
app/module/advanced-tools/controller/main.php CHANGED
@@ -425,7 +425,7 @@ class Main extends Controller {
425
  * Enqueue scripts & styles
426
  */
427
  public function scripts() {
428
- if ( $this->isInPage() ) {
429
  \WDEV_Plugin_Ui::load( wp_defender()->getPluginUrl() . 'shared-ui/' );
430
  wp_enqueue_script( 'defender' );
431
  wp_enqueue_style( 'defender' );
425
  * Enqueue scripts & styles
426
  */
427
  public function scripts() {
428
+ if ( $this->isInPage() || $this->isDashboard() ) {
429
  \WDEV_Plugin_Ui::load( wp_defender()->getPluginUrl() . 'shared-ui/' );
430
  wp_enqueue_script( 'defender' );
431
  wp_enqueue_style( 'defender' );
app/module/advanced-tools/view/login/otp.php CHANGED
@@ -221,7 +221,7 @@ do_action( 'login_header' );
221
  ?>
222
  <form method="post"
223
  action="<?php echo esc_url( add_query_arg( 'action', 'defenderVerifyOTP', site_url( 'wp-login.php', 'login_post' ) ) ); ?>">
224
- <p><?php _e( "Enter 6 digit passcode", wp_defender()->domain ) ?></p>
225
  <input type="text" value="" name="otp">
226
  <button class="button button-primary float-r"
227
  type="submit"><?php _e( "Authenticate", wp_defender()->domain ) ?></button>
221
  ?>
222
  <form method="post"
223
  action="<?php echo esc_url( add_query_arg( 'action', 'defenderVerifyOTP', site_url( 'wp-login.php', 'login_post' ) ) ); ?>">
224
+ <p><?php _e( "Open the Google Authenticator app and enter the 6 digit passcode.", wp_defender()->domain ) ?></p>
225
  <input type="text" value="" name="otp">
226
  <button class="button button-primary float-r"
227
  type="submit"><?php _e( "Authenticate", wp_defender()->domain ) ?></button>
app/module/hardener/behavior/widget.php CHANGED
@@ -15,13 +15,13 @@ class Widget extends Behavior {
15
  ?>
16
  <div class="dev-box hardener-widget">
17
  <div class="box-title">
18
- <span class="span-icon hardener-icon"></span>
19
  <h3><?php _e( "Security Tweaks", wp_defender()->domain ) ?>
20
  <?php
21
  $hardener_issues = count( Settings::instance()->issues );
22
  if ( $hardener_issues ): ?>
23
  <span class="def-tag tag-yellow"
24
- tooltip="<?php esc_attr_e( sprintf( __('You have %d security tweak(s) needing attention', wp_defender()->domain ), $hardener_issues ) ); ?>">
25
  <?php
26
  echo $hardener_issues ?>
27
  </span>
15
  ?>
16
  <div class="dev-box hardener-widget">
17
  <div class="box-title">
18
+ <span class="span-icon hardener-icon" aria-hidden="true"></span>
19
  <h3><?php _e( "Security Tweaks", wp_defender()->domain ) ?>
20
  <?php
21
  $hardener_issues = count( Settings::instance()->issues );
22
  if ( $hardener_issues ): ?>
23
  <span class="def-tag tag-yellow"
24
+ tooltip="<?php esc_attr_e( sprintf( __('You have %d security tweak(s) needing attention.', wp_defender()->domain ), $hardener_issues ) ); ?>">
25
  <?php
26
  echo $hardener_issues ?>
27
  </span>
app/module/hardener/component/hide-error-service.php CHANGED
@@ -34,7 +34,8 @@ class Hide_Error_Service extends Rule_Service implements IRule_Service {
34
  if ( $isLog == 1 ) {
35
  ini_set( 'log_errors', 1 );
36
  }
37
- if ( strpos( $body, ABSPATH . 'wp-includes/theme-compat/embed.php' ) !== false ) {
 
38
  $altCache->set( 'Hide_Error_Service', 0 );
39
 
40
  return false;
34
  if ( $isLog == 1 ) {
35
  ini_set( 'log_errors', 1 );
36
  }
37
+ if ( strpos( $body, ABSPATH . 'wp-includes/theme-compat/embed.php' ) !== false ||
38
+ WP_DEBUG == true && ( ! defined( 'WP_DEBUG_DISPLAY' ) || WP_DEBUG_DISPLAY != false )) {
39
  $altCache->set( 'Hide_Error_Service', 0 );
40
 
41
  return false;
app/module/hardener/component/login-duration.php CHANGED
@@ -79,7 +79,7 @@ class Login_Duration extends Rule {
79
  }
80
  $service = $this->getService();
81
  $duration = HTTP_Helper::retrieve_post( 'duration' );
82
- if ( is_numeric( $duration ) ) {
83
  $service->setDuration( $duration );
84
  $ret = $service->process();
85
  if ( ! is_wp_error( $ret ) ) {
@@ -91,7 +91,7 @@ class Login_Duration extends Rule {
91
  }
92
  } else {
93
  wp_send_json_error( array(
94
- 'message' => __( 'Duration can only be a number', wp_defender()->domain )
95
  ) );
96
  }
97
  }
@@ -123,8 +123,12 @@ class Login_Duration extends Rule {
123
  $last_login_time = get_user_meta( $user_id, 'last_login_time', true );
124
  $login_period = $this->getService()->getDuration( true );
125
  if ( $last_login_time ) {
126
- $diff = strtotime( $current_time ) - strtotime( $last_login_time );
127
- if( $diff > $login_period ) {
 
 
 
 
128
  $current_url = Utils::instance()->currentPageURL();
129
  $after_logout_payload = array( 'redirect_to' => $current_url, 'msg'=>'session_expired' );
130
  if ( is_multisite() ) {
79
  }
80
  $service = $this->getService();
81
  $duration = HTTP_Helper::retrieve_post( 'duration' );
82
+ if ( is_numeric( $duration ) && intval( $duration ) > 0 ) {
83
  $service->setDuration( $duration );
84
  $ret = $service->process();
85
  if ( ! is_wp_error( $ret ) ) {
91
  }
92
  } else {
93
  wp_send_json_error( array(
94
+ 'message' => __( 'Duration can only be a number and greater than 0', wp_defender()->domain )
95
  ) );
96
  }
97
  }
123
  $last_login_time = get_user_meta( $user_id, 'last_login_time', true );
124
  $login_period = $this->getService()->getDuration( true );
125
  if ( $last_login_time ) {
126
+ $current_time = strtotime( $current_time );
127
+ $last_login_time = strtotime( $last_login_time );
128
+ $diff = $current_time - $last_login_time ;
129
+ //Check if the current and login times are not the same
130
+ //so we dont kick out someone who set it to 0
131
+ if( ( $current_time != $last_login_time ) && $diff > $login_period ) {
132
  $current_url = Utils::instance()->currentPageURL();
133
  $after_logout_payload = array( 'redirect_to' => $current_url, 'msg'=>'session_expired' );
134
  if ( is_multisite() ) {
app/module/hardener/js/scripts.js CHANGED
@@ -40,7 +40,22 @@ jQuery(function ($) {
40
  if ( $('.hardener-instructions-apache-litespeed').length ) {
41
  $('.hardener-update-frm [name="file_paths"]').val(text_val);
42
  }
43
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  /**
46
  * Pevent PHP update posts toggle
40
  if ( $('.hardener-instructions-apache-litespeed').length ) {
41
  $('.hardener-update-frm [name="file_paths"]').val(text_val);
42
  }
43
+ });
44
+
45
+ /**
46
+ * Validate that the number put is greater than 0 and is actually a number
47
+ */
48
+ $(document).on('keyup keypress paste','.defender-login-duration', function(){
49
+ var text_val = $(this).val();
50
+ if( /^-?[0-9]+$/i.test(text_val)){
51
+ //is integer
52
+ if(text_val <= 0){
53
+ $(this).val('');
54
+ }
55
+ } else{
56
+ $(this).val('');
57
+ }
58
+ });
59
 
60
  /**
61
  * Pevent PHP update posts toggle
app/module/hardener/readme DELETED
@@ -1 +0,0 @@
1
- when this module init, it will auto check the rules condition and store in settings model
 
app/module/hardener/view/ignore.php CHANGED
@@ -23,7 +23,7 @@
23
  </div>
24
  <?php else: ?>
25
  <div class="well well-blue with-cap">
26
- <i class="def-icon icon-warning"></i>
27
  <?php _e( "You haven't ignored any issues yet. You can ignore any security tweaks you don't want to be warned about by clicking 'Ignore' inside the issue description.", wp_defender()->domain ) ?>
28
  </div>
29
  <?php endif; ?>
23
  </div>
24
  <?php else: ?>
25
  <div class="well well-blue with-cap">
26
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
27
  <?php _e( "You haven't ignored any issues yet. You can ignore any security tweaks you don't want to be warned about by clicking 'Ignore' inside the issue description.", wp_defender()->domain ) ?>
28
  </div>
29
  <?php endif; ?>
app/module/hardener/view/issues.php CHANGED
@@ -18,7 +18,7 @@
18
  if ( count( $issues ) == 0 ) {
19
  ?>
20
  <div class="well well-green with-cap">
21
- <i class="def-icon icon-tick"></i>
22
  <?php _e( "You have actioned all available security tweaks. Great work!", wp_defender()->domain ) ?>
23
  </div>
24
  <?php
18
  if ( count( $issues ) == 0 ) {
19
  ?>
20
  <div class="well well-green with-cap">
21
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
22
  <?php _e( "You have actioned all available security tweaks. Great work!", wp_defender()->domain ) ?>
23
  </div>
24
  <?php
app/module/hardener/view/layouts/layout.php CHANGED
@@ -15,12 +15,12 @@
15
  <?php if ( $controller->getCount( 'issues' ) > 0 ) :
16
  $hardener_issues = ( $controller->getCount( 'fixed' ) + $controller->getCount( 'ignore' ) ) . '/' . count( \WP_Defender\Module\Hardener\Model\Settings::instance()->getDefinedRules( false ) );
17
  ?>
18
- <span class="" tooltip="<?php esc_attr_e( sprintf( __('You have actioned %s security tweaks', wp_defender()->domain ), $hardener_issues ) ); ?>">
19
  <?php else : ?>
20
- <span class="" tooltip="<?php esc_attr_e( 'You have no outstanding security issues', wp_defender()->domain ); ?>">
21
  <?php endif; ?>
22
  <?php
23
- $icon = $controller->getCount( 'issues' ) == 0 ? ' <i class="def-icon icon-tick icon-active"></i>' : ' <i class="def-icon icon-warning"></i>';
24
  echo $icon;
25
  ?>
26
  </span>
@@ -53,51 +53,55 @@
53
  </div>
54
  <div class="row">
55
  <div class="col-third">
56
- <ul class="inner-nav is-hidden-mobile">
57
- <li>
58
- <a class="<?php echo \Hammer\Helper\HTTP_Helper::retrieve_get( 'view', false ) == false ? 'active' : null ?>"
59
- href="<?php echo network_admin_url( 'admin.php?page=wdf-hardener' ) ?>">
60
- <?php _e( "Issues", wp_defender()->domain ) ?>
61
- <?php
62
- $tooltip = '';
63
- if ( $controller->getCount( 'issues' ) > 0 ) :
64
- $tooltip = 'tooltip="'.esc_attr( sprintf( __('You have %d security tweak(s) needing attention', wp_defender()->domain ), $controller->getCount( 'issues' ) ) ).'"';
65
- endif;
66
- ?>
67
- <span class="def-tag count-issues tag-yellow <?php echo $controller->getCount( 'issues' ) == 0 ? 'wd-hide' : null ?>" <?php echo $tooltip; ?>><?php echo $controller->getCount( 'issues' ) ?></span>
68
- </a>
69
- </li>
70
- <li>
71
- <a class="<?php echo $controller->isView( 'resolved' ) ? 'active' : null ?>"
72
- href="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=resolved' ) ?>">
73
- <?php _e( "Resolved", wp_defender()->domain ) ?>
74
- <span class="count-resolved <?php echo $controller->getCount( 'fixed' ) == 0 ? 'wd-hide' : null ?>"><?php echo $controller->getCount( 'fixed' ) ?></span>
75
- </a>
76
- </li>
77
- <li>
78
- <a class="<?php echo $controller->isView( 'ignored' ) ? 'active' : null ?>"
79
- href="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=ignored' ) ?>">
80
- <?php _e( "Ignored", wp_defender()->domain ) ?>
81
- <span class="count-ignored <?php echo $controller->getCount( 'ignore' ) == 0 ? 'wd-hide' : null ?>"><?php echo $controller->getCount( 'ignore' ) ?></span>
82
- </a>
83
- </li>
84
- <!-- <li>-->
85
- <!-- <a class="-->
86
- <?php //echo $controller->isView( 'notification' ) ? 'active' : null ?><!--"-->
87
- <!-- href="-->
88
- <?php //echo network_admin_url( 'admin.php?page=wdf-hardener&view=notification' ) ?><!--">-->
89
- <?php //_e( "Notifications", wp_defender()->domain ) ?><!--</a>-->
90
- <!-- </li>-->
91
- </ul>
 
 
92
  <div class="is-hidden-tablet mline">
93
- <select class="mobile-nav">
94
- <option <?php selected( '', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
95
- value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener' ) ?>"><?php _e( "Issues", wp_defender()->domain ) ?></option>
96
- <option <?php selected( 'resolved', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
97
- value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=resolved' ) ?>"><?php _e( "Resolved", wp_defender()->domain ) ?></option>
98
- <option <?php selected( 'ignored', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
99
- value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=ignored' ) ?>"><?php _e( "Ignored", wp_defender()->domain ) ?></option>
100
- </select>
 
 
101
  </div>
102
  </div>
103
  <div class="col-two-third">
15
  <?php if ( $controller->getCount( 'issues' ) > 0 ) :
16
  $hardener_issues = ( $controller->getCount( 'fixed' ) + $controller->getCount( 'ignore' ) ) . '/' . count( \WP_Defender\Module\Hardener\Model\Settings::instance()->getDefinedRules( false ) );
17
  ?>
18
+ <span class="" tooltip="<?php esc_attr_e( sprintf( __('You have actioned %s security tweaks.', wp_defender()->domain ), $hardener_issues ) ); ?>">
19
  <?php else : ?>
20
+ <span class="" tooltip="<?php esc_attr_e( 'You have no outstanding security issues.', wp_defender()->domain ); ?>">
21
  <?php endif; ?>
22
  <?php
23
+ $icon = $controller->getCount( 'issues' ) == 0 ? ' <i class="def-icon icon-tick icon-active" aria-hidden="true"></i>' : ' <i class="def-icon icon-warning" aria-hidden="true"></i>';
24
  echo $icon;
25
  ?>
26
  </span>
53
  </div>
54
  <div class="row">
55
  <div class="col-third">
56
+ <nav role="navigation" aria-label="Filters">
57
+ <ul class="inner-nav is-hidden-mobile">
58
+ <li>
59
+ <a class="<?php echo \Hammer\Helper\HTTP_Helper::retrieve_get( 'view', false ) == false ? 'active' : null ?>"
60
+ href="<?php echo network_admin_url( 'admin.php?page=wdf-hardener' ) ?>">
61
+ <?php _e( "Issues", wp_defender()->domain ) ?>
62
+ <?php
63
+ $tooltip = '';
64
+ if ( $controller->getCount( 'issues' ) > 0 ) :
65
+ $tooltip = 'tooltip="'.esc_attr( sprintf( __('You have %d security tweak(s) needing attention.', wp_defender()->domain ), $controller->getCount( 'issues' ) ) ).'"';
66
+ endif;
67
+ ?>
68
+ <span class="def-tag count-issues tag-yellow <?php echo $controller->getCount( 'issues' ) == 0 ? 'wd-hide' : null ?>" <?php echo $tooltip; ?>><?php echo $controller->getCount( 'issues' ) ?></span>
69
+ </a>
70
+ </li>
71
+ <li>
72
+ <a class="<?php echo $controller->isView( 'resolved' ) ? 'active' : null ?>"
73
+ href="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=resolved' ) ?>">
74
+ <?php _e( "Resolved", wp_defender()->domain ) ?>
75
+ <span class="count-resolved <?php echo $controller->getCount( 'fixed' ) == 0 ? 'wd-hide' : null ?>"><?php echo $controller->getCount( 'fixed' ) ?></span>
76
+ </a>
77
+ </li>
78
+ <li>
79
+ <a class="<?php echo $controller->isView( 'ignored' ) ? 'active' : null ?>"
80
+ href="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=ignored' ) ?>">
81
+ <?php _e( "Ignored", wp_defender()->domain ) ?>
82
+ <span class="count-ignored <?php echo $controller->getCount( 'ignore' ) == 0 ? 'wd-hide' : null ?>"><?php echo $controller->getCount( 'ignore' ) ?></span>
83
+ </a>
84
+ </li>
85
+ <!-- <li>-->
86
+ <!-- <a class="-->
87
+ <?php //echo $controller->isView( 'notification' ) ? 'active' : null ?><!--"-->
88
+ <!-- href="-->
89
+ <?php //echo network_admin_url( 'admin.php?page=wdf-hardener&view=notification' ) ?><!--">-->
90
+ <?php //_e( "Notifications", wp_defender()->domain ) ?><!--</a>-->
91
+ <!-- </li>-->
92
+ </ul>
93
+ </nav>
94
  <div class="is-hidden-tablet mline">
95
+ <nav role="navigation" aria-label="Filters">
96
+ <select class="mobile-nav">
97
+ <option <?php selected( '', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
98
+ value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener' ) ?>"><?php _e( "Issues", wp_defender()->domain ) ?></option>
99
+ <option <?php selected( 'resolved', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
100
+ value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=resolved' ) ?>"><?php _e( "Resolved", wp_defender()->domain ) ?></option>
101
+ <option <?php selected( 'ignored', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
102
+ value="<?php echo network_admin_url( 'admin.php?page=wdf-hardener&view=ignored' ) ?>"><?php _e( "Ignored", wp_defender()->domain ) ?></option>
103
+ </select>
104
+ </nav>
105
  </div>
106
  </div>
107
  <div class="col-two-third">
app/module/hardener/view/rules/change-admin.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="change_admin">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php _e( "Change default admin user account", wp_defender()->domain ) ?>
9
  </div>
1
  <div class="rule closed" id="change_admin">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php _e( "Change default admin user account", wp_defender()->domain ) ?>
9
  </div>
app/module/hardener/view/rules/db-prefix.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="db_prefix">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php _e( "Change default database prefix", wp_defender()->domain ) ?>
9
  </div>
1
  <div class="rule closed" id="db_prefix">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php _e( "Change default database prefix", wp_defender()->domain ) ?>
9
  </div>
app/module/hardener/view/rules/disable-file-editor.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="disable_file_editor">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php _e( "Disable the file editor", wp_defender()->domain ) ?>
9
  </div>
1
  <div class="rule closed" id="disable_file_editor">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php _e( "Disable the file editor", wp_defender()->domain ) ?>
9
  </div>
app/module/hardener/view/rules/disable-trackback.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="disable_trackback">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php _e( "Disable trackbacks and pingbacks", wp_defender()->domain ) ?>
9
  </div>
1
  <div class="rule closed" id="disable_trackback">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php _e( "Disable trackbacks and pingbacks", wp_defender()->domain ) ?>
9
  </div>
app/module/hardener/view/rules/hide-error.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="disable-file-editor">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php _e( "Hide error reporting", wp_defender()->domain ) ?>
9
  </div>
@@ -37,7 +37,7 @@
37
  //php debug is turn off, however the error still dsplay, need to show user about this
38
  else: ?>
39
  <p class="line">
40
- <?php _e( "We attempted to disable the WP_DEBUG setting to prevent code errors displaying but it’s being overridden by your server config. Please contact your hosting provider and ask them to set WP_DEBUG to false.", wp_defender()->domain ) ?>
41
  </p>
42
  <?php $controller->showIgnoreForm() ?>
43
  <?php endif; ?>
1
  <div class="rule closed" id="disable-file-editor">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php _e( "Hide error reporting", wp_defender()->domain ) ?>
9
  </div>
37
  //php debug is turn off, however the error still dsplay, need to show user about this
38
  else: ?>
39
  <p class="line">
40
+ <?php _e( "We attempted to disable the display_errors setting to prevent code errors displaying but it’s being overridden by your server config. Please contact your hosting provider and ask them to set display_errors to false.", wp_defender()->domain ) ?>
41
  </p>
42
  <?php $controller->showIgnoreForm() ?>
43
  <?php endif; ?>
app/module/hardener/view/rules/login-duration.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="login-duration">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php echo $controller->getTitle() ?>
9
  </div>
@@ -38,7 +38,7 @@
38
  <?php $controller->createNonceField(); ?>
39
  <input type="hidden" name="action" value="processHardener"/>
40
  <input type="text" placeholder="<?php esc_attr_e( "Enter number of days", wp_defender()->domain ) ?>"
41
- name="duration" class="block" />
42
  <input type="hidden" name="slug" value="<?php echo $controller::$slug ?>"/>
43
  <button class="button float-r"
44
  type="submit"><?php _e( "Update", wp_defender()->domain ) ?></button>
1
  <div class="rule closed" id="login-duration">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php echo $controller->getTitle() ?>
9
  </div>
38
  <?php $controller->createNonceField(); ?>
39
  <input type="hidden" name="action" value="processHardener"/>
40
  <input type="text" placeholder="<?php esc_attr_e( "Enter number of days", wp_defender()->domain ) ?>"
41
+ name="duration" class="block defender-login-duration" />
42
  <input type="hidden" name="slug" value="<?php echo $controller::$slug ?>"/>
43
  <button class="button float-r"
44
  type="submit"><?php _e( "Update", wp_defender()->domain ) ?></button>
app/module/hardener/view/rules/php-version.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="php_version">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php _e( "Update PHP to latest version", wp_defender()->domain ) ?>
9
  </div>
1
  <div class="rule closed" id="php_version">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php _e( "Update PHP to latest version", wp_defender()->domain ) ?>
9
  </div>
app/module/hardener/view/rules/prevent-php-executed.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="disable-file-editor">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php _e( "Prevent PHP execution", wp_defender()->domain ) ?>
9
  </div>
1
  <div class="rule closed" id="disable-file-editor">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php _e( "Prevent PHP execution", wp_defender()->domain ) ?>
9
  </div>
app/module/hardener/view/rules/protect-information.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="disable-file-editor">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php _e( "Prevent Information Disclosure", wp_defender()->domain ) ?>
9
  </div>
@@ -28,14 +28,7 @@
28
  <?php else:
29
  $servers = \WP_Defender\Behavior\Utils::instance()->serverTypes();
30
  $setting = \WP_Defender\Module\Hardener\Model\Settings::instance();
31
- global $is_nginx, $is_IIS, $is_iis7;
32
- if ( $is_nginx ) {
33
- $setting->active_server = 'nginx';
34
- } else if ( $is_IIS ) {
35
- $setting->active_server = 'iis';
36
- } else if ( $is_iis7 ) {
37
- $setting->active_server = 'iis-7';
38
- }
39
  ?>
40
  <div class="columns">
41
  <div class="column is-one-third">
1
  <div class="rule closed" id="disable-file-editor">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php _e( "Prevent Information Disclosure", wp_defender()->domain ) ?>
9
  </div>
28
  <?php else:
29
  $servers = \WP_Defender\Behavior\Utils::instance()->serverTypes();
30
  $setting = \WP_Defender\Module\Hardener\Model\Settings::instance();
31
+ $setting->active_server = \WP_Defender\Behavior\Utils::instance()->determineServer( true );
 
 
 
 
 
 
 
32
  ?>
33
  <div class="columns">
34
  <div class="column is-one-third">
app/module/hardener/view/rules/security-key.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="security_key">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php _e( "Update old security keys", wp_defender()->domain ) ?>
9
  </div>
1
  <div class="rule closed" id="security_key">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php _e( "Update old security keys", wp_defender()->domain ) ?>
9
  </div>
app/module/hardener/view/rules/wp-version.php CHANGED
@@ -1,9 +1,9 @@
1
  <div class="rule closed" id="wp-version">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
- <i class="def-icon icon-warning"></i>
5
  <?php else: ?>
6
- <i class="def-icon icon-tick"></i>
7
  <?php endif; ?>
8
  <?php _e( "Update WordPress to latest version", wp_defender()->domain ) ?>
9
  </div>
1
  <div class="rule closed" id="wp-version">
2
  <div class="rule-title">
3
  <?php if ( $controller->check() == false ): ?>
4
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
5
  <?php else: ?>
6
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
7
  <?php endif; ?>
8
  <?php _e( "Update WordPress to latest version", wp_defender()->domain ) ?>
9
  </div>
app/module/ip-lockout/behavior/widget.php CHANGED
@@ -23,7 +23,7 @@ class Widget extends Behavior {
23
  <span class="span-icon icon-lockout"></span>
24
  <h3><?php _e( "IP LOCKOUTS", wp_defender()->domain ) ?></h3>
25
  </div>
26
- <div class="box-content">
27
  <div class="line">
28
  <?php _e( "Protect your login area by automatically locking out any suspicious behavior.", wp_defender()->domain ) ?>
29
  </div>
23
  <span class="span-icon icon-lockout"></span>
24
  <h3><?php _e( "IP LOCKOUTS", wp_defender()->domain ) ?></h3>
25
  </div>
26
+ <div class="box-content advanced-tools">
27
  <div class="line">
28
  <?php _e( "Protect your login area by automatically locking out any suspicious behavior.", wp_defender()->domain ) ?>
29
  </div>
app/module/ip-lockout/component/ip-api.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Author: Hoang Ngo
4
+ */
5
+
6
+ namespace WP_Defender\Module\IP_Lockout\Component;
7
+
8
+ use Hammer\WP\Component;
9
+
10
+ class IP_API extends Component {
11
+ public static function compareCIDR( $ip, $block ) {
12
+ if ( self::isV4( $ip ) ) {
13
+ return self::_compareCIDRV4( $ip, $block );
14
+ } elseif ( self::isV6( $ip ) ) {
15
+
16
+ }
17
+
18
+ return false;
19
+ }
20
+
21
+ /**
22
+ * @param $ip
23
+ * @param $block
24
+ *
25
+ * @src http://stackoverflow.com/a/594134
26
+ * @return bool
27
+ */
28
+ private static function _compareCIDRV4( $ip, $block ) {
29
+ list ( $subnet, $bits ) = explode( '/', $block );
30
+ $ip = ip2long( $ip );
31
+ $subnet = ip2long( $subnet );
32
+ $mask = - 1 << ( 32 - $bits );
33
+ $subnet &= $mask; # nb: in case the supplied subnet wasn't correctly aligned
34
+
35
+ return ( $ip & $mask ) == $subnet;
36
+ }
37
+
38
+ private static function _compareCIDRV6() {
39
+
40
+ }
41
+
42
+ /**
43
+ * @param $ip
44
+ * @param $firstInRange
45
+ * @param $lastInRange
46
+ *
47
+ * @return bool
48
+ */
49
+ public static function compareInRange( $ip, $firstInRange, $lastInRange ) {
50
+ if ( self::isV4( $firstInRange ) && self::isV4( $lastInRange ) ) {
51
+ return self::_compareV4InRange( $ip, $firstInRange, $lastInRange );
52
+ } elseif ( self::isV6( $firstInRange ) && self::isV6( $lastInRange ) ) {
53
+ self::_compareV6InRange( $ip, $firstInRange, $lastInRange );
54
+ }
55
+
56
+ return false;
57
+ }
58
+
59
+ /**
60
+ * @param $ip
61
+ * @param $fistInRange
62
+ * @param $lastInRange
63
+ *
64
+ * @return bool
65
+ */
66
+ private static function _compareV4InRange( $ip, $fistInRange, $lastInRange ) {
67
+ $high = sprintf( "%u", ip2long( $fistInRange ) );
68
+ $low = sprintf( "%u", ip2long( $lastInRange ) );
69
+
70
+ $cip = sprintf( "%u", ip2long( $ip ) );
71
+ if ( $high >= $cip && $cip >= $low ) {
72
+ return true;
73
+ }
74
+
75
+ return false;
76
+ }
77
+
78
+ /**
79
+ * @param $ip
80
+ * @param $firstInRange
81
+ * @param $lastInRange
82
+ *
83
+ * @return bool
84
+ */
85
+ private static function _compareV6InRange( $ip, $firstInRange, $lastInRange ) {
86
+ $firstInRange = inet_pton( self::expandIPv6( $firstInRange ) );
87
+ $lastInRange = inet_pton( self::expandIPv6( $lastInRange ) );
88
+ $ip = inet_pton( self::expandIPv6( $ip ) );
89
+
90
+ if ( ( strlen( $ip ) == strlen( $firstInRange ) )
91
+ && ( $ip >= $firstInRange && $ip <= $lastInRange ) ) {
92
+ return true;
93
+ } else {
94
+ return false;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Compare ip2 to ip1, true if ip2>ip1, false if not
100
+ *
101
+ * @param $ip1
102
+ * @param $ip2
103
+ *
104
+ * @return bool
105
+ */
106
+ public static function compareIP( $ip1, $ip2 ) {
107
+ if ( self::isV4( $ip1 ) && self::isV4( $ip2 ) ) {
108
+ if ( sprintf( "%u", ip2long( $ip2 ) ) - sprintf( "%u", ip2long( $ip1 ) ) > 0 ) {
109
+ return true;
110
+ }
111
+ } elseif ( self::isV6( $ip1 ) && self::isV6( $ip2 ) ) {
112
+ $ip1 = inet_pton( self::expandIPv6( $ip1 ) );
113
+ $ip2 = inet_pton( self::expandIPv6( $ip2 ) );
114
+
115
+ return $ip2 > $ip1;
116
+ }
117
+
118
+ return false;
119
+ }
120
+
121
+ /**
122
+ * @param $ip
123
+ *
124
+ * @return mixed
125
+ */
126
+ private static function isV4( $ip ) {
127
+ return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 );
128
+ }
129
+
130
+ /**
131
+ * @param $ip
132
+ *
133
+ * @return mixed
134
+ */
135
+ private static function isV6( $ip ) {
136
+ return filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 );
137
+ }
138
+
139
+ /**
140
+ * @param $ip
141
+ *
142
+ * @return bool|string
143
+ */
144
+ private static function expandIPv6( $ip ) {
145
+ $hex = unpack( "H*hex", inet_pton( $ip ) );
146
+ $ip = substr( preg_replace( "/([A-f0-9]{4})/", "$1:", $hex['hex'] ), 0, - 1 );
147
+
148
+ return $ip;
149
+ }
150
+ }
app/module/ip-lockout/component/login-protection-api.php CHANGED
@@ -44,7 +44,7 @@ class Login_Protection_Api extends Component {
44
  'ip' => $log->ip,
45
  'type' => Log_Model::AUTH_FAIL,
46
  'blog_id' => get_current_blog_id(),
47
- 'date' => array( 'compare' => '>=', 'value' => $after )
48
  ) );
49
 
50
  if ( ! is_object( $model ) ) {
@@ -53,7 +53,6 @@ class Login_Protection_Api extends Component {
53
  $model->ip = $log->ip;
54
  $model->status = IP_Model::STATUS_NORMAL;
55
  }
56
-
57
  $model->attempt = $attempt;
58
  if ( $model->attempt >= $settings->login_protection_login_attempt || $force == true ) {
59
  $model->status = IP_Model::STATUS_BLOCKED;
@@ -73,6 +72,8 @@ class Login_Protection_Api extends Component {
73
  $lock_log->user_agent = $_SERVER['HTTP_USER_AGENT'];
74
  if ( $force && $blacklist ) {
75
  $lock_log->log = esc_html__( "Lockout occurred: Attempting to login with a banned username.", wp_defender()->domain );
 
 
76
  } else {
77
  $lock_log->log = esc_html__( "Lockout occurred: Too many failed login attempts", wp_defender()->domain );
78
  }
@@ -118,7 +119,7 @@ class Login_Protection_Api extends Component {
118
  'type' => Log_Model::ERROR_404,
119
  'blog_id' => get_current_blog_id(),
120
  'date' => array(
121
- 'compare' => '>=',
122
  'value' => $after
123
  )
124
  ) );
@@ -129,7 +130,18 @@ class Login_Protection_Api extends Component {
129
  $model->ip = $log->ip;
130
  $model->status = IP_Model::STATUS_NORMAL;
131
  }
 
 
 
 
 
 
 
 
 
 
132
  if ( count( $logs ) >= $settings->detect_404_threshold ) {
 
133
  $model->status = IP_Model::STATUS_BLOCKED;
134
  $model->release_time = strtotime( '+ ' . $settings->detect_404_lockout_duration . ' seconds' );
135
  $model->lockout_message = $settings->detect_404_lockout_message;
@@ -386,6 +398,46 @@ class Login_Protection_Api extends Component {
386
  return false;
387
  }
388
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
389
  /**
390
  *
391
  */
@@ -422,6 +474,24 @@ CREATE TABLE `{$tableName2}` (
422
  dbDelta( $sql );
423
  }
424
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425
  /**
426
  * @return bool
427
  */
44
  'ip' => $log->ip,
45
  'type' => Log_Model::AUTH_FAIL,
46
  'blog_id' => get_current_blog_id(),
47
+ 'date' => array( 'compare' => '>', 'value' => $after )
48
  ) );
49
 
50
  if ( ! is_object( $model ) ) {
53
  $model->ip = $log->ip;
54
  $model->status = IP_Model::STATUS_NORMAL;
55
  }
 
56
  $model->attempt = $attempt;
57
  if ( $model->attempt >= $settings->login_protection_login_attempt || $force == true ) {
58
  $model->status = IP_Model::STATUS_BLOCKED;
72
  $lock_log->user_agent = $_SERVER['HTTP_USER_AGENT'];
73
  if ( $force && $blacklist ) {
74
  $lock_log->log = esc_html__( "Lockout occurred: Attempting to login with a banned username.", wp_defender()->domain );
75
+ } elseif ( ! empty( $log->tried ) ) {
76
+ $lock_log->log = sprintf( esc_html__( "Lockout occurred: Too many failed login attempts for the username %s", wp_defender()->domain ), $log->tried );
77
  } else {
78
  $lock_log->log = esc_html__( "Lockout occurred: Too many failed login attempts", wp_defender()->domain );
79
  }
119
  'type' => Log_Model::ERROR_404,
120
  'blog_id' => get_current_blog_id(),
121
  'date' => array(
122
+ 'compare' => '>',
123
  'value' => $after
124
  )
125
  ) );
130
  $model->ip = $log->ip;
131
  $model->status = IP_Model::STATUS_NORMAL;
132
  }
133
+
134
+ //filter out the extension
135
+ $ignoresFileTypes = $settings->get404Ignorelist();
136
+ foreach ( $logs as $k => $log ) {
137
+ $ext = pathinfo( $log->log, PATHINFO_EXTENSION );
138
+ if ( in_array( $ext, $ignoresFileTypes ) ) {
139
+ unset( $logs[ $k ] );
140
+ }
141
+ }
142
+
143
  if ( count( $logs ) >= $settings->detect_404_threshold ) {
144
+ //we need to check the extension
145
  $model->status = IP_Model::STATUS_BLOCKED;
146
  $model->release_time = strtotime( '+ ' . $settings->detect_404_lockout_duration . ' seconds' );
147
  $model->lockout_message = $settings->detect_404_lockout_message;
398
  return false;
399
  }
400
 
401
+ public static function maybeSendNotification( $type, $model, $settings ) {
402
+ $lastSentKey = $type == 'login' ? 'lastSentLockout' : 'lastSent404';
403
+ $stopTimeKey = $type == 'login' ? 'stopTimeLockout' : 'stopTime404';
404
+ if ( $settings->cooldown_enabled ) {
405
+ //check the last time,and check the status
406
+ $lastSent = $model->getMeta( $lastSentKey );
407
+ $stopTime = $model->getMeta( $stopTimeKey, false );
408
+ $currentTime = apply_filters( 'wd_lockout_notification_current_time', time() );
409
+ if ( $stopTime && $currentTime < $stopTime ) {
410
+ //no further email
411
+ return false;
412
+ }
413
+ //we need to check if we can lock
414
+ if ( $lastSent == false ) {
415
+ //no info, we need to init
416
+ $lastSent = time();
417
+ $model->updateMeta( $lastSentKey, $lastSent );
418
+ }
419
+ //we have last sent value here, now need to check the amount from now to last sent
420
+ if ( $stopTime && $lastSent < $stopTime ) {
421
+ $lastSent = $stopTime;
422
+ }
423
+
424
+ $count = Log_Model::count( array(
425
+ 'type' => $type == 'login' ? Log_Model::AUTH_LOCK : Log_Model::LOCKOUT_404,
426
+ 'blog_id' => get_current_blog_id(),
427
+ 'date' => array(
428
+ 'compare' => '>',
429
+ 'value' => $lastSent
430
+ )
431
+ ) );
432
+ if ( $count >= $settings->cooldown_number_lockout ) {
433
+ $model->updateMeta( $stopTimeKey, strtotime( '+' . $settings->cooldown_period . ' hours' ) );
434
+ $model->updateMeta( $lastSentKey, time() );
435
+ }
436
+ }
437
+
438
+ return true;
439
+ }
440
+
441
  /**
442
  *
443
  */
474
  dbDelta( $sql );
475
  }
476
 
477
+ public static function alterTableFor171() {
478
+ global $wpdb;
479
+ $tableName1 = $wpdb->base_prefix . 'defender_lockout_log';
480
+ $tableName2 = $wpdb->base_prefix . 'defender_lockout';
481
+ $check = "SHOW COLUMNS FROM {$tableName1} LIKE 'tried';";
482
+ $check = $wpdb->get_col( $check );
483
+ if ( count( $check ) == 0 ) {
484
+ $sql = "ALTER TABLE " . $tableName1 . " ADD COLUMN `tried` VARCHAR(255);";
485
+ $wpdb->query( $sql );
486
+ }
487
+ $check = "SHOW COLUMNS FROM {$tableName2} LIKE 'meta';";
488
+ $check = $wpdb->get_col( $check );
489
+ if ( count( $check ) == 0 ) {
490
+ $sql = "ALTER TABLE " . $tableName2 . " ADD COLUMN `meta` text;";
491
+ $wpdb->query( $sql );
492
+ }
493
+ }
494
+
495
  /**
496
  * @return bool
497
  */
app/module/ip-lockout/component/logs-table.php CHANGED
@@ -320,4 +320,73 @@ class Logs_Table extends \WP_List_Table {
320
 
321
  echo $this->_pagination;
322
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  }
320
 
321
  echo $this->_pagination;
322
  }
323
+
324
+ public function print_column_headers( $with_id = true ) {
325
+ list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
326
+
327
+ $current_url = network_admin_url( 'admin.php?page=wdf-ip-lockout&view=logs' );
328
+
329
+ if ( isset( $_GET['orderby'] ) ) {
330
+ $current_orderby = $_GET['orderby'];
331
+ } else {
332
+ $current_orderby = '';
333
+ }
334
+
335
+ if ( isset( $_GET['order'] ) && 'desc' === $_GET['order'] ) {
336
+ $current_order = 'desc';
337
+ } else {
338
+ $current_order = 'asc';
339
+ }
340
+
341
+ if ( ! empty( $columns['cb'] ) ) {
342
+ static $cb_counter = 1;
343
+ $columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All' ) . '</label>'
344
+ . '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
345
+ $cb_counter ++;
346
+ }
347
+
348
+ foreach ( $columns as $column_key => $column_display_name ) {
349
+ $class = array( 'manage-column', "column-$column_key" );
350
+
351
+ if ( in_array( $column_key, $hidden ) ) {
352
+ $class[] = 'hidden';
353
+ }
354
+
355
+ if ( 'cb' === $column_key ) {
356
+ $class[] = 'check-column';
357
+ } elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) ) {
358
+ $class[] = 'num';
359
+ }
360
+
361
+ if ( $column_key === $primary ) {
362
+ $class[] = 'column-primary';
363
+ }
364
+
365
+ if ( isset( $sortable[ $column_key ] ) ) {
366
+ list( $orderby, $desc_first ) = $sortable[ $column_key ];
367
+
368
+ if ( $current_orderby === $orderby ) {
369
+ $order = 'asc' === $current_order ? 'desc' : 'asc';
370
+ $class[] = 'sorted';
371
+ $class[] = $current_order;
372
+ } else {
373
+ $order = $desc_first ? 'desc' : 'asc';
374
+ $class[] = 'sortable';
375
+ $class[] = $desc_first ? 'asc' : 'desc';
376
+ }
377
+
378
+ $column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
379
+ }
380
+
381
+ $tag = ( 'cb' === $column_key ) ? 'td' : 'th';
382
+ $scope = ( 'th' === $tag ) ? 'scope="col"' : '';
383
+ $id = $with_id ? "id='$column_key'" : '';
384
+
385
+ if ( ! empty( $class ) ) {
386
+ $class = "class='" . join( ' ', $class ) . "'";
387
+ }
388
+
389
+ echo "<$tag $scope $id $class>$column_display_name</$tag>";
390
+ }
391
+ }
392
  }
app/module/ip-lockout/controller/main.php CHANGED
@@ -245,7 +245,7 @@ class Main extends Controller {
245
  'ip' => $ip
246
  ) );
247
  if ( is_object( $model ) && $model->is_locked() ) {
248
- header('HTTP/1.0 403 Forbidden');
249
  header( 'Cache-Control: private' );
250
  $this->renderPartial( 'locked', array(
251
  'message' => $model->lockout_message
@@ -304,7 +304,7 @@ class Main extends Controller {
304
 
305
  $ip = $this->getUserIp();
306
  $settings = Settings::instance();
307
- if ( $settings->report ) {
308
  //report
309
  $this->add_action( 'lockoutReportCron', 'lockoutReportCron' );
310
  }
@@ -383,6 +383,9 @@ class Main extends Controller {
383
  */
384
  public function lockout404Notification( $model, $uri ) {
385
  $settings = Settings::instance();
 
 
 
386
  foreach ( $settings->receipts as $user_id ) {
387
  $user = get_user_by( 'id', $user_id );
388
  if ( is_object( $user ) ) {
@@ -406,6 +409,9 @@ class Main extends Controller {
406
  */
407
  public function lockoutLoginNotification( IP_Model $model, $force, $blacklist ) {
408
  $settings = Settings::instance();
 
 
 
409
  foreach ( $settings->receipts as $user_id ) {
410
  $user = get_user_by( 'id', $user_id );
411
  if ( is_object( $user ) ) {
@@ -453,7 +459,12 @@ class Main extends Controller {
453
  return;
454
  }
455
 
456
- $uri = $_SERVER['REQUEST_URI'];
 
 
 
 
 
457
  if ( in_array( $uri, $settings->get404Whitelist() ) ) {
458
  //it is white list, just return
459
  return;
@@ -464,7 +475,7 @@ class Main extends Controller {
464
  $model = new Log_Model();
465
  $model->ip = $this->getUserIp();
466
  $model->user_agent = $_SERVER['HTTP_USER_AGENT'];
467
- $model->log = esc_url( $_SERVER['REQUEST_URI'] );
468
  $model->date = time();
469
  if ( strlen( $ext ) > 0 && in_array( $ext, $settings->get404Ignorelist() ) ) {
470
  $model->type = Log_Model::ERROR_404_IGNORE;
@@ -487,6 +498,7 @@ class Main extends Controller {
487
  $model->log = sprintf( esc_html__( "Failed login attempt with username %s", wp_defender()->domain ), $username );
488
  $model->date = time();
489
  $model->type = 'auth_fail';
 
490
  $model->save();
491
 
492
  $settings = Settings::instance();
@@ -851,8 +863,19 @@ class Main extends Controller {
851
  if ( ! $this->checkPermission() ) {
852
  return;
853
  }
 
854
  $totalItems = get_site_option( 'defenderLogsTotal' );
855
- $params = array(
 
 
 
 
 
 
 
 
 
 
856
  'date' => array(
857
  'compare' => '>=',
858
  'value' => strtotime( '-30 days' )
@@ -870,10 +893,11 @@ class Main extends Controller {
870
  ) );
871
  }
872
 
873
- $logs = Log_Model_Legacy::findAll( $params, 'id', 'DESC', '0,50' );
874
- $logs = array_filter( $logs );
875
- $ips = IP_Model_Legacy::findAll( array(), 'id', 'DESC', '0,50' );
876
- $ips = array_filter( $ips );
 
877
  if ( is_array( $logs ) && count( $logs ) ) {
878
  foreach ( $logs as $item ) {
879
  $model = new Log_Model();
@@ -883,6 +907,7 @@ class Main extends Controller {
883
  $model->save();
884
  $item->delete();
885
  }
 
886
  }
887
 
888
  if ( is_array( $ips ) && count( $ips ) ) {
@@ -894,6 +919,8 @@ class Main extends Controller {
894
  $model->save();
895
  $item->delete();
896
  }
 
 
897
  }
898
 
899
  if ( empty( $logs ) && empty( $ips ) ) {
@@ -902,15 +929,15 @@ class Main extends Controller {
902
  delete_site_option( 'defenderLogsMovedCount' );
903
  delete_site_option( 'defenderLockoutNeedUpdateLog' );
904
  wp_send_json_success( array(
905
- 'message' => __( "Thanks for your patience. All sets!", wp_defender()->domain )
906
  ) );
907
  }
908
 
909
  $count = get_site_option( 'defenderLogsMovedCount', 0 );
910
- $count += 200;
911
  update_site_option( 'defenderLogsMovedCount', $count );
912
  wp_send_json_error( array(
913
- 'progress' => round( ( $count / $totalItems ) * 200, 2 ) > 100 ? 100 : round( ( $count / $totalItems ) * 200, 2 )
914
  ) );
915
  }
916
  }
245
  'ip' => $ip
246
  ) );
247
  if ( is_object( $model ) && $model->is_locked() ) {
248
+ header( 'HTTP/1.0 403 Forbidden' );
249
  header( 'Cache-Control: private' );
250
  $this->renderPartial( 'locked', array(
251
  'message' => $model->lockout_message
304
 
305
  $ip = $this->getUserIp();
306
  $settings = Settings::instance();
307
+ if ( $settings->report && $this->hasMethod( 'lockoutReportCron' ) ) {
308
  //report
309
  $this->add_action( 'lockoutReportCron', 'lockoutReportCron' );
310
  }
383
  */
384
  public function lockout404Notification( $model, $uri ) {
385
  $settings = Settings::instance();
386
+ if ( ! Login_Protection_Api::maybeSendNotification( '404', $model, $settings ) ) {
387
+ return;
388
+ }
389
  foreach ( $settings->receipts as $user_id ) {
390
  $user = get_user_by( 'id', $user_id );
391
  if ( is_object( $user ) ) {
409
  */
410
  public function lockoutLoginNotification( IP_Model $model, $force, $blacklist ) {
411
  $settings = Settings::instance();
412
+ if ( ! Login_Protection_Api::maybeSendNotification( 'login', $model, $settings ) ) {
413
+ return;
414
+ }
415
  foreach ( $settings->receipts as $user_id ) {
416
  $user = get_user_by( 'id', $user_id );
417
  if ( is_object( $user ) ) {
459
  return;
460
  }
461
 
462
+ $uri = $_SERVER['REQUEST_URI'];
463
+ $absUrl = parse_url( get_site_url(), PHP_URL_PATH );
464
+ if ( strpos( $uri, $absUrl ) === 0 ) {
465
+ $uri = substr( $uri, strlen( $absUrl ) );
466
+ }
467
+ $uri = rtrim( $uri, '/' );
468
  if ( in_array( $uri, $settings->get404Whitelist() ) ) {
469
  //it is white list, just return
470
  return;
475
  $model = new Log_Model();
476
  $model->ip = $this->getUserIp();
477
  $model->user_agent = $_SERVER['HTTP_USER_AGENT'];
478
+ $model->log = esc_url( $uri );
479
  $model->date = time();
480
  if ( strlen( $ext ) > 0 && in_array( $ext, $settings->get404Ignorelist() ) ) {
481
  $model->type = Log_Model::ERROR_404_IGNORE;
498
  $model->log = sprintf( esc_html__( "Failed login attempt with username %s", wp_defender()->domain ), $username );
499
  $model->date = time();
500
  $model->type = 'auth_fail';
501
+ $model->tried = $username;
502
  $model->save();
503
 
504
  $settings = Settings::instance();
863
  if ( ! $this->checkPermission() ) {
864
  return;
865
  }
866
+
867
  $totalItems = get_site_option( 'defenderLogsTotal' );
868
+ $resetFlag = get_site_option( 'defenderMigrateNeedReset' );
869
+ if ( $totalItems !== false && $resetFlag === false ) {
870
+ //reset it
871
+ delete_site_option( 'defenderLogsTotal' );
872
+ delete_site_option( 'defenderLogsMovedCount' );
873
+ update_site_option( 'defenderMigrateNeedReset', 1 );
874
+ wp_send_json_error( array(
875
+ 'progress' => 0
876
+ ) );
877
+ }
878
+ $params = array(
879
  'date' => array(
880
  'compare' => '>=',
881
  'value' => strtotime( '-30 days' )
893
  ) );
894
  }
895
 
896
+ $logs = Log_Model_Legacy::findAll( $params, 'id', 'DESC', '0,50' );
897
+ $logs = array_filter( $logs );
898
+ $ips = IP_Model_Legacy::findAll( array(), 'id', 'DESC', '0,50' );
899
+ $ips = array_filter( $ips );
900
+ $internalCount = 0;
901
  if ( is_array( $logs ) && count( $logs ) ) {
902
  foreach ( $logs as $item ) {
903
  $model = new Log_Model();
907
  $model->save();
908
  $item->delete();
909
  }
910
+ $internalCount += count( $logs );
911
  }
912
 
913
  if ( is_array( $ips ) && count( $ips ) ) {
919
  $model->save();
920
  $item->delete();
921
  }
922
+
923
+ $internalCount += count( $ips );
924
  }
925
 
926
  if ( empty( $logs ) && empty( $ips ) ) {
929
  delete_site_option( 'defenderLogsMovedCount' );
930
  delete_site_option( 'defenderLockoutNeedUpdateLog' );
931
  wp_send_json_success( array(
932
+ 'message' => __( "Thanks for your patience. All set.", wp_defender()->domain )
933
  ) );
934
  }
935
 
936
  $count = get_site_option( 'defenderLogsMovedCount', 0 );
937
+ $count += $internalCount;
938
  update_site_option( 'defenderLogsMovedCount', $count );
939
  wp_send_json_error( array(
940
+ 'progress' => round( ( $count / $totalItems ) * 100, 2 ) > 100 ? 100 : round( ( $count / $totalItems ) * 100, 2 )
941
  ) );
942
  }
943
  }
app/module/ip-lockout/model/ip-model.php CHANGED
@@ -22,6 +22,7 @@ class IP_Model extends DB_Model {
22
  public $lock_time_404;
23
  public $attempt;
24
  public $attempt_404;
 
25
 
26
  /**
27
  * @return bool
@@ -42,4 +43,71 @@ class IP_Model extends DB_Model {
42
 
43
  return false;
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
22
  public $lock_time_404;
23
  public $attempt;
24
  public $attempt_404;
25
+ public $meta;
26
 
27
  /**
28
  * @return bool
43
 
44
  return false;
45
  }
46
+
47
+ /**
48
+ * @param $key
49
+ * @param null $default
50
+ *
51
+ * @return mixed|null
52
+ */
53
+ public function getMeta( $key, $default = null ) {
54
+ $meta = $this->meta;
55
+ if ( ! is_array( $meta ) ) {
56
+ $meta = maybe_unserialize( $meta );
57
+ }
58
+
59
+ if ( ! is_array( $meta ) ) {
60
+ $meta = array();
61
+ }
62
+
63
+ if ( isset( $meta[ $key ] ) ) {
64
+ return $meta[ $key ];
65
+ }
66
+
67
+ return $default;
68
+ }
69
+
70
+ /**
71
+ * @param $key
72
+ * @param $value
73
+ */
74
+ public function updateMeta( $key, $value ) {
75
+ $meta = $this->meta;
76
+ if ( ! is_array( $meta ) ) {
77
+ $meta = maybe_unserialize( $meta );
78
+ }
79
+
80
+ if ( ! is_array( $meta ) ) {
81
+ $meta = array();
82
+ }
83
+
84
+ $meta[ $key ] = $value;
85
+ $this->meta = serialize( $meta );
86
+ $this->save();
87
+ }
88
+
89
+ public function events() {
90
+ $that = $this;
91
+
92
+ return array(
93
+ self::EVENT_BEFORE_INSERT => array(
94
+ array(
95
+ function () use ( $that ) {
96
+ if ( is_array( $that->meta ) ) {
97
+ $that->meta = serialize( $that->meta );
98
+ }
99
+ }
100
+ )
101
+ ),
102
+ self::EVENT_BEFORE_UPDATE => array(
103
+ array(
104
+ function () use ( $that ) {
105
+ if ( is_array( $that->meta ) ) {
106
+ $that->meta = serialize( $that->meta );
107
+ }
108
+ }
109
+ )
110
+ )
111
+ );
112
+ }
113
  }
app/module/ip-lockout/model/log-model.php CHANGED
@@ -20,6 +20,7 @@ class Log_Model extends DB_Model {
20
  public $user_agent;
21
  public $type;
22
  public $blog_id;
 
23
 
24
  /**
25
  * @return string
20
  public $user_agent;
21
  public $type;
22
  public $blog_id;
23
+ public $tried;
24
 
25
  /**
26
  * @return string
app/module/ip-lockout/model/settings.php CHANGED
@@ -50,6 +50,10 @@ class Settings extends \Hammer\WP\Settings {
50
  public $report_receipts = array();
51
  public $lastReportSent;
52
 
 
 
 
 
53
  public $cache = array();
54
 
55
  public function __construct( $id, $isMulti ) {
@@ -81,7 +85,8 @@ class Settings extends \Hammer\WP\Settings {
81
  'login_protection_login_attempt',
82
  'login_protection_lockout_timeframe',
83
  'detect_404_threshold',
84
- 'detect_404_timeframe'
 
85
  ),
86
  'integer',
87
  )
@@ -104,6 +109,7 @@ class Settings extends \Hammer\WP\Settings {
104
  public function get404Ignorelist() {
105
  $arr = array_filter( explode( PHP_EOL, $this->detect_404_ignored_filetypes ) );
106
  $arr = array_map( 'trim', $arr );
 
107
 
108
  return $arr;
109
  }
50
  public $report_receipts = array();
51
  public $lastReportSent;
52
 
53
+ public $cooldown_enabled = false;
54
+ public $cooldown_number_lockout = '3';
55
+ public $cooldown_period = '24';
56
+
57
  public $cache = array();
58
 
59
  public function __construct( $id, $isMulti ) {
85
  'login_protection_login_attempt',
86
  'login_protection_lockout_timeframe',
87
  'detect_404_threshold',
88
+ 'detect_404_timeframe',
89
+ 'storage_days',
90
  ),
91
  'integer',
92
  )
109
  public function get404Ignorelist() {
110
  $arr = array_filter( explode( PHP_EOL, $this->detect_404_ignored_filetypes ) );
111
  $arr = array_map( 'trim', $arr );
112
+ $arr = array_map( 'strtolower', $arr );
113
 
114
  return $arr;
115
  }
app/module/ip-lockout/view/notification/enabled.php CHANGED
@@ -58,8 +58,67 @@
58
  $email_search->renderInput() ?>
59
  </div>
60
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  <div class="clear line"></div>
62
- <?php wp_nonce_field( 'saveLockoutSettings' ) ?>
63
  <input type="hidden" name="action" value="saveLockoutSettings"/>
64
  <button type="submit" class="button button-primary float-r">
65
  <?php esc_html_e( "UPDATE SETTINGS", wp_defender()->domain ) ?>
58
  $email_search->renderInput() ?>
59
  </div>
60
  </div>
61
+ <div class="columns">
62
+ <div class="column is-one-third">
63
+ <label>
64
+ <?php esc_html_e( "Repeat Lockouts", wp_defender()->domain ) ?>
65
+ </label>
66
+ <span class="sub">
67
+ <?php esc_html_e( "If you’re getting too many emails from IPs who are repeatedly being locked out you can turn them off for a period of time.", wp_defender()->domain ) ?>
68
+ </span>
69
+ </div>
70
+ <div class="column">
71
+ <span class="toggle float-l">
72
+ <input type="hidden" name="cooldown_enabled" value="0"/>
73
+ <input type="checkbox"
74
+ name="cooldown_enabled" <?php checked( 1, $settings->cooldown_enabled ) ?>
75
+ value="1" class="toggle-checkbox"
76
+ id="cooldown_enabled"/>
77
+ <label class="toggle-label" for="cooldown_enabled"></label>
78
+ </span>
79
+ <label><?php _e( "Limit email notifications for repeat lockouts", wp_defender()->domain ) ?></label>
80
+ <div class="well well-white schedule-box">
81
+ <label><strong><?php _e( "Threshold", wp_defender()->domain ) ?></strong>
82
+ - <?php _e( "The number of lockouts before we turn off emails", wp_defender()->domain ) ?>
83
+ </label>
84
+ <select name="cooldown_number_lockout">
85
+ <option <?php selected( '1', $settings->cooldown_number_lockout ) ?> value="1">1
86
+ </option>
87
+ <option <?php selected( '3', $settings->cooldown_number_lockout ) ?> value="3">3
88
+ </option>
89
+ <option <?php selected( '5', $settings->cooldown_number_lockout ) ?> value="5">5
90
+ </option>
91
+ <option <?php selected( '10', $settings->cooldown_number_lockout ) ?> value="10">10
92
+ </option>
93
+ </select>
94
+ <label><strong><?php _e( "Cool Off Period", wp_defender()->domain ) ?></strong>
95
+ - <?php _e( "For how long should we turn them off?", wp_defender()->domain ) ?>
96
+ </label>
97
+ <select name="cooldown_period" class="mline">
98
+ <option <?php selected( '1', $settings->cooldown_period ) ?>
99
+ value="1"><?php _e( "1 hour", wp_defender()->domain ) ?></option>
100
+ <option <?php selected( '2', $settings->cooldown_period ) ?>
101
+ value="2"><?php _e( "2 hours", wp_defender()->domain ) ?></option>
102
+ <option <?php selected( '6', $settings->cooldown_period ) ?>
103
+ value="6"><?php _e( "6 hours", wp_defender()->domain ) ?></option>
104
+ <option <?php selected( '12', $settings->cooldown_period ) ?>
105
+ value="12"><?php _e( "12 hours", wp_defender()->domain ) ?></option>
106
+ <option <?php selected( '24', $settings->cooldown_period ) ?>
107
+ value="24"><?php _e( "24 hours", wp_defender()->domain ) ?></option>
108
+ <option <?php selected( '36', $settings->cooldown_period ) ?>
109
+ value="36"><?php _e( "36 hours", wp_defender()->domain ) ?></option>
110
+ <option <?php selected( '48', $settings->cooldown_period ) ?>
111
+ value="48"><?php _e( "48 hours", wp_defender()->domain ) ?></option>
112
+ <option <?php selected( '168', $settings->cooldown_period ) ?>
113
+ value="168"><?php _e( "7 days", wp_defender()->domain ) ?></option>
114
+ <option <?php selected( '720', $settings->cooldown_period ) ?>
115
+ value="720"><?php _e( "30 days", wp_defender()->domain ) ?></option>
116
+ </select>
117
+ </div>
118
+ </div>
119
+ </div>
120
  <div class="clear line"></div>
121
+ <?php wp_nonce_field( 'saveLockoutSettings' ) ?>
122
  <input type="hidden" name="action" value="saveLockoutSettings"/>
123
  <button type="submit" class="button button-primary float-r">
124
  <?php esc_html_e( "UPDATE SETTINGS", wp_defender()->domain ) ?>
app/module/scan.php CHANGED
@@ -16,6 +16,10 @@ class Scan extends Module {
16
 
17
  private function _registerPostTpe() {
18
  register_post_type( 'wdf_scan', array(
 
 
 
 
19
  'capability_type' => array( 'wdf_scan', 'wdf_scans' ),
20
  'supports' => array( '' ),
21
  'hierarchical' => false,
@@ -31,6 +35,10 @@ class Scan extends Module {
31
  'rewrite' => false,
32
  ) );
33
  register_post_type( 'wdf_scan_item', array(
 
 
 
 
34
  'capability_type' => array( 'wdf_scan_item', 'wdf_scan_items' ),
35
  'supports' => array( '' ),
36
  'hierarchical' => false,
16
 
17
  private function _registerPostTpe() {
18
  register_post_type( 'wdf_scan', array(
19
+ 'labels' => array(
20
+ 'name' => __( "Scans", wp_defender()->domain ),
21
+ 'singular_name' => __( "Scan", wp_defender()->domain )
22
+ ),
23
  'capability_type' => array( 'wdf_scan', 'wdf_scans' ),
24
  'supports' => array( '' ),
25
  'hierarchical' => false,
35
  'rewrite' => false,
36
  ) );
37
  register_post_type( 'wdf_scan_item', array(
38
+ 'labels' => array(
39
+ 'name' => __( "Scan Items", wp_defender()->domain ),
40
+ 'singular_name' => __( "Scan Item", wp_defender()->domain )
41
+ ),
42
  'capability_type' => array( 'wdf_scan_item', 'wdf_scan_items' ),
43
  'supports' => array( '' ),
44
  'hierarchical' => false,
app/module/scan/component/result-table.php CHANGED
@@ -91,7 +91,7 @@ class Result_Table extends \WP_List_Table {
91
  <?php wp_nonce_field( 'unIgnoreItem' ) ?>
92
  <button type="submit" tooltip="<?php esc_attr_e( "Restore File", wp_defender()->domain ) ?>"
93
  class="button button-small">
94
- <i class="wdv-icon wdv-icon-fw wdv-icon-refresh"></i>
95
  </button>
96
  </form>
97
  <?php
@@ -151,7 +151,7 @@ class Result_Table extends \WP_List_Table {
151
  public function column_col_action( Result_Item $item ) {
152
  $content = $item->renderDialog();
153
 
154
- $content .= '<a href="#dia_' . $item->id . '" rel="dialog" tooltip="' . esc_attr__( "Fix Issue", wp_defender()->domain ) . '" class="fix">
155
  <img src="' . wp_defender()->getPluginUrl() . 'assets/img/icon-fix.svg">
156
  </a>';
157
 
91
  <?php wp_nonce_field( 'unIgnoreItem' ) ?>
92
  <button type="submit" tooltip="<?php esc_attr_e( "Restore File", wp_defender()->domain ) ?>"
93
  class="button button-small">
94
+ <i class="wdv-icon wdv-icon-fw wdv-icon-refresh" aria-hidden="true"></i>
95
  </button>
96
  </form>
97
  <?php
151
  public function column_col_action( Result_Item $item ) {
152
  $content = $item->renderDialog();
153
 
154
+ $content .= '<a href="#dia_' . $item->id . '" rel="dialog" role="button" tooltip="' . esc_attr__( "Fix Issue", wp_defender()->domain ) . '" class="fix">
155
  <img src="' . wp_defender()->getPluginUrl() . 'assets/img/icon-fix.svg">
156
  </a>';
157
 
app/module/scan/component/scan-api.php CHANGED
@@ -140,6 +140,8 @@ class Scan_Api extends Component {
140
  $files = File_Helper::findFiles( WP_CONTENT_DIR, true, false, array(), array(
141
  'ext' => array( 'php' )
142
  ), true, $settings->max_filesize );
 
 
143
 
144
  $cache->set( self::CACHE_CONTENT, $files );
145
 
140
  $files = File_Helper::findFiles( WP_CONTENT_DIR, true, false, array(), array(
141
  'ext' => array( 'php' )
142
  ), true, $settings->max_filesize );
143
+ //include wp-config.php here
144
+ $files[] = ABSPATH . 'wp-config.php';
145
 
146
  $cache->set( self::CACHE_CONTENT, $files );
147
 
app/module/scan/model/settings.php CHANGED
@@ -82,7 +82,7 @@ class Settings extends \Hammer\WP\Settings {
82
  /**
83
  * @var string
84
  */
85
- public $time = '04:00';
86
 
87
  public $lastReportSent;
88
 
82
  /**
83
  * @var string
84
  */
85
+ public $time = '0:00';
86
 
87
  public $lastReportSent;
88
 
app/module/scan/view/cleaned.php CHANGED
@@ -11,7 +11,7 @@
11
  } else {
12
  ?>
13
  <div class="well well-blue with-cap">
14
- <i class="def-icon icon-warning"></i>
15
  <?php _e( "You haven't cleaned any suspicious files yet. When this action is available, any cleaned files will appear here.", wp_defender()->domain ) ?>
16
  </div>
17
  <?php
11
  } else {
12
  ?>
13
  <div class="well well-blue with-cap">
14
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
15
  <?php _e( "You haven't cleaned any suspicious files yet. When this action is available, any cleaned files will appear here.", wp_defender()->domain ) ?>
16
  </div>
17
  <?php
app/module/scan/view/ignored.php CHANGED
@@ -14,7 +14,7 @@
14
  } else {
15
  ?>
16
  <div class="well well-blue with-cap">
17
- <i class="def-icon icon-warning"></i>
18
  <?php _e( "You haven't ignored any suspicious files yet. Ignored files appear here and can be restored at any times.", wp_defender()->domain ) ?>
19
  </div>
20
  <?php
14
  } else {
15
  ?>
16
  <div class="well well-blue with-cap">
17
+ <i class="def-icon icon-warning" aria-hidden="true"></i>
18
  <?php _e( "You haven't ignored any suspicious files yet. Ignored files appear here and can be restored at any times.", wp_defender()->domain ) ?>
19
  </div>
20
  <?php
app/module/scan/view/issues.php CHANGED
@@ -33,7 +33,7 @@
33
  } else {
34
  ?>
35
  <div class="well well-green with-cap">
36
- <i class="def-icon icon-tick"></i>
37
  <?php _e( "Your code is currently clean! There were no issues found during the last scan, though you can always perform a new scan anytime.", wp_defender()->domain ) ?>
38
  </div>
39
  <?php
33
  } else {
34
  ?>
35
  <div class="well well-green with-cap">
36
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
37
  <?php _e( "Your code is currently clean! There were no issues found during the last scan, though you can always perform a new scan anytime.", wp_defender()->domain ) ?>
38
  </div>
39
  <?php
app/module/scan/view/layouts/layout.php CHANGED
@@ -23,17 +23,17 @@
23
  <div>
24
  <h5 class="def-issues def-issues-top-left"><?php echo $countAll = $model->countAll( \WP_Defender\Module\Scan\Model\Result_Item::STATUS_ISSUE ) ?></h5>
25
  <?php if ( $countAll > 0 ) : ?>
26
- <span class="def-issues-top-left-icon" tooltip="<?php esc_attr_e( sprintf( __('You have %d suspicious file(s) needing attention', wp_defender()->domain ), $countAll ) ); ?>">
27
  <?php else: ?>
28
- <span class="def-issues-top-left-icon" tooltip="<?php esc_attr_e( 'Your code is clean, the skies are clear', wp_defender()->domain ); ?>">
29
  <?php endif; ?>
30
  <?php
31
- $icon = $countAll == 0 ? ' <i class="def-icon icon-tick"></i>' : ' <i class="def-icon icon-warning fill-red"></i>';
32
  echo $icon;
33
  ?>
34
  </span>
35
  <div class="clear"></div>
36
- <span class="sub"><?php _e( "File scanning issues need attention", wp_defender()->domain ) ?></span>
37
  <div class="clear mline"></div>
38
  <strong><?php echo $lastScanDate ?></strong>
39
  <span class="sub"><?php _e( "Last scan", wp_defender()->domain ) ?></span>
@@ -88,65 +88,69 @@
88
  </div>
89
  <div class="row">
90
  <div class="col-third">
91
- <ul class="inner-nav is-hidden-mobile">
92
- <li class="issues-nav">
93
- <a class="<?php echo \Hammer\Helper\HTTP_Helper::retrieve_get( 'view', false ) == false ? 'active' : null ?>"
94
- href="<?php echo network_admin_url( 'admin.php?page=wdf-scan' ) ?>">
95
- <?php _e( "Issues", wp_defender()->domain ) ?>
96
- <?php
97
- $issues = $model->countAll( \WP_Defender\Module\Scan\Model\Result_Item::STATUS_ISSUE );
98
- $tooltip = '';
99
- if ( $issues > 0 ) :
100
- $tooltip = 'tooltip="' . esc_attr( sprintf( __("You have %d suspicious file(s) needing attention", wp_defender()->domain ), $countAll ) ) . '"';
101
- endif;
102
- echo $issues > 0 ? '<span class="def-tag tag-error def-issues-below" ' . $tooltip . '>' . $issues . '</span>' : '' ?>
103
- </a>
104
- </li>
105
- <!-- <li>-->
106
- <!-- <a class="-->
107
- <?php //echo $controller->isView( 'cleaned' ) ? 'active' : null ?><!--"-->
108
- <!-- href="-->
109
- <?php //echo network_admin_url( 'admin.php?page=wdf-scan&view=cleaned' ) ?><!--">--><?php //_e( "Cleaned", wp_defender()->domain ) ?>
110
- <!-- <span>-->
111
- <!-- --><?php
112
- // $issues = $model->countAll( \WP_Defender\Module\Scan\Model\Result_Item::STATUS_FIXED );
113
- // echo $issues > 0 ? $issues : '' ?>
114
- <!-- </span>-->
115
- <!-- </a>-->
116
- <!-- </li>-->
117
- <li>
118
- <a class="<?php echo $controller->isView( 'ignored' ) ? 'active' : null ?>"
119
- href="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=ignored' ) ?>">
120
- <?php _e( "Ignored", wp_defender()->domain ) ?>
121
- <span class="def-ignored">
122
- <?php
123
- $issues = $model->countAll( \WP_Defender\Module\Scan\Model\Result_Item::STATUS_IGNORED );
124
- echo $issues > 0 ? $issues : '' ?>
125
- </span>
126
- </a>
127
- </li>
128
- <li>
129
- <a class="<?php echo $controller->isView( 'settings' ) ? 'active' : null ?>"
130
- href="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=settings' ) ?>">
131
- <?php _e( "Settings", wp_defender()->domain ) ?></a>
132
- </li>
133
- <li>
134
- <a class="<?php echo $controller->isView( 'reporting' ) ? 'active' : null ?>"
135
- href="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=reporting' ) ?>">
136
- <?php _e( "Reporting", wp_defender()->domain ) ?></a>
137
- </li>
138
- </ul>
 
 
139
  <div class="is-hidden-tablet mline">
140
- <select class="mobile-nav">
141
- <option <?php selected( '', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
142
- value="<?php echo network_admin_url( 'admin.php?page=wdf-scan' ) ?>"><?php _e( "Issues", wp_defender()->domain ) ?></option>
143
- <option <?php selected( 'ignored', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
144
- value="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=ignored' ) ?>"><?php _e( "Ignored", wp_defender()->domain ) ?></option>
145
- <option <?php selected( 'settings', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
146
- value="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=settings' ) ?>"><?php _e( "Settings", wp_defender()->domain ) ?></option>
147
- <option <?php selected( 'reporting', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
148
- value="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=reporting' ) ?>"><?php _e( "Reporting", wp_defender()->domain ) ?></option>
149
- </select>
 
 
150
  </div>
151
  </div>
152
  <div class="col-two-third">
23
  <div>
24
  <h5 class="def-issues def-issues-top-left"><?php echo $countAll = $model->countAll( \WP_Defender\Module\Scan\Model\Result_Item::STATUS_ISSUE ) ?></h5>
25
  <?php if ( $countAll > 0 ) : ?>
26
+ <span class="def-issues-top-left-icon" tooltip="<?php esc_attr_e( sprintf( __('You have %d suspicious file(s) needing attention.', wp_defender()->domain ), $countAll ) ); ?>">
27
  <?php else: ?>
28
+ <span class="def-issues-top-left-icon" tooltip="<?php esc_attr_e( 'Your code is clean, the skies are clear.', wp_defender()->domain ); ?>">
29
  <?php endif; ?>
30
  <?php
31
+ $icon = $countAll == 0 ? ' <i class="def-icon icon-tick" aria-hidden="true"></i>' : ' <i class="def-icon icon-warning fill-red" aria-hidden="true"></i>';
32
  echo $icon;
33
  ?>
34
  </span>
35
  <div class="clear"></div>
36
+ <span class="sub"><?php _e( "File scanning issues need attention.", wp_defender()->domain ) ?></span>
37
  <div class="clear mline"></div>
38
  <strong><?php echo $lastScanDate ?></strong>
39
  <span class="sub"><?php _e( "Last scan", wp_defender()->domain ) ?></span>
88
  </div>
89
  <div class="row">
90
  <div class="col-third">
91
+ <nav role="navigation" aria-label="Filters">
92
+ <ul class="inner-nav is-hidden-mobile">
93
+ <li class="issues-nav">
94
+ <a class="<?php echo \Hammer\Helper\HTTP_Helper::retrieve_get( 'view', false ) == false ? 'active' : null ?>"
95
+ href="<?php echo network_admin_url( 'admin.php?page=wdf-scan' ) ?>">
96
+ <?php _e( "Issues", wp_defender()->domain ) ?>
97
+ <?php
98
+ $issues = $model->countAll( \WP_Defender\Module\Scan\Model\Result_Item::STATUS_ISSUE );
99
+ $tooltip = '';
100
+ if ( $issues > 0 ) :
101
+ $tooltip = 'tooltip="' . esc_attr( sprintf( __("You have %d suspicious file(s) needing attention", wp_defender()->domain ), $countAll ) ) . '"';
102
+ endif;
103
+ echo $issues > 0 ? '<span class="def-tag tag-error def-issues-below" ' . $tooltip . '>' . $issues . '</span>' : '' ?>
104
+ </a>
105
+ </li>
106
+ <!-- <li>-->
107
+ <!-- <a class="-->
108
+ <?php //echo $controller->isView( 'cleaned' ) ? 'active' : null ?><!--"-->
109
+ <!-- href="-->
110
+ <?php //echo network_admin_url( 'admin.php?page=wdf-scan&view=cleaned' ) ?><!--">--><?php //_e( "Cleaned", wp_defender()->domain ) ?>
111
+ <!-- <span>-->
112
+ <!-- --><?php
113
+ // $issues = $model->countAll( \WP_Defender\Module\Scan\Model\Result_Item::STATUS_FIXED );
114
+ // echo $issues > 0 ? $issues : '' ?>
115
+ <!-- </span>-->
116
+ <!-- </a>-->
117
+ <!-- </li>-->
118
+ <li>
119
+ <a class="<?php echo $controller->isView( 'ignored' ) ? 'active' : null ?>"
120
+ href="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=ignored' ) ?>">
121
+ <?php _e( "Ignored", wp_defender()->domain ) ?>
122
+ <span class="def-ignored">
123
+ <?php
124
+ $issues = $model->countAll( \WP_Defender\Module\Scan\Model\Result_Item::STATUS_IGNORED );
125
+ echo $issues > 0 ? $issues : '' ?>
126
+ </span>
127
+ </a>
128
+ </li>
129
+ <li>
130
+ <a class="<?php echo $controller->isView( 'settings' ) ? 'active' : null ?>"
131
+ href="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=settings' ) ?>">
132
+ <?php _e( "Settings", wp_defender()->domain ) ?></a>
133
+ </li>
134
+ <li>
135
+ <a class="<?php echo $controller->isView( 'reporting' ) ? 'active' : null ?>"
136
+ href="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=reporting' ) ?>">
137
+ <?php _e( "Reporting", wp_defender()->domain ) ?></a>
138
+ </li>
139
+ </ul>
140
+ </nav>
141
  <div class="is-hidden-tablet mline">
142
+ <nav role="navigation" aria-label="Filters">
143
+ <select class="mobile-nav">
144
+ <option <?php selected( '', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
145
+ value="<?php echo network_admin_url( 'admin.php?page=wdf-scan' ) ?>"><?php _e( "Issues", wp_defender()->domain ) ?></option>
146
+ <option <?php selected( 'ignored', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
147
+ value="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=ignored' ) ?>"><?php _e( "Ignored", wp_defender()->domain ) ?></option>
148
+ <option <?php selected( 'settings', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
149
+ value="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=settings' ) ?>"><?php _e( "Settings", wp_defender()->domain ) ?></option>
150
+ <option <?php selected( 'reporting', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
151
+ value="<?php echo network_admin_url( 'admin.php?page=wdf-scan&view=reporting' ) ?>"><?php _e( "Reporting", wp_defender()->domain ) ?></option>
152
+ </select>
153
+ </nav>
154
  </div>
155
  </div>
156
  <div class="col-two-third">
app/module/scan/view/pro-feature.php CHANGED
@@ -2,7 +2,7 @@
2
  <div class="wp-defender">
3
  <p class=""><?php _e( "Here’s what you’ll get by upgrading to Defender Pro;", wp_defender()->domain ) ?></p>
4
  <div class="well well-blank with-cap">
5
- <i class="def-icon icon-tick fill-blue"></i>
6
  <strong><?php _e( "Automatic Full File Scans & Notifications", wp_defender()->domain ) ?></strong>
7
  <p class="sub">
8
  <?php _e( "Schedule Defender to automatically run a full file scan daily, weekly or monthly and get email reports
@@ -11,21 +11,21 @@
11
  </p>
12
  </div>
13
  <div class="well well-blank with-cap">
14
- <i class="def-icon icon-tick fill-blue"></i>
15
  <strong><?php _e( "Advanced File Scanning", wp_defender()->domain ) ?></strong>
16
  <p class="sub">
17
  <?php _e( "Defender will go beyond just plugins and themes and scan your entire file system for suspicious code.", wp_defender()->domain ) ?>
18
  </p>
19
  </div>
20
  <div class="well well-blank with-cap">
21
- <i class="def-icon icon-tick fill-blue"></i>
22
  <strong><?php _e( "Audit Logging", wp_defender()->domain ) ?></strong>
23
  <p class="sub">
24
  <?php _e( "Track and log each and every event when changes are made to your website and get detailed reports on what’s going on behind the scenes, including any hacking attempts on your site.", wp_defender()->domain ) ?>
25
  </p>
26
  </div>
27
  <div class="well well-blank with-cap mline">
28
- <i class="def-icon icon-tick fill-blue"></i>
29
  <strong><?php _e( "Tailored Reporting", wp_defender()->domain ) ?></strong>
30
  <p class="sub">
31
  <?php _e( "Get tailored security reports for File Scanning, Audit Logging and IP Lockouts delivered to your inbox so you don’t have to worry about checking in.", wp_defender()->domain ) ?>
2
  <div class="wp-defender">
3
  <p class=""><?php _e( "Here’s what you’ll get by upgrading to Defender Pro;", wp_defender()->domain ) ?></p>
4
  <div class="well well-blank with-cap">
5
+ <i class="def-icon icon-tick fill-blue" aria-hidden="true"></i>
6
  <strong><?php _e( "Automatic Full File Scans & Notifications", wp_defender()->domain ) ?></strong>
7
  <p class="sub">
8
  <?php _e( "Schedule Defender to automatically run a full file scan daily, weekly or monthly and get email reports
11
  </p>
12
  </div>
13
  <div class="well well-blank with-cap">
14
+ <i class="def-icon icon-tick fill-blue" aria-hidden="true"></i>
15
  <strong><?php _e( "Advanced File Scanning", wp_defender()->domain ) ?></strong>
16
  <p class="sub">
17
  <?php _e( "Defender will go beyond just plugins and themes and scan your entire file system for suspicious code.", wp_defender()->domain ) ?>
18
  </p>
19
  </div>
20
  <div class="well well-blank with-cap">
21
+ <i class="def-icon icon-tick fill-blue" aria-hidden="true"></i>
22
  <strong><?php _e( "Audit Logging", wp_defender()->domain ) ?></strong>
23
  <p class="sub">
24
  <?php _e( "Track and log each and every event when changes are made to your website and get detailed reports on what’s going on behind the scenes, including any hacking attempts on your site.", wp_defender()->domain ) ?>
25
  </p>
26
  </div>
27
  <div class="well well-blank with-cap mline">
28
+ <i class="def-icon icon-tick fill-blue" aria-hidden="true"></i>
29
  <strong><?php _e( "Tailored Reporting", wp_defender()->domain ) ?></strong>
30
  <p class="sub">
31
  <?php _e( "Get tailored security reports for File Scanning, Audit Logging and IP Lockouts delivered to your inbox so you don’t have to worry about checking in.", wp_defender()->domain ) ?>
app/module/scan/view/scanning.php CHANGED
@@ -26,7 +26,7 @@
26
  <div class="well mline">
27
  <div class="scan-progress">
28
  <div class="scan-progress-text">
29
- <img src="<?php echo wp_defender()->getPluginUrl() ?>assets/img/loading.gif" width="18"
30
  height="18"/>
31
  <span><?php echo $percent ?>%</span>
32
  </div>
26
  <div class="well mline">
27
  <div class="scan-progress">
28
  <div class="scan-progress-text">
29
+ <img aria-hidden="true" src="<?php echo wp_defender()->getPluginUrl() ?>assets/img/loading.gif" width="18"
30
  height="18"/>
31
  <span><?php echo $percent ?>%</span>
32
  </div>
app/module/scan/view/setting-free.php CHANGED
@@ -25,14 +25,13 @@
25
  <div class="clear mline"></div>
26
  <div class="feature-pre-require">
27
  <div></div>
28
- <a href="#pro-feature" rel="dialog" class="button button-small button-pre"
29
  tooltip="<?php esc_attr_e( "Try Defender Pro free today", wp_defender()->domain ) ?>" >
30
  <?php _e( "Pro Feature", wp_defender()->domain ) ?></a>
31
- <span class="toggle">
32
- <input type="checkbox" class="toggle-checkbox" value="1"
33
- id="scan-vuln"/>
34
- <label class="toggle-label" for="scan-vuln"></label>
35
- </span>
36
  <label for="scan-vuln"><?php _e( "Plugins & Themes", wp_defender()->domain ) ?></label>
37
  <span class="sub inpos">
38
  <?php _e( "Defender looks for publicly reported vulnerabilities in your installed plugins and themes.", wp_defender()->domain ) ?>
@@ -41,14 +40,13 @@
41
  <div class="clear mline"></div>
42
  <div class="feature-pre-require">
43
  <div></div>
44
- <a href="#pro-feature" rel="dialog" class="button button-small button-pre"
45
  tooltip="<?php esc_attr_e( "Try Defender Pro free today", wp_defender()->domain ) ?>">
46
  <?php _e( "Pro Feature", wp_defender()->domain ) ?></a>
47
- <span class="toggle">
48
- <input type="checkbox" class="toggle-checkbox" value="1"
49
- id="scan-content"/>
50
- <label class="toggle-label" for="scan-content"></label>
51
- </span>
52
  <label for="scan-content"><?php _e( "Suspicious Code", wp_defender()->domain ) ?></label>
53
  <span class="sub inpos">
54
  <?php _e( "Defender looks inside all of your files for suspicious and potentially harmful code.", wp_defender()->domain ) ?>
@@ -58,7 +56,7 @@
58
  <div class="clear"></div>
59
  <div class="presale-text">
60
  <div>
61
- <?php printf( __( "Defenders scans through every line of code on your website, searching for anything suspicious. This feature is included when you join WPMU DEV, along with 100+ plugins and themes, 24/7 support and lots of handy site management tools. – <a href=\"%s\">Try it all FREE today!
62
  </a>", wp_defender()->domain ), "https://premium.wpmudev.org/project/wp-defender/?utm_source=defender&utm_medium=plugin&utm_campaign=defender_modal_upgrade" ) ?>
63
  </div>
64
  </div>
@@ -83,11 +81,11 @@
83
  </span>
84
  </div>
85
  <div class="column">
86
- <span class="toggle">
87
  <input type="hidden" name="always_send" value="0"/>
88
- <input type="checkbox" name="always_send" class="toggle-checkbox" value="1"
89
  id="always_send" <?php checked( true, $setting->always_send ) ?>/>
90
- <label class="toggle-label" for="always_send"></label>
91
  </span>
92
  <label><?php _e( "Send all scan report emails", wp_defender()->domain ) ?></label>
93
  </div>
@@ -113,7 +111,7 @@
113
  <div>
114
  <span class="list-label"><?php _e( "When an issue is found", wp_defender()->domain ) ?></span>
115
  <span class="list-detail tr">
116
- <a href="#issue-found" rel="dialog"><?php _e( "Edit", wp_defender()->domain ) ?></a></span>
117
  </div>
118
  </li>
119
  <li>
@@ -121,7 +119,7 @@
121
  <span class="list-label"><?php _e( "When no issues are found", wp_defender()->domain ) ?></span>
122
  <span class="list-detail tr">
123
  <a href="#all-ok"
124
- rel="dialog"><?php _e( "Edit", wp_defender()->domain ) ?></a></span>
125
  </div>
126
  </li>
127
  </ul>
25
  <div class="clear mline"></div>
26
  <div class="feature-pre-require">
27
  <div></div>
28
+ <a href="#pro-feature" role="button" rel="dialog" class="button button-small button-pre"
29
  tooltip="<?php esc_attr_e( "Try Defender Pro free today", wp_defender()->domain ) ?>" >
30
  <?php _e( "Pro Feature", wp_defender()->domain ) ?></a>
31
+ <span class="toggle" aria-hidden="true" role="presentation">
32
+ <input role="presentation" type="checkbox" class="toggle-checkbox" value="1" id="scan-vuln"/>
33
+ <label class="toggle-label" aria-hidden="true" for="scan-vuln"></label>
34
+ </span>
 
35
  <label for="scan-vuln"><?php _e( "Plugins & Themes", wp_defender()->domain ) ?></label>
36
  <span class="sub inpos">
37
  <?php _e( "Defender looks for publicly reported vulnerabilities in your installed plugins and themes.", wp_defender()->domain ) ?>
40
  <div class="clear mline"></div>
41
  <div class="feature-pre-require">
42
  <div></div>
43
+ <a href="#pro-feature" role="button" rel="dialog" class="button button-small button-pre"
44
  tooltip="<?php esc_attr_e( "Try Defender Pro free today", wp_defender()->domain ) ?>">
45
  <?php _e( "Pro Feature", wp_defender()->domain ) ?></a>
46
+ <span class="toggle" aria-hidden="true" role="presentation">
47
+ <input role="presentation" type="checkbox" class="toggle-checkbox" value="1" id="scan-content"/>
48
+ <label class="toggle-label" aria-hidden="true" for="scan-content"></label>
49
+ </span>
 
50
  <label for="scan-content"><?php _e( "Suspicious Code", wp_defender()->domain ) ?></label>
51
  <span class="sub inpos">
52
  <?php _e( "Defender looks inside all of your files for suspicious and potentially harmful code.", wp_defender()->domain ) ?>
56
  <div class="clear"></div>
57
  <div class="presale-text">
58
  <div>
59
+ <?php printf( __( "Defenders scans through every line of code on your website, searching for anything suspicious. This feature is included when you join WPMU DEV, along with 100+ plugins and themes, 24/7 support and lots of handy site management tools. – <a href=\"%s\" role='button'>Try it all FREE today!
60
  </a>", wp_defender()->domain ), "https://premium.wpmudev.org/project/wp-defender/?utm_source=defender&utm_medium=plugin&utm_campaign=defender_modal_upgrade" ) ?>
61
  </div>
62
  </div>
81
  </span>
82
  </div>
83
  <div class="column">
84
+ <span class="toggle" aria-hidden="true" role="presentation">
85
  <input type="hidden" name="always_send" value="0"/>
86
+ <input type="checkbox" role="presentation" name="always_send" class="toggle-checkbox" value="1"
87
  id="always_send" <?php checked( true, $setting->always_send ) ?>/>
88
+ <label class="toggle-label" aria-hidden="true" for="always_send"></label>
89
  </span>
90
  <label><?php _e( "Send all scan report emails", wp_defender()->domain ) ?></label>
91
  </div>
111
  <div>
112
  <span class="list-label"><?php _e( "When an issue is found", wp_defender()->domain ) ?></span>
113
  <span class="list-detail tr">
114
+ <a href="#issue-found" rel="dialog" role='button'><?php _e( "Edit", wp_defender()->domain ) ?></a></span>
115
  </div>
116
  </li>
117
  <li>
119
  <span class="list-label"><?php _e( "When no issues are found", wp_defender()->domain ) ?></span>
120
  <span class="list-detail tr">
121
  <a href="#all-ok"
122
+ rel="dialog" role='button'><?php _e( "Edit", wp_defender()->domain ) ?></a></span>
123
  </div>
124
  </li>
125
  </ul>
app/module/scan/view/setting.php CHANGED
@@ -12,33 +12,33 @@
12
  </span>
13
  </div>
14
  <div class="column">
15
- <span class="toggle">
16
  <input type="hidden" name="scan_core" value="0"/>
17
- <input type="checkbox" name="scan_core" class="toggle-checkbox" id="core-scan" value="1"
18
  <?php checked( true, $setting->scan_core ) ?>/>
19
- <label class="toggle-label" for="core-scan"></label>
20
  </span>
21
  <label for="core-scan"><?php _e( "WordPress Core", wp_defender()->domain ) ?></label>
22
  <span class="sub inpos">
23
  <?php _e( "Defender checks for any modifications or additions to WordPress core files.", wp_defender()->domain ) ?>
24
  </span>
25
  <div class="clear mline"></div>
26
- <span class="toggle">
27
  <input type="hidden" name="scan_vuln" value="0"/>
28
- <input type="checkbox" class="toggle-checkbox" name="scan_vuln" value="1"
29
  id="scan-vuln" <?php checked( true, $setting->scan_vuln ) ?>/>
30
- <label class="toggle-label" for="scan-vuln"></label>
31
  </span>
32
  <label for="scan-vuln"><?php _e( "Plugins & Themes", wp_defender()->domain ) ?></label>
33
  <span class="sub inpos">
34
  <?php _e( "Defender looks for publicly reported vulnerabilities in your installed plugins and themes.", wp_defender()->domain ) ?>
35
  </span>
36
  <div class="clear mline"></div>
37
- <span class="toggle">
38
  <input type="hidden" name="scan_content" value="0"/>
39
- <input type="checkbox" class="toggle-checkbox" name="scan_content" value="1"
40
  id="scan-content" <?php checked( true, $setting->scan_content ) ?>/>
41
- <label class="toggle-label" for="scan-content"></label>
42
  </span>
43
  <label for="scan-content"><?php _e( "Suspicious Code", wp_defender()->domain ) ?></label>
44
  <span class="sub inpos">
@@ -96,7 +96,7 @@
96
  <div>
97
  <span class="list-label"><?php _e( "When an issue is found", wp_defender()->domain ) ?></span>
98
  <span class="list-detail tr">
99
- <a href="#issue-found" rel="dialog"><?php _e( "Edit", wp_defender()->domain ) ?></a></span>
100
  </div>
101
  </li>
102
  <li>
@@ -104,7 +104,7 @@
104
  <span class="list-label"><?php _e( "When no issues are found", wp_defender()->domain ) ?></span>
105
  <span class="list-detail tr">
106
  <a href="#all-ok"
107
- rel="dialog"><?php _e( "Edit", wp_defender()->domain ) ?></a></span>
108
  </div>
109
  </li>
110
  </ul>
@@ -119,18 +119,44 @@
119
  </div>
120
  </div>
121
  <dialog id="issue-found" title="<?php esc_attr_e( "Issues found", wp_defender()->domain ) ?>">
122
- <form method="post" class="scan-frm scan-settings">
123
- <textarea rows="12" name="email_has_issue"><?php echo $setting->email_has_issue ?></textarea>
124
- <input type="hidden" name="action" value="saveScanSettings"/>
125
- <?php wp_nonce_field( 'saveScanSettings' ) ?>
126
- <button class="button"><?php _e( "Save", wp_defender()->domain ) ?></button>
127
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  </dialog>
129
  <dialog id="all-ok" title="<?php esc_attr_e( 'All OK', wp_defender()->domain ) ?>">
130
- <form method="post" class="scan-frm scan-settings">
131
- <input type="hidden" name="action" value="saveScanSettings"/>
132
- <?php wp_nonce_field( 'saveScanSettings' ) ?>
133
- <textarea rows="12" name="email_all_ok"><?php echo $setting->email_all_ok ?></textarea>
134
- <button class="button"><?php _e( "Save", wp_defender()->domain ) ?></button>
135
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
136
  </dialog>
12
  </span>
13
  </div>
14
  <div class="column">
15
+ <span class="toggle" aria-hidden="true" role="presentation">
16
  <input type="hidden" name="scan_core" value="0"/>
17
+ <input role="presentation" type="checkbox" name="scan_core" class="toggle-checkbox" id="core-scan" value="1"
18
  <?php checked( true, $setting->scan_core ) ?>/>
19
+ <label aria-hidden="true" class="toggle-label" for="core-scan"></label>
20
  </span>
21
  <label for="core-scan"><?php _e( "WordPress Core", wp_defender()->domain ) ?></label>
22
  <span class="sub inpos">
23
  <?php _e( "Defender checks for any modifications or additions to WordPress core files.", wp_defender()->domain ) ?>
24
  </span>
25
  <div class="clear mline"></div>
26
+ <span class="toggle" aria-hidden="true" role="presentation">
27
  <input type="hidden" name="scan_vuln" value="0"/>
28
+ <input role="presentation" type="checkbox" class="toggle-checkbox" name="scan_vuln" value="1"
29
  id="scan-vuln" <?php checked( true, $setting->scan_vuln ) ?>/>
30
+ <label aria-hidden="true" class="toggle-label" for="scan-vuln"></label>
31
  </span>
32
  <label for="scan-vuln"><?php _e( "Plugins & Themes", wp_defender()->domain ) ?></label>
33
  <span class="sub inpos">
34
  <?php _e( "Defender looks for publicly reported vulnerabilities in your installed plugins and themes.", wp_defender()->domain ) ?>
35
  </span>
36
  <div class="clear mline"></div>
37
+ <span class="toggle" aria-hidden="true" role="presentation">
38
  <input type="hidden" name="scan_content" value="0"/>
39
+ <input role="presentation" type="checkbox" class="toggle-checkbox" name="scan_content" value="1"
40
  id="scan-content" <?php checked( true, $setting->scan_content ) ?>/>
41
+ <label aria-hidden="true" class="toggle-label" for="scan-content"></label>
42
  </span>
43
  <label for="scan-content"><?php _e( "Suspicious Code", wp_defender()->domain ) ?></label>
44
  <span class="sub inpos">
96
  <div>
97
  <span class="list-label"><?php _e( "When an issue is found", wp_defender()->domain ) ?></span>
98
  <span class="list-detail tr">
99
+ <a href="#issue-found" rel="dialog" role="button"><?php _e( "Edit", wp_defender()->domain ) ?></a></span>
100
  </div>
101
  </li>
102
  <li>
104
  <span class="list-label"><?php _e( "When no issues are found", wp_defender()->domain ) ?></span>
105
  <span class="list-detail tr">
106
  <a href="#all-ok"
107
+ rel="dialog" role="button"><?php _e( "Edit", wp_defender()->domain ) ?></a></span>
108
  </div>
109
  </li>
110
  </ul>
119
  </div>
120
  </div>
121
  <dialog id="issue-found" title="<?php esc_attr_e( "Issues found", wp_defender()->domain ) ?>">
122
+ <div class="wp-defender">
123
+ <form method="post" class="scan-frm scan-settings">
124
+ <textarea rows="12" name="email_has_issue"><?php echo $setting->email_has_issue ?></textarea>
125
+ <strong class="small">
126
+ <?php _e( "Available variables", wp_defender()->domain ) ?>
127
+ </strong>
128
+ <input type="hidden" name="action" value="saveScanSettings"/>
129
+ <div class="clearfix"></div>
130
+ <span class="def-tag tag-generic">{USER_NAME}</span>
131
+ <span class="def-tag tag-generic">{SITE_URL}</span>
132
+ <span class="def-tag tag-generic">{ISSUES_COUNT}</span>
133
+ <span class="def-tag tag-generic">{ISSUES_LIST}</span>
134
+ <?php wp_nonce_field( 'saveScanSettings' ) ?>
135
+ <div class="clearfix mline"></div>
136
+ <hr class="mline"/>
137
+ <button type="button"
138
+ class="button button-light close"><?php _e( "Cancel", wp_defender()->domain ) ?></button>
139
+ <button class="button float-r"><?php _e( "Save Template", wp_defender()->domain ) ?></button>
140
+ </form>
141
+ </div>
142
  </dialog>
143
  <dialog id="all-ok" title="<?php esc_attr_e( 'All OK', wp_defender()->domain ) ?>">
144
+ <div class="wp-defender">
145
+ <form method="post" class="scan-frm scan-settings">
146
+ <input type="hidden" name="action" value="saveScanSettings"/>
147
+ <?php wp_nonce_field( 'saveScanSettings' ) ?>
148
+ <textarea rows="12" name="email_all_ok"><?php echo $setting->email_all_ok ?></textarea>
149
+ <strong class="small">
150
+ <?php _e( "Available variables", wp_defender()->domain ) ?>
151
+ </strong>
152
+ <div class="clearfix"></div>
153
+ <span class="def-tag tag-generic">{USER_NAME}</span>
154
+ <span class="def-tag tag-generic">{SITE_URL}</span>
155
+ <div class="clearfix mline"></div>
156
+ <hr class="mline"/>
157
+ <button type="button"
158
+ class="button button-light close"><?php _e( "Cancel", wp_defender()->domain ) ?></button>
159
+ <button class="button float-r"><?php _e( "Save Template", wp_defender()->domain ) ?></button>
160
+ </form>
161
+ </div>
162
  </dialog>
app/view/dashboard.php CHANGED
@@ -11,27 +11,32 @@
11
  $countAll = $hCount + $sCount;
12
  echo $countAll;
13
  ?></h5>
14
- <?php if ( $countAll == 0 ): ?>
15
- <span class="" tooltip="<?php esc_attr_e( 'You have no outstanding security issues', wp_defender()->domain ); ?>">
16
- <i class="def-icon icon-tick"></i>
17
- <?php else: ?>
18
- <?php
19
- if ( $sCount > 0 && $hCount > 0 ) :
20
- ?>
21
- <span class="" tooltip="<?php esc_attr_e( sprintf( __('You have %d security tweak(s) and %d suspicious file(s) needing attention', wp_defender()->domain ), $hCount, $sCount ) ); ?>">
 
 
22
  <?php elseif ( $hCount > 0 ): ?>
23
- <span class="" tooltip="<?php esc_attr_e( sprintf( __('You have %d security tweak(s) needing attention', wp_defender()->domain ), $hCount ) ); ?>">
 
24
  <?php elseif ( $sCount > 0 ): ?>
25
- <span class="" tooltip="<?php esc_attr_e( sprintf( __('You have %d suspicious file(s) needing attention', wp_defender()->domain ), $sCount ) ); ?>">
 
26
  <?php else: ?>
27
- <span class="" tooltip="<?php esc_attr_e( 'You have no outstanding security issues', wp_defender()->domain ); ?>">
 
28
  <?php endif; ?>
29
- <i class="def-icon icon-warning icon-yellow <?php echo $sCount > 0 ? 'fill-red' : null ?>"></i>
30
- <?php endif; ?>
31
  </span>
32
  <div class="clear"></div>
33
  <span class="sub"><?php
34
- _e( "security issues", wp_defender()->domain ) ?></span>
35
  </div>
36
  </div>
37
  <div class="column is-5">
@@ -72,6 +77,7 @@
72
  <?php echo $controller->renderHardenerWidget() ?>
73
  <?php $controller->renderBlacklistWidget() ?>
74
  <?php $controller->renderAuditWidget() ?>
 
75
  <?php if ( wp_defender()->isFree ): ?>
76
  <div class="dev-box dev-team">
77
  <div class="box-title">
11
  $countAll = $hCount + $sCount;
12
  echo $countAll;
13
  ?></h5>
14
+ <?php if ( $countAll == 0 ): ?>
15
+ <span class=""
16
+ tooltip="<?php esc_attr_e( 'You have no outstanding security issues.', wp_defender()->domain ); ?>">
17
+ <i class="def-icon icon-tick" aria-hidden="true"></i>
18
+ <?php else: ?>
19
+ <?php
20
+ if ( $sCount > 0 && $hCount > 0 ) :
21
+ ?>
22
+ <span class=""
23
+ tooltip="<?php esc_attr_e( sprintf( __( 'You have %d security tweak(s) and %d suspicious file(s) needing attention.', wp_defender()->domain ), $hCount, $sCount ) ); ?>">
24
  <?php elseif ( $hCount > 0 ): ?>
25
+ <span class=""
26
+ tooltip="<?php esc_attr_e( sprintf( __( 'You have %d security tweak(s) needing attention.', wp_defender()->domain ), $hCount ) ); ?>">
27
  <?php elseif ( $sCount > 0 ): ?>
28
+ <span class=""
29
+ tooltip="<?php esc_attr_e( sprintf( __( 'You have %d suspicious file(s) needing attention.', wp_defender()->domain ), $sCount ) ); ?>">
30
  <?php else: ?>
31
+ <span class=""
32
+ tooltip="<?php esc_attr_e( 'You have no outstanding security issues.', wp_defender()->domain ); ?>">
33
  <?php endif; ?>
34
+ <i class="def-icon icon-warning icon-yellow <?php echo $sCount > 0 ? 'fill-red' : null ?>" aria-hidden="true"></i>
35
+ <?php endif; ?>
36
  </span>
37
  <div class="clear"></div>
38
  <span class="sub"><?php
39
+ _e( "security issues", wp_defender()->domain ) ?></span>
40
  </div>
41
  </div>
42
  <div class="column is-5">
77
  <?php echo $controller->renderHardenerWidget() ?>
78
  <?php $controller->renderBlacklistWidget() ?>
79
  <?php $controller->renderAuditWidget() ?>
80
+ <?php $controller->renderATWidget() ?>
81
  <?php if ( wp_defender()->isFree ): ?>
82
  <div class="dev-box dev-team">
83
  <div class="box-title">
assets/css/styles.css CHANGED
@@ -1749,6 +1749,13 @@
1749
  .wp-defender .table tbody tr:last-child th, .wp-defender .table tbody tr:last-child td {
1750
  border-bottom: none;
1751
  padding-bottom: 0; }
 
 
 
 
 
 
 
1752
  .wp-defender .def-dashboard .hardener-widget .dev-list {
1753
  margin: 0 0 30px; }
1754
  .wp-defender .def-dashboard .hardener-widget .dev-list a {
@@ -2249,11 +2256,7 @@
2249
  .wp-defender .iplockout .bulk-nav .bulk-action p {
2250
  line-height: 42px; }
2251
  .wp-defender .iplockout .well.schedule-box strong {
2252
- font-weight: bold;
2253
- color: #333;
2254
- font-family: "Roboto Condensed", sans-serif;
2255
- font-size: 13px;
2256
- text-transform: uppercase; }
2257
  .wp-defender .iplockout .well.schedule-box .columns {
2258
  border-bottom: 0;
2259
  margin-bottom: 0;
@@ -2297,6 +2300,19 @@
2297
  -webkit-mask: none; }
2298
  .wp-defender .advanced-tools .toggle .toggle-label:after {
2299
  left: 0; }
 
 
 
 
 
 
 
 
 
 
 
 
 
2300
  .wp-defender .toggle-row {
2301
  display: none; }
2302
  @media screen and (min-width: 769px) and (max-width: 979px) {
1749
  .wp-defender .table tbody tr:last-child th, .wp-defender .table tbody tr:last-child td {
1750
  border-bottom: none;
1751
  padding-bottom: 0; }
1752
+ .wp-defender strong.small {
1753
+ color: #888;
1754
+ font-size: 12px;
1755
+ font-weight: bold;
1756
+ line-height: 22px; }
1757
+ .wp-defender .wd-select-inline {
1758
+ display: inline-block; }
1759
  .wp-defender .def-dashboard .hardener-widget .dev-list {
1760
  margin: 0 0 30px; }
1761
  .wp-defender .def-dashboard .hardener-widget .dev-list a {
2256
  .wp-defender .iplockout .bulk-nav .bulk-action p {
2257
  line-height: 42px; }
2258
  .wp-defender .iplockout .well.schedule-box strong {
2259
+ color: #888; }
 
 
 
 
2260
  .wp-defender .iplockout .well.schedule-box .columns {
2261
  border-bottom: 0;
2262
  margin-bottom: 0;
2300
  -webkit-mask: none; }
2301
  .wp-defender .advanced-tools .toggle .toggle-label:after {
2302
  left: 0; }
2303
+ .wp-defender .advanced-tools .at-line {
2304
+ margin-top: 15px; }
2305
+ .wp-defender .advanced-tools .at-line strong {
2306
+ color: #333333;
2307
+ font-size: 13px;
2308
+ font-weight: 500;
2309
+ line-height: 30px; }
2310
+ .wp-defender .advanced-tools .at-line span {
2311
+ display: block;
2312
+ color: #888888;
2313
+ font-size: 13px;
2314
+ line-height: 22px;
2315
+ margin-bottom: 10px; }
2316
  .wp-defender .toggle-row {
2317
  display: none; }
2318
  @media screen and (min-width: 769px) and (max-width: 979px) {
changelog.txt CHANGED
@@ -1,9 +1,18 @@
1
  Plugin Name: WP Defender
2
  Author: Hoang Ngo, Aaron Edwards
3
- Tested up to: 4.8.1
4
 
5
  Change Log:
6
 
 
 
 
 
 
 
 
 
 
7
  1.7 - 2017-15-08
8
  ----------------------------------------------------------------------
9
  - New: Now you can enable 2 factors authentication with Defender and Google Authenticator app, support for iOS and Android
1
  Plugin Name: WP Defender
2
  Author: Hoang Ngo, Aaron Edwards
3
+ Tested up to: 4.7.4
4
 
5
  Change Log:
6
 
7
+ 1.7.1 - 2017-25-09
8
+ ----------------------------------------------------------------------
9
+ - Improvement: Audit logging logs will be stored up to 1 year, query range can be set up to 3 months
10
+ - Improvement: Option to set a cooldown period for lockout notifications.
11
+ - Added: widget for 2 factors authentication
12
+ - Fix: Defender does not detect the right IP when CloudFlare is being used
13
+ - Fix: Conflict with TM Photo Gallery Plugin
14
+ - Other minor enhancements/fixes
15
+
16
  1.7 - 2017-15-08
17
  ----------------------------------------------------------------------
18
  - New: Now you can enable 2 factors authentication with Defender and Google Authenticator app, support for iOS and Android
languages/wpdef-default.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the GNU General Public License (Version 2 - GPLv2).
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: WP Defender Pro 1.7\n"
6
  "Report-Msgid-Bugs-To: https://wpmudev.org\n"
7
- "POT-Creation-Date: 2017-08-17 04:38:03+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -25,7 +25,7 @@ msgstr ""
25
  #: app/module/scan/view/layouts/layout.php:61
26
  #: app/module/scan/view/layouts/layout.php:77
27
  #: app/module/scan/view/setting-free.php:29
28
- #: app/module/scan/view/setting-free.php:45
29
  msgid "Try Defender Pro free today"
30
  msgstr ""
31
 
@@ -152,17 +152,17 @@ msgid "Lockout reports are active scheduled to send %s"
152
  msgstr ""
153
 
154
  #: app/behavior/report-free.php:129 app/behavior/report.php:224
155
- #: app/behavior/utils.php:663 free/utils.php:516
156
  msgid "daily"
157
  msgstr ""
158
 
159
  #: app/behavior/report-free.php:132 app/behavior/report.php:227
160
- #: app/behavior/utils.php:666 free/utils.php:519
161
  msgid "weekly"
162
  msgstr ""
163
 
164
  #: app/behavior/report-free.php:135 app/behavior/report.php:230
165
- #: app/behavior/utils.php:669 free/utils.php:522
166
  msgid "monthly"
167
  msgstr ""
168
 
@@ -204,39 +204,39 @@ msgstr ""
204
  msgid "To activate this report you must first enable the Audit Logging module."
205
  msgstr ""
206
 
207
- #: app/behavior/utils.php:76 free/utils.php:77
208
  msgid ""
209
  "WPMU DEV Dashboard will be required for this action. Please visit <a "
210
  "href=\"%s\">here</a> and install the WPMU DEV Dashboard"
211
  msgstr ""
212
 
213
- #: app/behavior/utils.php:173 app/behavior/utils.php:182
214
  #: app/module/audit/view/table.php:86 app/module/audit/view/table.php:144
215
- #: free/utils.php:174 free/utils.php:183
216
  msgid "Guest"
217
  msgstr ""
218
 
219
- #: app/behavior/utils.php:550
220
  msgid "WordPress Core Integrity"
221
  msgstr ""
222
 
223
- #: app/behavior/utils.php:551
224
  msgid "Plugins & Themes vulnerability"
225
  msgstr ""
226
 
227
- #: app/behavior/utils.php:552 app/module/scan/behavior/scan.php:145
228
  #: app/module/scan/view/layouts/layout.php:70
229
- #: app/module/scan/view/setting-free.php:52 app/module/scan/view/setting.php:43
230
  #: app/view/settings.php:98
231
  msgid "Suspicious Code"
232
  msgstr ""
233
 
234
- #: app/behavior/utils.php:557 app/module/audit/controller/main.php:143
235
  #: app/module/ip-lockout/controller/main.php:92
236
  msgid "Never"
237
  msgstr ""
238
 
239
- #: app/behavior/utils.php:646 free/utils.php:499
240
  msgid "Please upgrade to 5.3 or later"
241
  msgstr ""
242
 
@@ -309,6 +309,46 @@ msgstr ""
309
  msgid "Defender%s"
310
  msgstr ""
311
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
  #: app/module/advanced-tools/controller/main.php:58
313
  msgid ""
314
  "You enabled Jetpack WordPress.com login, so Defender will disable the 2 "
@@ -349,27 +389,13 @@ msgstr ""
349
  msgid "Whoops, the passcode you entered was incorrect or expired."
350
  msgstr ""
351
 
352
- #: app/module/advanced-tools/controller/main.php:392
353
- #: app/module/advanced-tools/view/layouts/layout.php:5
354
- msgid "Advanced Tools"
355
- msgstr ""
356
-
357
  #: app/module/advanced-tools/controller/main.php:455
358
  #: app/module/audit/controller/main.php:196
359
- #: app/module/ip-lockout/controller/main.php:652
360
  #: app/module/scan/controller/main.php:305
361
  msgid "Your settings have been updated."
362
  msgstr ""
363
 
364
- #: app/module/advanced-tools/view/disabled.php:4
365
- #: app/module/advanced-tools/view/layouts/layout.php:13
366
- #: app/module/advanced-tools/view/layouts/layout.php:20
367
- #: app/module/advanced-tools/view/login/disabled.php:6
368
- #: app/module/advanced-tools/view/login/enabled.php:6
369
- #: app/module/advanced-tools/view/main.php:4
370
- msgid "2 Factor Authentication"
371
- msgstr ""
372
-
373
  #: app/module/advanced-tools/view/disabled.php:10
374
  msgid ""
375
  "Beef up your website’s security with 2-Step verification. Protect your user "
@@ -378,12 +404,6 @@ msgid ""
378
  "attacks."
379
  msgstr ""
380
 
381
- #: app/module/advanced-tools/view/disabled.php:19
382
- #: app/module/audit/behavior/audit.php:43 app/module/audit/view/new.php:15
383
- #: app/module/ip-lockout/behavior/widget.php:37
384
- msgid "Activate"
385
- msgstr ""
386
-
387
  #: app/module/advanced-tools/view/login/disabled.php:2
388
  #: app/module/advanced-tools/view/login/enabled.php:2
389
  msgid "Security"
@@ -402,6 +422,7 @@ msgstr ""
402
 
403
  #: app/module/advanced-tools/view/login/disabled.php:20
404
  #: app/module/audit/view/report.php:68 app/module/scan/controller/main.php:530
 
405
  msgid "Cancel"
406
  msgstr ""
407
 
@@ -439,10 +460,6 @@ msgstr ""
439
  msgid "Verify"
440
  msgstr ""
441
 
442
- #: app/module/advanced-tools/view/login/enabled.php:9
443
- msgid "2 factor authentication is active."
444
- msgstr ""
445
-
446
  #: app/module/advanced-tools/view/login/enabled.php:12
447
  msgid "Disabled"
448
  msgstr ""
@@ -466,7 +483,7 @@ msgid "Powered by WordPress"
466
  msgstr ""
467
 
468
  #: app/module/advanced-tools/view/login/otp.php:224
469
- msgid "Enter 6 digit passcode"
470
  msgstr ""
471
 
472
  #: app/module/advanced-tools/view/login/otp.php:227
@@ -1102,16 +1119,16 @@ msgid "Banned Email Domains"
1102
  msgstr ""
1103
 
1104
  #: app/module/audit/component/options-audit.php:215
1105
- #: app/module/audit/view/layouts/layout.php:70
1106
- #: app/module/audit/view/layouts/layout.php:82
1107
  #: app/module/audit/view/settings.php:3
1108
  #: app/module/ip-lockout/view/layouts/layout.php:74
1109
  #: app/module/ip-lockout/view/layouts/layout.php:94
1110
  #: app/module/ip-lockout/view/settings.php:3
1111
- #: app/module/scan/view/layouts/layout.php:131
1112
- #: app/module/scan/view/layouts/layout.php:146
1113
  #: app/module/scan/view/setting-free.php:3 app/module/scan/view/setting.php:3
1114
- #: app/view/settings.php:6 free/main-activator.php:146 main-activator.php:89
1115
  msgid "Settings"
1116
  msgstr ""
1117
 
@@ -1187,36 +1204,36 @@ msgstr ""
1187
  msgid "%s changed user %s's role from %s to %s"
1188
  msgstr ""
1189
 
1190
- #: app/module/audit/component/users-audit.php:170
1191
  msgid "User %s updated his/her profile"
1192
  msgstr ""
1193
 
1194
- #: app/module/audit/component/users-audit.php:172
1195
  msgid "%s updated user %s's profile information"
1196
  msgstr ""
1197
 
1198
- #: app/module/audit/component/users-audit.php:178
1199
  msgid "lost password"
1200
  msgstr ""
1201
 
1202
- #: app/module/audit/component/users-audit.php:179
1203
  msgid "registered"
1204
  msgstr ""
1205
 
1206
- #: app/module/audit/component/users-audit.php:180
1207
  msgid "login"
1208
  msgstr ""
1209
 
1210
- #: app/module/audit/component/users-audit.php:181
1211
  msgid "logout"
1212
  msgstr ""
1213
 
1214
- #: app/module/audit/component/users-audit.php:182
1215
  msgid "password reset"
1216
  msgstr ""
1217
 
1218
  #: app/module/audit/controller/main-free.php:36
1219
- #: app/module/audit/controller/main.php:489
1220
  #: app/module/audit/view/pro-feature.php:22
1221
  #: app/module/ip-lockout/view/pro-feature.php:22
1222
  #: app/module/scan/view/pro-feature.php:22 app/view/activator.php:33
@@ -1253,42 +1270,52 @@ msgstr ""
1253
  msgid "User"
1254
  msgstr ""
1255
 
1256
- #: app/module/audit/controller/main.php:331
 
 
 
 
 
 
 
 
 
 
1257
  msgid "Hi {USER_NAME},"
1258
  msgstr ""
1259
 
1260
- #: app/module/audit/controller/main.php:333
1261
  msgid ""
1262
  "It’s WP Defender here, reporting from the frontline with a quick update on "
1263
  "what’s been happening at <a href=\"%s\">%s</a>."
1264
  msgstr ""
1265
 
1266
- #: app/module/audit/controller/main.php:345
1267
  msgid "Event Type"
1268
  msgstr ""
1269
 
1270
- #: app/module/audit/controller/main.php:349
1271
  msgid "Action Summaries"
1272
  msgstr ""
1273
 
1274
- #: app/module/audit/controller/main.php:390
1275
  msgid "You can view the full audit report for your site here."
1276
  msgstr ""
1277
 
1278
- #: app/module/audit/controller/main.php:423
1279
  msgid "There were no events logged for %s"
1280
  msgstr ""
1281
 
1282
- #: app/module/audit/controller/main.php:428
1283
- #: app/module/audit/controller/main.php:453
1284
  msgid "Here’s what’s been happening at %s"
1285
  msgstr ""
1286
 
1287
- #: app/module/audit/controller/main.php:545 app/view/settings.php:209
1288
  msgid "Type a user’s name"
1289
  msgstr ""
1290
 
1291
- #: app/module/audit/controller/main.php:546
1292
  msgid "We did not find an user with this name..."
1293
  msgstr ""
1294
 
@@ -1359,7 +1386,7 @@ msgstr ""
1359
  msgid "<a href=\"%s\">Configure reporting preferences</a>"
1360
  msgstr ""
1361
 
1362
- #: app/module/audit/view/free.php:9 free/main-activator.php:106
1363
  msgid "Upgrade"
1364
  msgstr ""
1365
 
@@ -1376,21 +1403,13 @@ msgid "Events logged in the past 7 days"
1376
  msgstr ""
1377
 
1378
  #: app/module/audit/view/layouts/layout.php:28
1379
- #: app/module/audit/view/layouts/layout.php:74
1380
- #: app/module/audit/view/layouts/layout.php:84
1381
  msgid "Reports"
1382
  msgstr ""
1383
 
1384
- #: app/module/audit/view/layouts/layout.php:38
1385
- msgid "at %s"
1386
- msgstr ""
1387
-
1388
- #: app/module/audit/view/layouts/layout.php:41
1389
- msgid "%s at %s"
1390
- msgstr ""
1391
-
1392
- #: app/module/audit/view/layouts/layout.php:66
1393
- #: app/module/audit/view/layouts/layout.php:80
1394
  msgid "Event Logs"
1395
  msgstr ""
1396
 
@@ -1511,7 +1530,7 @@ msgid "NOTIFICATIONS"
1511
  msgstr ""
1512
 
1513
  #: app/module/audit/view/report.php:9
1514
- msgid "Schedule Scans"
1515
  msgstr ""
1516
 
1517
  #: app/module/audit/view/report.php:11
@@ -1567,7 +1586,7 @@ msgid ""
1567
  msgstr ""
1568
 
1569
  #: app/module/audit/view/report.php:67 app/module/scan/view/automation.php:67
1570
- #: app/module/scan/view/setting-free.php:133
1571
  #: app/module/scan/view/setting.php:116
1572
  msgid "Update Settings"
1573
  msgstr ""
@@ -1584,7 +1603,7 @@ msgstr ""
1584
  #: app/module/ip-lockout/view/blacklist/enabled.php:114
1585
  #: app/module/ip-lockout/view/detect-404/enabled.php:148
1586
  #: app/module/ip-lockout/view/login-lockouts/enabled.php:124
1587
- #: app/module/ip-lockout/view/notification/enabled.php:65
1588
  #: app/module/ip-lockout/view/notification/report.php:81
1589
  #: app/module/ip-lockout/view/settings.php:44
1590
  msgid "UPDATE SETTINGS"
@@ -1695,7 +1714,7 @@ msgstr ""
1695
  #: app/module/hardener/component/db-prefix-service.php:95
1696
  #: app/module/hardener/component/disable-file-editor-service.php:32
1697
  #: app/module/hardener/component/disable-file-editor-service.php:66
1698
- #: app/module/hardener/component/hide-error-service.php:60
1699
  #: app/module/hardener/component/protect-information-service.php:44
1700
  #: app/module/hardener/component/protect-information-service.php:77
1701
  #: app/module/hardener/component/security-key-service.php:48
@@ -1744,8 +1763,8 @@ msgid "Change default database prefix"
1744
  msgstr ""
1745
 
1746
  #: app/module/hardener/component/disable-file-editor-service.php:40
1747
- #: app/module/hardener/component/hide-error-service.php:69
1748
- #: app/module/hardener/component/hide-error-service.php:77
1749
  #: app/module/hardener/component/security-key-service.php:117
1750
  msgid ""
1751
  "Defender can't recognize your wp-config.php, please revert it to original "
@@ -1770,7 +1789,7 @@ msgstr ""
1770
  msgid "Disable trackbacks and pingbacks"
1771
  msgstr ""
1772
 
1773
- #: app/module/hardener/component/hide-error-service.php:102
1774
  msgid "WP_DEBUG get override somewhere, please check with your host provider"
1775
  msgstr ""
1776
 
@@ -1784,10 +1803,10 @@ msgid "Manage Login Duration"
1784
  msgstr ""
1785
 
1786
  #: app/module/hardener/component/login-duration.php:94
1787
- msgid "Duration can only be a number"
1788
  msgstr ""
1789
 
1790
- #: app/module/hardener/component/login-duration.php:190
1791
  msgid ""
1792
  "Your session has expired because it has been over %d days since your last "
1793
  "login. Please log back in to continue."
@@ -1889,10 +1908,10 @@ msgid ""
1889
  msgstr ""
1890
 
1891
  #: app/module/hardener/view/issues.php:3
1892
- #: app/module/hardener/view/layouts/layout.php:60
1893
- #: app/module/hardener/view/layouts/layout.php:95
1894
- #: app/module/scan/view/issues.php:4 app/module/scan/view/layouts/layout.php:95
1895
- #: app/module/scan/view/layouts/layout.php:142
1896
  msgid "Issues"
1897
  msgstr ""
1898
 
@@ -1903,12 +1922,12 @@ msgid ""
1903
  "recommend you action as many tweaks as possible."
1904
  msgstr ""
1905
 
1906
- #: app/module/hardener/view/layouts/layout.php:20 app/view/dashboard.php:15
1907
- #: app/view/dashboard.php:27
1908
- msgid "You have no outstanding security issues"
1909
  msgstr ""
1910
 
1911
- #: app/module/hardener/view/layouts/layout.php:28 app/view/dashboard.php:41
1912
  msgid "Security tweaks actioned"
1913
  msgstr ""
1914
 
@@ -1920,20 +1939,20 @@ msgstr ""
1920
  msgid "WordPress Version"
1921
  msgstr ""
1922
 
1923
- #: app/module/hardener/view/layouts/layout.php:64
1924
- msgid "You have %d security tweak(s) needing attention"
1925
  msgstr ""
1926
 
1927
- #: app/module/hardener/view/layouts/layout.php:73
1928
- #: app/module/hardener/view/layouts/layout.php:97
1929
  msgid "Resolved"
1930
  msgstr ""
1931
 
1932
- #: app/module/hardener/view/layouts/layout.php:80
1933
- #: app/module/hardener/view/layouts/layout.php:99
1934
  #: app/module/scan/view/cleaned.php:3 app/module/scan/view/ignored.php:3
1935
- #: app/module/scan/view/layouts/layout.php:120
1936
- #: app/module/scan/view/layouts/layout.php:144
1937
  msgid "Ignored"
1938
  msgstr ""
1939
 
@@ -2108,9 +2127,9 @@ msgstr ""
2108
 
2109
  #: app/module/hardener/view/rules/hide-error.php:40
2110
  msgid ""
2111
- "We attempted to disable the WP_DEBUG setting to prevent code errors "
2112
  "displaying but it’s being overridden by your server config. Please contact "
2113
- "your hosting provider and ask them to set WP_DEBUG to false."
2114
  msgstr ""
2115
 
2116
  #: app/module/hardener/view/rules/login-duration.php:13
@@ -2179,14 +2198,14 @@ msgid "Update .htaccess file"
2179
  msgstr ""
2180
 
2181
  #: app/module/hardener/view/rules/prevent-php-executed.php:77
2182
- #: app/module/hardener/view/rules/protect-information.php:42
2183
  msgid "Server Type:"
2184
  msgstr ""
2185
 
2186
  #: app/module/hardener/view/rules/prevent-php-executed.php:91
2187
  #: app/module/hardener/view/rules/prevent-php-executed.php:105
2188
- #: app/module/hardener/view/rules/protect-information.php:54
2189
- #: app/module/hardener/view/rules/protect-information.php:66
2190
  msgid ""
2191
  "We will place <strong>.htaccess</strong> file into the root folder to lock "
2192
  "down the files and folders inside."
@@ -2194,44 +2213,44 @@ msgstr ""
2194
 
2195
  #: app/module/hardener/view/rules/prevent-php-executed.php:100
2196
  #: app/module/hardener/view/rules/prevent-php-executed.php:114
2197
- #: app/module/hardener/view/rules/protect-information.php:61
2198
- #: app/module/hardener/view/rules/protect-information.php:73
2199
  msgid "Add .htaccess file"
2200
  msgstr ""
2201
 
2202
  #: app/module/hardener/view/rules/prevent-php-executed.php:138
2203
- #: app/module/hardener/view/rules/protect-information.php:105
2204
  msgid "For NGINX servers:"
2205
  msgstr ""
2206
 
2207
  #: app/module/hardener/view/rules/prevent-php-executed.php:141
2208
- #: app/module/hardener/view/rules/protect-information.php:108
2209
  msgid ""
2210
  "Copy the generated code into your site specific .conf file usually located "
2211
  "in a subdirectory under /etc/nginx/... or /usr/local/nginx/conf/..."
2212
  msgstr ""
2213
 
2214
  #: app/module/hardener/view/rules/prevent-php-executed.php:144
2215
- #: app/module/hardener/view/rules/protect-information.php:111
2216
  msgid ""
2217
  "Add the code above inside the <strong>server</strong> section in the file, "
2218
  "right before the php location block. Looks something like:"
2219
  msgstr ""
2220
 
2221
  #: app/module/hardener/view/rules/prevent-php-executed.php:148
2222
- #: app/module/hardener/view/rules/protect-information.php:115
2223
  msgid "Reload NGINX."
2224
  msgstr ""
2225
 
2226
  #: app/module/hardener/view/rules/prevent-php-executed.php:151
2227
- #: app/module/hardener/view/rules/protect-information.php:118
2228
  msgid ""
2229
  "Still having trouble? <a target='_blank' href=\"%s\">Open a support "
2230
  "ticket</a>."
2231
  msgstr ""
2232
 
2233
  #: app/module/hardener/view/rules/prevent-php-executed.php:161
2234
- #: app/module/hardener/view/rules/protect-information.php:124
2235
  msgid "For IIS servers, <a href=\"%s\">visit Microsoft TechNet</a>"
2236
  msgstr ""
2237
 
@@ -2275,7 +2294,7 @@ msgstr ""
2275
  msgid "Your WordPress is protected."
2276
  msgstr ""
2277
 
2278
- #: app/module/hardener/view/rules/protect-information.php:129
2279
  msgid "For IIS 7 servers, <a href=\"%s\">visit Microsoft TechNet</a>"
2280
  msgstr ""
2281
 
@@ -2385,41 +2404,45 @@ msgstr ""
2385
  msgid "Lockout notifications are disabled"
2386
  msgstr ""
2387
 
2388
- #: app/module/ip-lockout/component/login-protection-api.php:62
2389
- #: app/module/ip-lockout/controller/main.php:547
2390
- #: app/module/ip-lockout/controller/main.php:556
2391
  msgid ""
2392
  "You have been locked out by the administrator for attempting to login with "
2393
  "a banned username"
2394
  msgstr ""
2395
 
2396
- #: app/module/ip-lockout/component/login-protection-api.php:75
2397
  msgid "Lockout occurred: Attempting to login with a banned username."
2398
  msgstr ""
2399
 
2400
- #: app/module/ip-lockout/component/login-protection-api.php:77
 
 
 
 
2401
  msgid "Lockout occurred: Too many failed login attempts"
2402
  msgstr ""
2403
 
2404
- #: app/module/ip-lockout/component/login-protection-api.php:144
2405
  msgid "Lockout occurred: Too many 404 requests for %s"
2406
  msgstr ""
2407
 
2408
- #: app/module/ip-lockout/component/login-protection-api.php:244
2409
  msgid "Ban"
2410
  msgstr ""
2411
 
2412
- #: app/module/ip-lockout/component/login-protection-api.php:246
2413
  msgid "Unban"
2414
  msgstr ""
2415
 
2416
- #: app/module/ip-lockout/component/login-protection-api.php:251
2417
  #: app/module/ip-lockout/view/blacklist/enabled.php:53
2418
  #: app/module/ip-lockout/view/detect-404/enabled.php:93
2419
  msgid "Whitelist"
2420
  msgstr ""
2421
 
2422
- #: app/module/ip-lockout/component/login-protection-api.php:253
2423
  msgid "Unwhitelist"
2424
  msgstr ""
2425
 
@@ -2458,27 +2481,27 @@ msgstr ""
2458
 
2459
  #: app/module/ip-lockout/component/logs-table.php:164
2460
  #: app/module/ip-lockout/model/log-model-legacy.php:111
2461
- #: app/module/ip-lockout/model/log-model.php:64
2462
  msgid "Failed login attempts"
2463
  msgstr ""
2464
 
2465
  #: app/module/ip-lockout/component/logs-table.php:166
2466
  #: app/module/ip-lockout/model/log-model-legacy.php:112
2467
- #: app/module/ip-lockout/model/log-model.php:65
2468
  msgid "Login lockout"
2469
  msgstr ""
2470
 
2471
  #: app/module/ip-lockout/component/logs-table.php:168
2472
  #: app/module/ip-lockout/model/log-model-legacy.php:113
2473
  #: app/module/ip-lockout/model/log-model-legacy.php:114
2474
- #: app/module/ip-lockout/model/log-model.php:66
2475
  #: app/module/ip-lockout/model/log-model.php:67
 
2476
  msgid "404 error"
2477
  msgstr ""
2478
 
2479
  #: app/module/ip-lockout/component/logs-table.php:170
2480
  #: app/module/ip-lockout/model/log-model-legacy.php:115
2481
- #: app/module/ip-lockout/model/log-model.php:68
2482
  msgid "404 lockout"
2483
  msgstr ""
2484
 
@@ -2500,6 +2523,10 @@ msgstr ""
2500
  msgid "%s results"
2501
  msgstr ""
2502
 
 
 
 
 
2503
  #: app/module/ip-lockout/controller/main.php:151
2504
  msgid "Your logs have been successfully deleted."
2505
  msgstr ""
@@ -2518,69 +2545,69 @@ msgstr ""
2518
  msgid "Demo"
2519
  msgstr ""
2520
 
2521
- #: app/module/ip-lockout/controller/main.php:399
2522
  msgid "404 lockout alert for %s"
2523
  msgstr ""
2524
 
2525
- #: app/module/ip-lockout/controller/main.php:422
2526
  msgid "Login lockout alert for %s"
2527
  msgstr ""
2528
 
2529
- #: app/module/ip-lockout/controller/main.php:487
2530
  msgid "Failed login attempt with username %s"
2531
  msgstr ""
2532
 
2533
- #: app/module/ip-lockout/controller/main.php:549
2534
- #: app/module/ip-lockout/controller/main.php:559
2535
  msgid "%d login attempts remaining"
2536
  msgstr ""
2537
 
2538
- #: app/module/ip-lockout/controller/main.php:648
2539
  msgid ""
2540
  "Your settings have been updated, however some IPs were removed because "
2541
  "invalid format, or you blacklist yourself"
2542
  msgstr ""
2543
 
2544
- #: app/module/ip-lockout/controller/main.php:659
2545
  msgid "Login Protection has been activated."
2546
  msgstr ""
2547
 
2548
- #: app/module/ip-lockout/controller/main.php:661
2549
  msgid "Login Protection has been deactivated."
2550
  msgstr ""
2551
 
2552
- #: app/module/ip-lockout/controller/main.php:666
2553
  msgid "404 Detection has been activated."
2554
  msgstr ""
2555
 
2556
- #: app/module/ip-lockout/controller/main.php:668
2557
  msgid "404 Detection has been deactivated."
2558
  msgstr ""
2559
 
2560
- #: app/module/ip-lockout/controller/main.php:697 app/module/ip-lockout.php:35
2561
  #: app/view/activator-free.php:33 app/view/activator.php:49
2562
  msgid "IP Lockouts"
2563
  msgstr ""
2564
 
2565
- #: app/module/ip-lockout/controller/main.php:714
2566
- #: app/module/ip-lockout/controller/main.php:720
2567
  msgid "Your file is invalid!"
2568
  msgstr ""
2569
 
2570
- #: app/module/ip-lockout/controller/main.php:726
2571
  msgid "Your file content is invalid!"
2572
  msgstr ""
2573
 
2574
- #: app/module/ip-lockout/controller/main.php:735
2575
  msgid "Your whitelist/blacklist has been successfully imported."
2576
  msgstr ""
2577
 
2578
- #: app/module/ip-lockout/controller/main.php:905
2579
- msgid "Thanks for your patience. All sets!"
2580
  msgstr ""
2581
 
2582
  #: app/module/ip-lockout/model/log-model-legacy.php:79
2583
- #: app/module/ip-lockout/model/log-model.php:38
2584
  msgid ""
2585
  "Request for file <span class='log-text-table' tooltip='%s'>%s</span> which "
2586
  "doesn't exist"
@@ -2947,8 +2974,8 @@ msgstr ""
2947
  #: app/module/ip-lockout/view/notification/report.php:3
2948
  #: app/module/scan/view/automation-free.php:3
2949
  #: app/module/scan/view/automation.php:3
2950
- #: app/module/scan/view/layouts/layout.php:136
2951
- #: app/module/scan/view/layouts/layout.php:148
2952
  msgid "Reporting"
2953
  msgstr ""
2954
 
@@ -3072,6 +3099,72 @@ msgid ""
3072
  "email."
3073
  msgstr ""
3074
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3075
  #: app/module/ip-lockout/view/notification/report-free.php:15
3076
  #: app/module/ip-lockout/view/notification/report.php:10
3077
  msgid "Lockouts report"
@@ -3175,9 +3268,9 @@ msgstr ""
3175
  #: app/module/scan/behavior/core-result.php:75
3176
  #: app/module/scan/behavior/core-result.php:405
3177
  #: app/module/scan/behavior/core-result.php:410
3178
- #: app/module/scan/behavior/pro/content-result.php:206
3179
- #: app/module/scan/behavior/pro/content-result.php:227
3180
- #: app/module/scan/behavior/pro/content-result.php:232
3181
  msgid "Defender doesn't have enough permission to remove this file"
3182
  msgstr ""
3183
 
@@ -3300,6 +3393,10 @@ msgstr ""
3300
  msgid "This will permanent delete this file, do you want to do this?"
3301
  msgstr ""
3302
 
 
 
 
 
3303
  #: app/module/scan/behavior/pro/vuln-result.php:33
3304
  msgid "WordPress Vulnerability"
3305
  msgstr ""
@@ -3361,6 +3458,7 @@ msgid ""
3361
  msgstr ""
3362
 
3363
  #: app/module/scan/behavior/scan.php:113
 
3364
  msgid "Your code is clean, the skies are clear."
3365
  msgstr ""
3366
 
@@ -3372,7 +3470,7 @@ msgstr ""
3372
 
3373
  #: app/module/scan/behavior/scan.php:130
3374
  #: app/module/scan/view/layouts/layout.php:54
3375
- #: app/module/scan/view/setting-free.php:36 app/module/scan/view/setting.php:32
3376
  msgid "Plugins & Themes"
3377
  msgstr ""
3378
 
@@ -3380,7 +3478,7 @@ msgstr ""
3380
  #: app/module/scan/view/layouts/layout.php:62
3381
  #: app/module/scan/view/layouts/layout.php:78
3382
  #: app/module/scan/view/setting-free.php:30
3383
- #: app/module/scan/view/setting-free.php:46
3384
  msgid "Pro Feature"
3385
  msgstr ""
3386
 
@@ -3463,19 +3561,19 @@ msgstr ""
3463
  msgid "A scan is already in progress"
3464
  msgstr ""
3465
 
3466
- #: app/module/scan/component/scan-api.php:190
3467
  msgid "No scan record exists"
3468
  msgstr ""
3469
 
3470
- #: app/module/scan/component/scan-api.php:230
3471
  msgid "Analyzing WordPress Core..."
3472
  msgstr ""
3473
 
3474
- #: app/module/scan/component/scan-api.php:233
3475
  msgid "Analyzing WordPress Content..."
3476
  msgstr ""
3477
 
3478
- #: app/module/scan/component/scan-api.php:236
3479
  msgid "Checking for any published vulnerabilities your plugins & themes..."
3480
  msgstr ""
3481
 
@@ -3642,19 +3740,15 @@ msgstr ""
3642
  msgid "New Scan"
3643
  msgstr ""
3644
 
3645
- #: app/module/scan/view/layouts/layout.php:28
3646
- msgid "Your code is clean, the skies are clear"
3647
- msgstr ""
3648
-
3649
  #: app/module/scan/view/layouts/layout.php:36
3650
- msgid "File scanning issues need attention"
3651
  msgstr ""
3652
 
3653
  #: app/module/scan/view/layouts/layout.php:39
3654
  msgid "Last scan"
3655
  msgstr ""
3656
 
3657
- #: app/module/scan/view/layouts/layout.php:100
3658
  msgid "You have %d suspicious file(s) needing attention"
3659
  msgstr ""
3660
 
@@ -3697,104 +3791,128 @@ msgstr ""
3697
  msgid "Defender checks for any modifications or additions to WordPress core files."
3698
  msgstr ""
3699
 
3700
- #: app/module/scan/view/setting-free.php:38 app/module/scan/view/setting.php:34
3701
  msgid ""
3702
  "Defender looks for publicly reported vulnerabilities in your installed "
3703
  "plugins and themes."
3704
  msgstr ""
3705
 
3706
- #: app/module/scan/view/setting-free.php:54 app/module/scan/view/setting.php:45
3707
  #: app/view/settings.php:117
3708
  msgid ""
3709
  "Defender looks inside all of your files for suspicious and potentially "
3710
  "harmful code."
3711
  msgstr ""
3712
 
3713
- #: app/module/scan/view/setting-free.php:61
3714
  msgid ""
3715
  "Defenders scans through every line of code on your website, searching for "
3716
  "anything suspicious. This feature is included when you join WPMU DEV, along "
3717
  "with 100+ plugins and themes, 24/7 support and lots of handy site "
3718
- "management tools. – <a href=\"%s\">Try it all FREE today!\n"
3719
  " </a>"
3720
  msgstr ""
3721
 
3722
- #: app/module/scan/view/setting-free.php:68 app/module/scan/view/setting.php:51
3723
  msgid "Maximum included file size"
3724
  msgstr ""
3725
 
3726
- #: app/module/scan/view/setting-free.php:70 app/module/scan/view/setting.php:53
3727
  msgid ""
3728
  "Defender will skip any files larger than this size. The smaller the number, "
3729
  "the faster Defender will scan your website."
3730
  msgstr ""
3731
 
3732
- #: app/module/scan/view/setting-free.php:75 app/module/scan/view/setting.php:58
3733
  msgid "MB"
3734
  msgstr ""
3735
 
3736
- #: app/module/scan/view/setting-free.php:80 app/module/scan/view/setting.php:63
3737
  msgid "Optional emails"
3738
  msgstr ""
3739
 
3740
- #: app/module/scan/view/setting-free.php:82 app/module/scan/view/setting.php:65
3741
  msgid ""
3742
  "By default, you'll only get email reports when your site runs into trouble. "
3743
  "Turn this option on to get reports even when your site is running smoothly."
3744
  msgstr ""
3745
 
3746
- #: app/module/scan/view/setting-free.php:92 app/module/scan/view/setting.php:75
3747
  msgid "Send all scan report emails"
3748
  msgstr ""
3749
 
3750
- #: app/module/scan/view/setting-free.php:97 app/module/scan/view/setting.php:80
3751
  msgid "Email subject"
3752
  msgstr ""
3753
 
3754
- #: app/module/scan/view/setting-free.php:105
3755
  #: app/module/scan/view/setting.php:88
3756
  msgid "Email templates"
3757
  msgstr ""
3758
 
3759
- #: app/module/scan/view/setting-free.php:107
3760
  #: app/module/scan/view/setting.php:90
3761
  msgid ""
3762
  "When Defender scans your website, a report will be generated with any "
3763
  "issues that have been found. You can choose to have reports emailed to you."
3764
  msgstr ""
3765
 
3766
- #: app/module/scan/view/setting-free.php:114
3767
  #: app/module/scan/view/setting.php:97
3768
  msgid "When an issue is found"
3769
  msgstr ""
3770
 
3771
- #: app/module/scan/view/setting-free.php:116
3772
- #: app/module/scan/view/setting-free.php:124
3773
  #: app/module/scan/view/setting.php:99 app/module/scan/view/setting.php:107
3774
  msgid "Edit"
3775
  msgstr ""
3776
 
3777
- #: app/module/scan/view/setting-free.php:121
3778
  #: app/module/scan/view/setting.php:104
3779
  msgid "When no issues are found"
3780
  msgstr ""
3781
 
3782
- #: app/module/scan/view/setting-free.php:138
3783
  #: app/module/scan/view/setting.php:121 app/view/settings.php:287
3784
  msgid "Issues found"
3785
  msgstr ""
3786
 
3787
- #: app/module/scan/view/setting-free.php:143
3788
- #: app/module/scan/view/setting-free.php:151
3789
- #: app/module/scan/view/setting.php:126 app/module/scan/view/setting.php:134
3790
  msgid "Save"
3791
  msgstr ""
3792
 
3793
- #: app/module/scan/view/setting-free.php:146
3794
- #: app/module/scan/view/setting.php:129 app/view/settings.php:304
3795
  msgid "All OK"
3796
  msgstr ""
3797
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3798
  #: app/view/activator-free.php:4
3799
  msgid ""
3800
  "Welcome to Defender! Let's quickly set up the most important security "
@@ -3851,36 +3969,36 @@ msgid ""
3851
  "something’s wrong, we’ll let you know via email."
3852
  msgstr ""
3853
 
3854
- #: app/view/dashboard.php:34
3855
  msgid "security issues"
3856
  msgstr ""
3857
 
3858
- #: app/view/dashboard.php:53
3859
  msgid "File Scan Issues"
3860
  msgstr ""
3861
 
3862
- #: app/view/dashboard.php:61
3863
  msgid "Last Lockout"
3864
  msgstr ""
3865
 
3866
- #: app/view/dashboard.php:78
3867
  msgid "TRY PRO FEATURES FOR FREE!"
3868
  msgstr ""
3869
 
3870
- #: app/view/dashboard.php:82
3871
  msgid ""
3872
  "Upgrade to Defender Pro to unlock Advanced File Scanning, Blacklist "
3873
  "Monitoring, Audit Logging and automated reporting for Audit Logging, IP "
3874
  "Lockouts and File Scans."
3875
  msgstr ""
3876
 
3877
- #: app/view/dashboard.php:85
3878
  msgid ""
3879
  "Get all this as part of a WPMU DEV Membership, and the best part is you can "
3880
  "try everything absolutely free."
3881
  msgstr ""
3882
 
3883
- #: app/view/dashboard.php:88
3884
  msgid "FIND OUT MORE"
3885
  msgstr ""
3886
 
@@ -4001,10 +4119,6 @@ msgid ""
4001
  "and change the copy below."
4002
  msgstr ""
4003
 
4004
- #: app/view/settings.php:229
4005
- msgid "Available variables"
4006
- msgstr ""
4007
-
4008
  #: app/view/settings.php:238
4009
  msgid ""
4010
  "We’ll grab the users first name, or display name is first name isn’t "
@@ -4039,18 +4153,26 @@ msgid ""
4039
  "this email."
4040
  msgstr ""
4041
 
4042
- #: free/main-activator.php:60
4043
  msgid "Get Members!"
4044
  msgstr ""
4045
 
4046
- #: free/main-activator.php:104
 
 
 
 
 
 
 
 
4047
  msgid ""
4048
  "%s, you now have access to Defender's pro features but you still have the "
4049
  "free version installed. Let's upgrade Defender and unlock all those juicy "
4050
  "features! &nbsp; %s"
4051
  msgstr ""
4052
 
4053
- #: free/main-activator.php:134
4054
  msgid "<br/>Something went wrong. Please try again later!"
4055
  msgstr ""
4056
 
@@ -4090,7 +4212,7 @@ msgstr ""
4090
  msgid "Rate %s"
4091
  msgstr ""
4092
 
4093
- #: main-activator.php:78
4094
  msgid ""
4095
  "We noticed you have both the free and pro versions of Defender installed, "
4096
  "so we've automatically deactivated the free version for you."
2
  # This file is distributed under the GNU General Public License (Version 2 - GPLv2).
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: WP Defender Pro 1.7.1\n"
6
  "Report-Msgid-Bugs-To: https://wpmudev.org\n"
7
+ "POT-Creation-Date: 2017-09-29 04:48:00+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
25
  #: app/module/scan/view/layouts/layout.php:61
26
  #: app/module/scan/view/layouts/layout.php:77
27
  #: app/module/scan/view/setting-free.php:29
28
+ #: app/module/scan/view/setting-free.php:44
29
  msgid "Try Defender Pro free today"
30
  msgstr ""
31
 
152
  msgstr ""
153
 
154
  #: app/behavior/report-free.php:129 app/behavior/report.php:224
155
+ #: app/behavior/utils.php:804 free/utils.php:656
156
  msgid "daily"
157
  msgstr ""
158
 
159
  #: app/behavior/report-free.php:132 app/behavior/report.php:227
160
+ #: app/behavior/utils.php:807 free/utils.php:659
161
  msgid "weekly"
162
  msgstr ""
163
 
164
  #: app/behavior/report-free.php:135 app/behavior/report.php:230
165
+ #: app/behavior/utils.php:810 free/utils.php:662
166
  msgid "monthly"
167
  msgstr ""
168
 
204
  msgid "To activate this report you must first enable the Audit Logging module."
205
  msgstr ""
206
 
207
+ #: app/behavior/utils.php:77 free/utils.php:78
208
  msgid ""
209
  "WPMU DEV Dashboard will be required for this action. Please visit <a "
210
  "href=\"%s\">here</a> and install the WPMU DEV Dashboard"
211
  msgstr ""
212
 
213
+ #: app/behavior/utils.php:178 app/behavior/utils.php:187
214
  #: app/module/audit/view/table.php:86 app/module/audit/view/table.php:144
215
+ #: free/utils.php:179 free/utils.php:188
216
  msgid "Guest"
217
  msgstr ""
218
 
219
+ #: app/behavior/utils.php:687
220
  msgid "WordPress Core Integrity"
221
  msgstr ""
222
 
223
+ #: app/behavior/utils.php:688
224
  msgid "Plugins & Themes vulnerability"
225
  msgstr ""
226
 
227
+ #: app/behavior/utils.php:689 app/module/scan/behavior/scan.php:145
228
  #: app/module/scan/view/layouts/layout.php:70
229
+ #: app/module/scan/view/setting-free.php:50 app/module/scan/view/setting.php:43
230
  #: app/view/settings.php:98
231
  msgid "Suspicious Code"
232
  msgstr ""
233
 
234
+ #: app/behavior/utils.php:694 app/module/audit/controller/main.php:143
235
  #: app/module/ip-lockout/controller/main.php:92
236
  msgid "Never"
237
  msgstr ""
238
 
239
+ #: app/behavior/utils.php:787 free/utils.php:639
240
  msgid "Please upgrade to 5.3 or later"
241
  msgstr ""
242
 
309
  msgid "Defender%s"
310
  msgstr ""
311
 
312
+ #: app/module/advanced-tools/behavior/at-widget.php:17
313
+ #: app/module/advanced-tools/controller/main.php:392
314
+ #: app/module/advanced-tools/view/layouts/layout.php:5
315
+ msgid "Advanced Tools"
316
+ msgstr ""
317
+
318
+ #: app/module/advanced-tools/behavior/at-widget.php:23
319
+ msgid ""
320
+ "Enable advanced tools for enhanced protection against even the most "
321
+ "aggressive of hackers and bots."
322
+ msgstr ""
323
+
324
+ #: app/module/advanced-tools/behavior/at-widget.php:27
325
+ #: app/module/advanced-tools/view/disabled.php:4
326
+ #: app/module/advanced-tools/view/layouts/layout.php:13
327
+ #: app/module/advanced-tools/view/layouts/layout.php:20
328
+ #: app/module/advanced-tools/view/login/disabled.php:6
329
+ #: app/module/advanced-tools/view/login/enabled.php:6
330
+ #: app/module/advanced-tools/view/main.php:4
331
+ msgid "2 Factor Authentication"
332
+ msgstr ""
333
+
334
+ #: app/module/advanced-tools/behavior/at-widget.php:31
335
+ msgid ""
336
+ "Protect your user accounts by requiring a second passcode sent to users "
337
+ "phones in order to get past your login screen"
338
+ msgstr ""
339
+
340
+ #: app/module/advanced-tools/behavior/at-widget.php:40
341
+ #: app/module/advanced-tools/view/login/enabled.php:9
342
+ msgid "2 factor authentication is active."
343
+ msgstr ""
344
+
345
+ #: app/module/advanced-tools/behavior/at-widget.php:48
346
+ #: app/module/advanced-tools/view/disabled.php:19
347
+ #: app/module/audit/behavior/audit.php:43 app/module/audit/view/new.php:15
348
+ #: app/module/ip-lockout/behavior/widget.php:37
349
+ msgid "Activate"
350
+ msgstr ""
351
+
352
  #: app/module/advanced-tools/controller/main.php:58
353
  msgid ""
354
  "You enabled Jetpack WordPress.com login, so Defender will disable the 2 "
389
  msgid "Whoops, the passcode you entered was incorrect or expired."
390
  msgstr ""
391
 
 
 
 
 
 
392
  #: app/module/advanced-tools/controller/main.php:455
393
  #: app/module/audit/controller/main.php:196
394
+ #: app/module/ip-lockout/controller/main.php:664
395
  #: app/module/scan/controller/main.php:305
396
  msgid "Your settings have been updated."
397
  msgstr ""
398
 
 
 
 
 
 
 
 
 
 
399
  #: app/module/advanced-tools/view/disabled.php:10
400
  msgid ""
401
  "Beef up your website’s security with 2-Step verification. Protect your user "
404
  "attacks."
405
  msgstr ""
406
 
 
 
 
 
 
 
407
  #: app/module/advanced-tools/view/login/disabled.php:2
408
  #: app/module/advanced-tools/view/login/enabled.php:2
409
  msgid "Security"
422
 
423
  #: app/module/advanced-tools/view/login/disabled.php:20
424
  #: app/module/audit/view/report.php:68 app/module/scan/controller/main.php:530
425
+ #: app/module/scan/view/setting.php:138 app/module/scan/view/setting.php:158
426
  msgid "Cancel"
427
  msgstr ""
428
 
460
  msgid "Verify"
461
  msgstr ""
462
 
 
 
 
 
463
  #: app/module/advanced-tools/view/login/enabled.php:12
464
  msgid "Disabled"
465
  msgstr ""
483
  msgstr ""
484
 
485
  #: app/module/advanced-tools/view/login/otp.php:224
486
+ msgid "Open the Google Authenticator app and enter the 6 digit passcode."
487
  msgstr ""
488
 
489
  #: app/module/advanced-tools/view/login/otp.php:227
1119
  msgstr ""
1120
 
1121
  #: app/module/audit/component/options-audit.php:215
1122
+ #: app/module/audit/view/layouts/layout.php:71
1123
+ #: app/module/audit/view/layouts/layout.php:83
1124
  #: app/module/audit/view/settings.php:3
1125
  #: app/module/ip-lockout/view/layouts/layout.php:74
1126
  #: app/module/ip-lockout/view/layouts/layout.php:94
1127
  #: app/module/ip-lockout/view/settings.php:3
1128
+ #: app/module/scan/view/layouts/layout.php:132
1129
+ #: app/module/scan/view/layouts/layout.php:149
1130
  #: app/module/scan/view/setting-free.php:3 app/module/scan/view/setting.php:3
1131
+ #: app/view/settings.php:6 free/main-activator.php:158 main-activator.php:96
1132
  msgid "Settings"
1133
  msgstr ""
1134
 
1204
  msgid "%s changed user %s's role from %s to %s"
1205
  msgstr ""
1206
 
1207
+ #: app/module/audit/component/users-audit.php:164
1208
  msgid "User %s updated his/her profile"
1209
  msgstr ""
1210
 
1211
+ #: app/module/audit/component/users-audit.php:169
1212
  msgid "%s updated user %s's profile information"
1213
  msgstr ""
1214
 
1215
+ #: app/module/audit/component/users-audit.php:177
1216
  msgid "lost password"
1217
  msgstr ""
1218
 
1219
+ #: app/module/audit/component/users-audit.php:178
1220
  msgid "registered"
1221
  msgstr ""
1222
 
1223
+ #: app/module/audit/component/users-audit.php:179
1224
  msgid "login"
1225
  msgstr ""
1226
 
1227
+ #: app/module/audit/component/users-audit.php:180
1228
  msgid "logout"
1229
  msgstr ""
1230
 
1231
+ #: app/module/audit/component/users-audit.php:181
1232
  msgid "password reset"
1233
  msgstr ""
1234
 
1235
  #: app/module/audit/controller/main-free.php:36
1236
+ #: app/module/audit/controller/main.php:502
1237
  #: app/module/audit/view/pro-feature.php:22
1238
  #: app/module/ip-lockout/view/pro-feature.php:22
1239
  #: app/module/scan/view/pro-feature.php:22 app/view/activator.php:33
1270
  msgid "User"
1271
  msgstr ""
1272
 
1273
+ #: app/module/audit/controller/main.php:203
1274
+ #: app/module/audit/view/layouts/layout.php:39
1275
+ msgid "at %s"
1276
+ msgstr ""
1277
+
1278
+ #: app/module/audit/controller/main.php:205
1279
+ #: app/module/audit/view/layouts/layout.php:42
1280
+ msgid "%s at %s"
1281
+ msgstr ""
1282
+
1283
+ #: app/module/audit/controller/main.php:344
1284
  msgid "Hi {USER_NAME},"
1285
  msgstr ""
1286
 
1287
+ #: app/module/audit/controller/main.php:346
1288
  msgid ""
1289
  "It’s WP Defender here, reporting from the frontline with a quick update on "
1290
  "what’s been happening at <a href=\"%s\">%s</a>."
1291
  msgstr ""
1292
 
1293
+ #: app/module/audit/controller/main.php:358
1294
  msgid "Event Type"
1295
  msgstr ""
1296
 
1297
+ #: app/module/audit/controller/main.php:362
1298
  msgid "Action Summaries"
1299
  msgstr ""
1300
 
1301
+ #: app/module/audit/controller/main.php:403
1302
  msgid "You can view the full audit report for your site here."
1303
  msgstr ""
1304
 
1305
+ #: app/module/audit/controller/main.php:436
1306
  msgid "There were no events logged for %s"
1307
  msgstr ""
1308
 
1309
+ #: app/module/audit/controller/main.php:441
1310
+ #: app/module/audit/controller/main.php:466
1311
  msgid "Here’s what’s been happening at %s"
1312
  msgstr ""
1313
 
1314
+ #: app/module/audit/controller/main.php:558 app/view/settings.php:209
1315
  msgid "Type a user’s name"
1316
  msgstr ""
1317
 
1318
+ #: app/module/audit/controller/main.php:559
1319
  msgid "We did not find an user with this name..."
1320
  msgstr ""
1321
 
1386
  msgid "<a href=\"%s\">Configure reporting preferences</a>"
1387
  msgstr ""
1388
 
1389
+ #: app/module/audit/view/free.php:9 free/main-activator.php:118
1390
  msgid "Upgrade"
1391
  msgstr ""
1392
 
1403
  msgstr ""
1404
 
1405
  #: app/module/audit/view/layouts/layout.php:28
1406
+ #: app/module/audit/view/layouts/layout.php:75
1407
+ #: app/module/audit/view/layouts/layout.php:85
1408
  msgid "Reports"
1409
  msgstr ""
1410
 
1411
+ #: app/module/audit/view/layouts/layout.php:67
1412
+ #: app/module/audit/view/layouts/layout.php:81
 
 
 
 
 
 
 
 
1413
  msgid "Event Logs"
1414
  msgstr ""
1415
 
1530
  msgstr ""
1531
 
1532
  #: app/module/audit/view/report.php:9
1533
+ msgid "Audit report"
1534
  msgstr ""
1535
 
1536
  #: app/module/audit/view/report.php:11
1586
  msgstr ""
1587
 
1588
  #: app/module/audit/view/report.php:67 app/module/scan/view/automation.php:67
1589
+ #: app/module/scan/view/setting-free.php:131
1590
  #: app/module/scan/view/setting.php:116
1591
  msgid "Update Settings"
1592
  msgstr ""
1603
  #: app/module/ip-lockout/view/blacklist/enabled.php:114
1604
  #: app/module/ip-lockout/view/detect-404/enabled.php:148
1605
  #: app/module/ip-lockout/view/login-lockouts/enabled.php:124
1606
+ #: app/module/ip-lockout/view/notification/enabled.php:124
1607
  #: app/module/ip-lockout/view/notification/report.php:81
1608
  #: app/module/ip-lockout/view/settings.php:44
1609
  msgid "UPDATE SETTINGS"
1714
  #: app/module/hardener/component/db-prefix-service.php:95
1715
  #: app/module/hardener/component/disable-file-editor-service.php:32
1716
  #: app/module/hardener/component/disable-file-editor-service.php:66
1717
+ #: app/module/hardener/component/hide-error-service.php:61
1718
  #: app/module/hardener/component/protect-information-service.php:44
1719
  #: app/module/hardener/component/protect-information-service.php:77
1720
  #: app/module/hardener/component/security-key-service.php:48
1763
  msgstr ""
1764
 
1765
  #: app/module/hardener/component/disable-file-editor-service.php:40
1766
+ #: app/module/hardener/component/hide-error-service.php:70
1767
+ #: app/module/hardener/component/hide-error-service.php:78
1768
  #: app/module/hardener/component/security-key-service.php:117
1769
  msgid ""
1770
  "Defender can't recognize your wp-config.php, please revert it to original "
1789
  msgid "Disable trackbacks and pingbacks"
1790
  msgstr ""
1791
 
1792
+ #: app/module/hardener/component/hide-error-service.php:103
1793
  msgid "WP_DEBUG get override somewhere, please check with your host provider"
1794
  msgstr ""
1795
 
1803
  msgstr ""
1804
 
1805
  #: app/module/hardener/component/login-duration.php:94
1806
+ msgid "Duration can only be a number and greater than 0"
1807
  msgstr ""
1808
 
1809
+ #: app/module/hardener/component/login-duration.php:194
1810
  msgid ""
1811
  "Your session has expired because it has been over %d days since your last "
1812
  "login. Please log back in to continue."
1908
  msgstr ""
1909
 
1910
  #: app/module/hardener/view/issues.php:3
1911
+ #: app/module/hardener/view/layouts/layout.php:61
1912
+ #: app/module/hardener/view/layouts/layout.php:98
1913
+ #: app/module/scan/view/issues.php:4 app/module/scan/view/layouts/layout.php:96
1914
+ #: app/module/scan/view/layouts/layout.php:145
1915
  msgid "Issues"
1916
  msgstr ""
1917
 
1922
  "recommend you action as many tweaks as possible."
1923
  msgstr ""
1924
 
1925
+ #: app/module/hardener/view/layouts/layout.php:20 app/view/dashboard.php:16
1926
+ #: app/view/dashboard.php:32
1927
+ msgid "You have no outstanding security issues."
1928
  msgstr ""
1929
 
1930
+ #: app/module/hardener/view/layouts/layout.php:28 app/view/dashboard.php:46
1931
  msgid "Security tweaks actioned"
1932
  msgstr ""
1933
 
1939
  msgid "WordPress Version"
1940
  msgstr ""
1941
 
1942
+ #: app/module/hardener/view/layouts/layout.php:65
1943
+ msgid "You have %d security tweak(s) needing attention."
1944
  msgstr ""
1945
 
1946
+ #: app/module/hardener/view/layouts/layout.php:74
1947
+ #: app/module/hardener/view/layouts/layout.php:100
1948
  msgid "Resolved"
1949
  msgstr ""
1950
 
1951
+ #: app/module/hardener/view/layouts/layout.php:81
1952
+ #: app/module/hardener/view/layouts/layout.php:102
1953
  #: app/module/scan/view/cleaned.php:3 app/module/scan/view/ignored.php:3
1954
+ #: app/module/scan/view/layouts/layout.php:121
1955
+ #: app/module/scan/view/layouts/layout.php:147
1956
  msgid "Ignored"
1957
  msgstr ""
1958
 
2127
 
2128
  #: app/module/hardener/view/rules/hide-error.php:40
2129
  msgid ""
2130
+ "We attempted to disable the display_errors setting to prevent code errors "
2131
  "displaying but it’s being overridden by your server config. Please contact "
2132
+ "your hosting provider and ask them to set display_errors to false."
2133
  msgstr ""
2134
 
2135
  #: app/module/hardener/view/rules/login-duration.php:13
2198
  msgstr ""
2199
 
2200
  #: app/module/hardener/view/rules/prevent-php-executed.php:77
2201
+ #: app/module/hardener/view/rules/protect-information.php:35
2202
  msgid "Server Type:"
2203
  msgstr ""
2204
 
2205
  #: app/module/hardener/view/rules/prevent-php-executed.php:91
2206
  #: app/module/hardener/view/rules/prevent-php-executed.php:105
2207
+ #: app/module/hardener/view/rules/protect-information.php:47
2208
+ #: app/module/hardener/view/rules/protect-information.php:59
2209
  msgid ""
2210
  "We will place <strong>.htaccess</strong> file into the root folder to lock "
2211
  "down the files and folders inside."
2213
 
2214
  #: app/module/hardener/view/rules/prevent-php-executed.php:100
2215
  #: app/module/hardener/view/rules/prevent-php-executed.php:114
2216
+ #: app/module/hardener/view/rules/protect-information.php:54
2217
+ #: app/module/hardener/view/rules/protect-information.php:66
2218
  msgid "Add .htaccess file"
2219
  msgstr ""
2220
 
2221
  #: app/module/hardener/view/rules/prevent-php-executed.php:138
2222
+ #: app/module/hardener/view/rules/protect-information.php:98
2223
  msgid "For NGINX servers:"
2224
  msgstr ""
2225
 
2226
  #: app/module/hardener/view/rules/prevent-php-executed.php:141
2227
+ #: app/module/hardener/view/rules/protect-information.php:101
2228
  msgid ""
2229
  "Copy the generated code into your site specific .conf file usually located "
2230
  "in a subdirectory under /etc/nginx/... or /usr/local/nginx/conf/..."
2231
  msgstr ""
2232
 
2233
  #: app/module/hardener/view/rules/prevent-php-executed.php:144
2234
+ #: app/module/hardener/view/rules/protect-information.php:104
2235
  msgid ""
2236
  "Add the code above inside the <strong>server</strong> section in the file, "
2237
  "right before the php location block. Looks something like:"
2238
  msgstr ""
2239
 
2240
  #: app/module/hardener/view/rules/prevent-php-executed.php:148
2241
+ #: app/module/hardener/view/rules/protect-information.php:108
2242
  msgid "Reload NGINX."
2243
  msgstr ""
2244
 
2245
  #: app/module/hardener/view/rules/prevent-php-executed.php:151
2246
+ #: app/module/hardener/view/rules/protect-information.php:111
2247
  msgid ""
2248
  "Still having trouble? <a target='_blank' href=\"%s\">Open a support "
2249
  "ticket</a>."
2250
  msgstr ""
2251
 
2252
  #: app/module/hardener/view/rules/prevent-php-executed.php:161
2253
+ #: app/module/hardener/view/rules/protect-information.php:117
2254
  msgid "For IIS servers, <a href=\"%s\">visit Microsoft TechNet</a>"
2255
  msgstr ""
2256
 
2294
  msgid "Your WordPress is protected."
2295
  msgstr ""
2296
 
2297
+ #: app/module/hardener/view/rules/protect-information.php:122
2298
  msgid "For IIS 7 servers, <a href=\"%s\">visit Microsoft TechNet</a>"
2299
  msgstr ""
2300
 
2404
  msgid "Lockout notifications are disabled"
2405
  msgstr ""
2406
 
2407
+ #: app/module/ip-lockout/component/login-protection-api.php:61
2408
+ #: app/module/ip-lockout/controller/main.php:559
2409
+ #: app/module/ip-lockout/controller/main.php:568
2410
  msgid ""
2411
  "You have been locked out by the administrator for attempting to login with "
2412
  "a banned username"
2413
  msgstr ""
2414
 
2415
+ #: app/module/ip-lockout/component/login-protection-api.php:74
2416
  msgid "Lockout occurred: Attempting to login with a banned username."
2417
  msgstr ""
2418
 
2419
+ #: app/module/ip-lockout/component/login-protection-api.php:76
2420
+ msgid "Lockout occurred: Too many failed login attempts for the username %s"
2421
+ msgstr ""
2422
+
2423
+ #: app/module/ip-lockout/component/login-protection-api.php:78
2424
  msgid "Lockout occurred: Too many failed login attempts"
2425
  msgstr ""
2426
 
2427
+ #: app/module/ip-lockout/component/login-protection-api.php:156
2428
  msgid "Lockout occurred: Too many 404 requests for %s"
2429
  msgstr ""
2430
 
2431
+ #: app/module/ip-lockout/component/login-protection-api.php:256
2432
  msgid "Ban"
2433
  msgstr ""
2434
 
2435
+ #: app/module/ip-lockout/component/login-protection-api.php:258
2436
  msgid "Unban"
2437
  msgstr ""
2438
 
2439
+ #: app/module/ip-lockout/component/login-protection-api.php:263
2440
  #: app/module/ip-lockout/view/blacklist/enabled.php:53
2441
  #: app/module/ip-lockout/view/detect-404/enabled.php:93
2442
  msgid "Whitelist"
2443
  msgstr ""
2444
 
2445
+ #: app/module/ip-lockout/component/login-protection-api.php:265
2446
  msgid "Unwhitelist"
2447
  msgstr ""
2448
 
2481
 
2482
  #: app/module/ip-lockout/component/logs-table.php:164
2483
  #: app/module/ip-lockout/model/log-model-legacy.php:111
2484
+ #: app/module/ip-lockout/model/log-model.php:65
2485
  msgid "Failed login attempts"
2486
  msgstr ""
2487
 
2488
  #: app/module/ip-lockout/component/logs-table.php:166
2489
  #: app/module/ip-lockout/model/log-model-legacy.php:112
2490
+ #: app/module/ip-lockout/model/log-model.php:66
2491
  msgid "Login lockout"
2492
  msgstr ""
2493
 
2494
  #: app/module/ip-lockout/component/logs-table.php:168
2495
  #: app/module/ip-lockout/model/log-model-legacy.php:113
2496
  #: app/module/ip-lockout/model/log-model-legacy.php:114
 
2497
  #: app/module/ip-lockout/model/log-model.php:67
2498
+ #: app/module/ip-lockout/model/log-model.php:68
2499
  msgid "404 error"
2500
  msgstr ""
2501
 
2502
  #: app/module/ip-lockout/component/logs-table.php:170
2503
  #: app/module/ip-lockout/model/log-model-legacy.php:115
2504
+ #: app/module/ip-lockout/model/log-model.php:69
2505
  msgid "404 lockout"
2506
  msgstr ""
2507
 
2523
  msgid "%s results"
2524
  msgstr ""
2525
 
2526
+ #: app/module/ip-lockout/component/logs-table.php:343
2527
+ msgid "Select All"
2528
+ msgstr ""
2529
+
2530
  #: app/module/ip-lockout/controller/main.php:151
2531
  msgid "Your logs have been successfully deleted."
2532
  msgstr ""
2545
  msgid "Demo"
2546
  msgstr ""
2547
 
2548
+ #: app/module/ip-lockout/controller/main.php:402
2549
  msgid "404 lockout alert for %s"
2550
  msgstr ""
2551
 
2552
+ #: app/module/ip-lockout/controller/main.php:428
2553
  msgid "Login lockout alert for %s"
2554
  msgstr ""
2555
 
2556
+ #: app/module/ip-lockout/controller/main.php:498
2557
  msgid "Failed login attempt with username %s"
2558
  msgstr ""
2559
 
2560
+ #: app/module/ip-lockout/controller/main.php:561
2561
+ #: app/module/ip-lockout/controller/main.php:571
2562
  msgid "%d login attempts remaining"
2563
  msgstr ""
2564
 
2565
+ #: app/module/ip-lockout/controller/main.php:660
2566
  msgid ""
2567
  "Your settings have been updated, however some IPs were removed because "
2568
  "invalid format, or you blacklist yourself"
2569
  msgstr ""
2570
 
2571
+ #: app/module/ip-lockout/controller/main.php:671
2572
  msgid "Login Protection has been activated."
2573
  msgstr ""
2574
 
2575
+ #: app/module/ip-lockout/controller/main.php:673
2576
  msgid "Login Protection has been deactivated."
2577
  msgstr ""
2578
 
2579
+ #: app/module/ip-lockout/controller/main.php:678
2580
  msgid "404 Detection has been activated."
2581
  msgstr ""
2582
 
2583
+ #: app/module/ip-lockout/controller/main.php:680
2584
  msgid "404 Detection has been deactivated."
2585
  msgstr ""
2586
 
2587
+ #: app/module/ip-lockout/controller/main.php:709 app/module/ip-lockout.php:35
2588
  #: app/view/activator-free.php:33 app/view/activator.php:49
2589
  msgid "IP Lockouts"
2590
  msgstr ""
2591
 
2592
+ #: app/module/ip-lockout/controller/main.php:726
2593
+ #: app/module/ip-lockout/controller/main.php:732
2594
  msgid "Your file is invalid!"
2595
  msgstr ""
2596
 
2597
+ #: app/module/ip-lockout/controller/main.php:738
2598
  msgid "Your file content is invalid!"
2599
  msgstr ""
2600
 
2601
+ #: app/module/ip-lockout/controller/main.php:747
2602
  msgid "Your whitelist/blacklist has been successfully imported."
2603
  msgstr ""
2604
 
2605
+ #: app/module/ip-lockout/controller/main.php:917
2606
+ msgid "Thanks for your patience. All set."
2607
  msgstr ""
2608
 
2609
  #: app/module/ip-lockout/model/log-model-legacy.php:79
2610
+ #: app/module/ip-lockout/model/log-model.php:39
2611
  msgid ""
2612
  "Request for file <span class='log-text-table' tooltip='%s'>%s</span> which "
2613
  "doesn't exist"
2974
  #: app/module/ip-lockout/view/notification/report.php:3
2975
  #: app/module/scan/view/automation-free.php:3
2976
  #: app/module/scan/view/automation.php:3
2977
+ #: app/module/scan/view/layouts/layout.php:137
2978
+ #: app/module/scan/view/layouts/layout.php:151
2979
  msgid "Reporting"
2980
  msgstr ""
2981
 
3099
  "email."
3100
  msgstr ""
3101
 
3102
+ #: app/module/ip-lockout/view/notification/enabled.php:64
3103
+ msgid "Repeat Lockouts"
3104
+ msgstr ""
3105
+
3106
+ #: app/module/ip-lockout/view/notification/enabled.php:67
3107
+ msgid ""
3108
+ "If you’re getting too many emails from IPs who are repeatedly being locked "
3109
+ "out you can turn them off for a period of time."
3110
+ msgstr ""
3111
+
3112
+ #: app/module/ip-lockout/view/notification/enabled.php:79
3113
+ msgid "Limit email notifications for repeat lockouts"
3114
+ msgstr ""
3115
+
3116
+ #: app/module/ip-lockout/view/notification/enabled.php:81
3117
+ msgid "Threshold"
3118
+ msgstr ""
3119
+
3120
+ #: app/module/ip-lockout/view/notification/enabled.php:82
3121
+ msgid "The number of lockouts before we turn off emails"
3122
+ msgstr ""
3123
+
3124
+ #: app/module/ip-lockout/view/notification/enabled.php:94
3125
+ msgid "Cool Off Period"
3126
+ msgstr ""
3127
+
3128
+ #: app/module/ip-lockout/view/notification/enabled.php:95
3129
+ msgid "For how long should we turn them off?"
3130
+ msgstr ""
3131
+
3132
+ #: app/module/ip-lockout/view/notification/enabled.php:99
3133
+ msgid "1 hour"
3134
+ msgstr ""
3135
+
3136
+ #: app/module/ip-lockout/view/notification/enabled.php:101
3137
+ msgid "2 hours"
3138
+ msgstr ""
3139
+
3140
+ #: app/module/ip-lockout/view/notification/enabled.php:103
3141
+ msgid "6 hours"
3142
+ msgstr ""
3143
+
3144
+ #: app/module/ip-lockout/view/notification/enabled.php:105
3145
+ msgid "12 hours"
3146
+ msgstr ""
3147
+
3148
+ #: app/module/ip-lockout/view/notification/enabled.php:107
3149
+ msgid "24 hours"
3150
+ msgstr ""
3151
+
3152
+ #: app/module/ip-lockout/view/notification/enabled.php:109
3153
+ msgid "36 hours"
3154
+ msgstr ""
3155
+
3156
+ #: app/module/ip-lockout/view/notification/enabled.php:111
3157
+ msgid "48 hours"
3158
+ msgstr ""
3159
+
3160
+ #: app/module/ip-lockout/view/notification/enabled.php:113
3161
+ msgid "7 days"
3162
+ msgstr ""
3163
+
3164
+ #: app/module/ip-lockout/view/notification/enabled.php:115
3165
+ msgid "30 days"
3166
+ msgstr ""
3167
+
3168
  #: app/module/ip-lockout/view/notification/report-free.php:15
3169
  #: app/module/ip-lockout/view/notification/report.php:10
3170
  msgid "Lockouts report"
3268
  #: app/module/scan/behavior/core-result.php:75
3269
  #: app/module/scan/behavior/core-result.php:405
3270
  #: app/module/scan/behavior/core-result.php:410
3271
+ #: app/module/scan/behavior/pro/content-result.php:209
3272
+ #: app/module/scan/behavior/pro/content-result.php:230
3273
+ #: app/module/scan/behavior/pro/content-result.php:235
3274
  msgid "Defender doesn't have enough permission to remove this file"
3275
  msgstr ""
3276
 
3393
  msgid "This will permanent delete this file, do you want to do this?"
3394
  msgstr ""
3395
 
3396
+ #: app/module/scan/behavior/pro/content-result.php:203
3397
+ msgid "wp-config.php can't be removed. Please remove the suspicious code manually."
3398
+ msgstr ""
3399
+
3400
  #: app/module/scan/behavior/pro/vuln-result.php:33
3401
  msgid "WordPress Vulnerability"
3402
  msgstr ""
3458
  msgstr ""
3459
 
3460
  #: app/module/scan/behavior/scan.php:113
3461
+ #: app/module/scan/view/layouts/layout.php:28
3462
  msgid "Your code is clean, the skies are clear."
3463
  msgstr ""
3464
 
3470
 
3471
  #: app/module/scan/behavior/scan.php:130
3472
  #: app/module/scan/view/layouts/layout.php:54
3473
+ #: app/module/scan/view/setting-free.php:35 app/module/scan/view/setting.php:32
3474
  msgid "Plugins & Themes"
3475
  msgstr ""
3476
 
3478
  #: app/module/scan/view/layouts/layout.php:62
3479
  #: app/module/scan/view/layouts/layout.php:78
3480
  #: app/module/scan/view/setting-free.php:30
3481
+ #: app/module/scan/view/setting-free.php:45
3482
  msgid "Pro Feature"
3483
  msgstr ""
3484
 
3561
  msgid "A scan is already in progress"
3562
  msgstr ""
3563
 
3564
+ #: app/module/scan/component/scan-api.php:192
3565
  msgid "No scan record exists"
3566
  msgstr ""
3567
 
3568
+ #: app/module/scan/component/scan-api.php:232
3569
  msgid "Analyzing WordPress Core..."
3570
  msgstr ""
3571
 
3572
+ #: app/module/scan/component/scan-api.php:235
3573
  msgid "Analyzing WordPress Content..."
3574
  msgstr ""
3575
 
3576
+ #: app/module/scan/component/scan-api.php:238
3577
  msgid "Checking for any published vulnerabilities your plugins & themes..."
3578
  msgstr ""
3579
 
3740
  msgid "New Scan"
3741
  msgstr ""
3742
 
 
 
 
 
3743
  #: app/module/scan/view/layouts/layout.php:36
3744
+ msgid "File scanning issues need attention."
3745
  msgstr ""
3746
 
3747
  #: app/module/scan/view/layouts/layout.php:39
3748
  msgid "Last scan"
3749
  msgstr ""
3750
 
3751
+ #: app/module/scan/view/layouts/layout.php:101
3752
  msgid "You have %d suspicious file(s) needing attention"
3753
  msgstr ""
3754
 
3791
  msgid "Defender checks for any modifications or additions to WordPress core files."
3792
  msgstr ""
3793
 
3794
+ #: app/module/scan/view/setting-free.php:37 app/module/scan/view/setting.php:34
3795
  msgid ""
3796
  "Defender looks for publicly reported vulnerabilities in your installed "
3797
  "plugins and themes."
3798
  msgstr ""
3799
 
3800
+ #: app/module/scan/view/setting-free.php:52 app/module/scan/view/setting.php:45
3801
  #: app/view/settings.php:117
3802
  msgid ""
3803
  "Defender looks inside all of your files for suspicious and potentially "
3804
  "harmful code."
3805
  msgstr ""
3806
 
3807
+ #: app/module/scan/view/setting-free.php:59
3808
  msgid ""
3809
  "Defenders scans through every line of code on your website, searching for "
3810
  "anything suspicious. This feature is included when you join WPMU DEV, along "
3811
  "with 100+ plugins and themes, 24/7 support and lots of handy site "
3812
+ "management tools. – <a href=\"%s\" role='button'>Try it all FREE today!\n"
3813
  " </a>"
3814
  msgstr ""
3815
 
3816
+ #: app/module/scan/view/setting-free.php:66 app/module/scan/view/setting.php:51
3817
  msgid "Maximum included file size"
3818
  msgstr ""
3819
 
3820
+ #: app/module/scan/view/setting-free.php:68 app/module/scan/view/setting.php:53
3821
  msgid ""
3822
  "Defender will skip any files larger than this size. The smaller the number, "
3823
  "the faster Defender will scan your website."
3824
  msgstr ""
3825
 
3826
+ #: app/module/scan/view/setting-free.php:73 app/module/scan/view/setting.php:58
3827
  msgid "MB"
3828
  msgstr ""
3829
 
3830
+ #: app/module/scan/view/setting-free.php:78 app/module/scan/view/setting.php:63
3831
  msgid "Optional emails"
3832
  msgstr ""
3833
 
3834
+ #: app/module/scan/view/setting-free.php:80 app/module/scan/view/setting.php:65
3835
  msgid ""
3836
  "By default, you'll only get email reports when your site runs into trouble. "
3837
  "Turn this option on to get reports even when your site is running smoothly."
3838
  msgstr ""
3839
 
3840
+ #: app/module/scan/view/setting-free.php:90 app/module/scan/view/setting.php:75
3841
  msgid "Send all scan report emails"
3842
  msgstr ""
3843
 
3844
+ #: app/module/scan/view/setting-free.php:95 app/module/scan/view/setting.php:80
3845
  msgid "Email subject"
3846
  msgstr ""
3847
 
3848
+ #: app/module/scan/view/setting-free.php:103
3849
  #: app/module/scan/view/setting.php:88
3850
  msgid "Email templates"
3851
  msgstr ""
3852
 
3853
+ #: app/module/scan/view/setting-free.php:105
3854
  #: app/module/scan/view/setting.php:90
3855
  msgid ""
3856
  "When Defender scans your website, a report will be generated with any "
3857
  "issues that have been found. You can choose to have reports emailed to you."
3858
  msgstr ""
3859
 
3860
+ #: app/module/scan/view/setting-free.php:112
3861
  #: app/module/scan/view/setting.php:97
3862
  msgid "When an issue is found"
3863
  msgstr ""
3864
 
3865
+ #: app/module/scan/view/setting-free.php:114
3866
+ #: app/module/scan/view/setting-free.php:122
3867
  #: app/module/scan/view/setting.php:99 app/module/scan/view/setting.php:107
3868
  msgid "Edit"
3869
  msgstr ""
3870
 
3871
+ #: app/module/scan/view/setting-free.php:119
3872
  #: app/module/scan/view/setting.php:104
3873
  msgid "When no issues are found"
3874
  msgstr ""
3875
 
3876
+ #: app/module/scan/view/setting-free.php:136
3877
  #: app/module/scan/view/setting.php:121 app/view/settings.php:287
3878
  msgid "Issues found"
3879
  msgstr ""
3880
 
3881
+ #: app/module/scan/view/setting-free.php:141
3882
+ #: app/module/scan/view/setting-free.php:149
 
3883
  msgid "Save"
3884
  msgstr ""
3885
 
3886
+ #: app/module/scan/view/setting-free.php:144
3887
+ #: app/module/scan/view/setting.php:143 app/view/settings.php:304
3888
  msgid "All OK"
3889
  msgstr ""
3890
 
3891
+ #: app/module/scan/view/setting.php:126 app/module/scan/view/setting.php:150
3892
+ #: app/view/settings.php:229
3893
+ msgid "Available variables"
3894
+ msgstr ""
3895
+
3896
+ #: app/module/scan/view/setting.php:139 app/module/scan/view/setting.php:159
3897
+ msgid "Save Template"
3898
+ msgstr ""
3899
+
3900
+ #: app/module/scan.php:20
3901
+ msgid "Scans"
3902
+ msgstr ""
3903
+
3904
+ #: app/module/scan.php:21
3905
+ msgid "Scan"
3906
+ msgstr ""
3907
+
3908
+ #: app/module/scan.php:39
3909
+ msgid "Scan Items"
3910
+ msgstr ""
3911
+
3912
+ #: app/module/scan.php:40
3913
+ msgid "Scan Item"
3914
+ msgstr ""
3915
+
3916
  #: app/view/activator-free.php:4
3917
  msgid ""
3918
  "Welcome to Defender! Let's quickly set up the most important security "
3969
  "something’s wrong, we’ll let you know via email."
3970
  msgstr ""
3971
 
3972
+ #: app/view/dashboard.php:39
3973
  msgid "security issues"
3974
  msgstr ""
3975
 
3976
+ #: app/view/dashboard.php:58
3977
  msgid "File Scan Issues"
3978
  msgstr ""
3979
 
3980
+ #: app/view/dashboard.php:66
3981
  msgid "Last Lockout"
3982
  msgstr ""
3983
 
3984
+ #: app/view/dashboard.php:84
3985
  msgid "TRY PRO FEATURES FOR FREE!"
3986
  msgstr ""
3987
 
3988
+ #: app/view/dashboard.php:88
3989
  msgid ""
3990
  "Upgrade to Defender Pro to unlock Advanced File Scanning, Blacklist "
3991
  "Monitoring, Audit Logging and automated reporting for Audit Logging, IP "
3992
  "Lockouts and File Scans."
3993
  msgstr ""
3994
 
3995
+ #: app/view/dashboard.php:91
3996
  msgid ""
3997
  "Get all this as part of a WPMU DEV Membership, and the best part is you can "
3998
  "try everything absolutely free."
3999
  msgstr ""
4000
 
4001
+ #: app/view/dashboard.php:94
4002
  msgid "FIND OUT MORE"
4003
  msgstr ""
4004
 
4119
  "and change the copy below."
4120
  msgstr ""
4121
 
 
 
 
 
4122
  #: app/view/settings.php:238
4123
  msgid ""
4124
  "We’ll grab the users first name, or display name is first name isn’t "
4153
  "this email."
4154
  msgstr ""
4155
 
4156
+ #: free/main-activator.php:66
4157
  msgid "Get Members!"
4158
  msgstr ""
4159
 
4160
+ #: free/main-activator.php:74
4161
+ msgid ""
4162
+ "We're happy that you've chosen to install Defender! Are you interested in "
4163
+ "how to make the most of this plugin? How would you like a quick 5 day email "
4164
+ "crash course with actionable advice on making your website security "
4165
+ "bulletproof? Only the info you want, no subscription!"
4166
+ msgstr ""
4167
+
4168
+ #: free/main-activator.php:116
4169
  msgid ""
4170
  "%s, you now have access to Defender's pro features but you still have the "
4171
  "free version installed. Let's upgrade Defender and unlock all those juicy "
4172
  "features! &nbsp; %s"
4173
  msgstr ""
4174
 
4175
+ #: free/main-activator.php:146
4176
  msgid "<br/>Something went wrong. Please try again later!"
4177
  msgstr ""
4178
 
4212
  msgid "Rate %s"
4213
  msgstr ""
4214
 
4215
+ #: main-activator.php:85
4216
  msgid ""
4217
  "We noticed you have both the free and pro versions of Defender installed, "
4218
  "so we've automatically deactivated the free version for you."
main-activator.php CHANGED
@@ -19,7 +19,6 @@ class WD_Main_Activator {
19
  */
20
  public function redirectToDefender( $plugin ) {
21
  if ( $plugin == wp_defender()->plugin_slug ) {
22
- error_log( $plugin );
23
  exit( wp_redirect( network_admin_url( 'admin.php?page=wp-defender' ) ) );
24
  }
25
  }
@@ -30,12 +29,17 @@ class WD_Main_Activator {
30
  public function init() {
31
  $db_ver = get_site_option( 'wd_db_version' );
32
  if ( version_compare( $db_ver, '1.7', '<' ) ) {
33
- if (! \WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api::checkIfTableExists() ) {
34
- \WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api::createTables();
35
  add_site_option( 'defenderLockoutNeedUpdateLog', 1 );
 
 
36
  }
37
- update_site_option( 'wd_db_version', "1.7" );
38
  }
 
 
 
 
 
39
  add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( &$this, 'addSettingsLink' ) );
40
  add_action( 'admin_enqueue_scripts', array( &$this, 'register_styles' ) );
41
  if ( ! \WP_Defender\Behavior\Utils::instance()->checkRequirement() ) {
@@ -50,8 +54,8 @@ class WD_Main_Activator {
50
  \Hammer\Base\Container::instance()->set( 'lockout', new \WP_Defender\Module\IP_Lockout() );
51
  \Hammer\Base\Container::instance()->set( 'advanced_tool', new \WP_Defender\Module\Advanced_Tools() );
52
  //no need to set debug
53
- new \WP_Defender\Controller\Debug();
54
  require_once $this->wp_defender->getPluginPath() . 'free-dashboard/module.php';
 
55
  do_action(
56
  'wdev-register-plugin',
57
  /* 1 Plugin ID */
@@ -59,13 +63,19 @@ class WD_Main_Activator {
59
  'WP Defender',
60
  '/plugins/defender-security/',
61
  /* 4 Email Button CTA */
62
- null,
63
  /* 5 getdrip Plugin param */
64
  'WP Defender'
65
  );
66
  }
67
  }
68
 
 
 
 
 
 
 
69
  public function hideNotice() {
70
  $utils = \WP_Defender\Behavior\Utils::instance();
71
  if ( ! $utils->checkPermission() ) {
19
  */
20
  public function redirectToDefender( $plugin ) {
21
  if ( $plugin == wp_defender()->plugin_slug ) {
 
22
  exit( wp_redirect( network_admin_url( 'admin.php?page=wp-defender' ) ) );
23
  }
24
  }
29
  public function init() {
30
  $db_ver = get_site_option( 'wd_db_version' );
31
  if ( version_compare( $db_ver, '1.7', '<' ) ) {
32
+ if ( ! \WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api::checkIfTableExists() ) {
 
33
  add_site_option( 'defenderLockoutNeedUpdateLog', 1 );
34
+ \WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api::createTables();
35
+ update_site_option( 'wd_db_version', "1.7" );
36
  }
 
37
  }
38
+ if ( version_compare( $db_ver, '1.7.1', '<' ) ) {
39
+ \WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api::alterTableFor171();
40
+ update_site_option( 'wd_db_version', "1.7.1" );
41
+ }
42
+
43
  add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( &$this, 'addSettingsLink' ) );
44
  add_action( 'admin_enqueue_scripts', array( &$this, 'register_styles' ) );
45
  if ( ! \WP_Defender\Behavior\Utils::instance()->checkRequirement() ) {
54
  \Hammer\Base\Container::instance()->set( 'lockout', new \WP_Defender\Module\IP_Lockout() );
55
  \Hammer\Base\Container::instance()->set( 'advanced_tool', new \WP_Defender\Module\Advanced_Tools() );
56
  //no need to set debug
 
57
  require_once $this->wp_defender->getPluginPath() . 'free-dashboard/module.php';
58
+ add_filter( 'wdev-email-message-' . plugin_basename( __FILE__ ), array( &$this, 'defenderAdsMessage' ) );
59
  do_action(
60
  'wdev-register-plugin',
61
  /* 1 Plugin ID */
63
  'WP Defender',
64
  '/plugins/defender-security/',
65
  /* 4 Email Button CTA */
66
+ __( 'Get Members!', wp_defender()->domain ),
67
  /* 5 getdrip Plugin param */
68
  'WP Defender'
69
  );
70
  }
71
  }
72
 
73
+ public function defenderAdsMessage( $message ) {
74
+ $message = __( "We're happy that you've chosen to install Defender! Are you interested in how to make the most of this plugin? How would you like a quick 5 day email crash course with actionable advice on making your website security bulletproof? Only the info you want, no subscription!", wp_defender()->domain );
75
+
76
+ return $message;
77
+ }
78
+
79
  public function hideNotice() {
80
  $utils = \WP_Defender\Behavior\Utils::instance();
81
  if ( ! $utils->checkPermission() ) {
readme.txt CHANGED
@@ -111,6 +111,12 @@ Hackers and bot attacks are not the only threat to your site. No matter what se
111
 
112
  == Changelog ==
113
 
 
 
 
 
 
 
114
  = 1.7.0.1 =
115
  * Fix: notification message.
116
 
111
 
112
  == Changelog ==
113
 
114
+ = 1.7.1
115
+ * Added: widget for 2 factors authentication
116
+ * Fix: Defender does not detect the right IP when CloudFlare is being used
117
+ * Fix: Conflict with TM Photo Gallery Plugin
118
+ * Other minor enhancements/fixes
119
+
120
  = 1.7.0.1 =
121
  * Fix: notification message.
122
 
uninstall.php CHANGED
@@ -46,4 +46,6 @@ $cache->delete( 'cleanchecksum' );
46
  delete_site_option( 'wp_defender' );
47
  delete_option( 'wp_defender' );
48
  delete_site_option( 'wd_db_version' );
49
- delete_option( 'wd_db_version' );
 
 
46
  delete_site_option( 'wp_defender' );
47
  delete_option( 'wp_defender' );
48
  delete_site_option( 'wd_db_version' );
49
+ delete_option( 'wd_db_version' );
50
+ delete_option( 'wdf_noNotice' );
51
+ delete_site_option( 'wdf_noNotice' );
vendor/hammer/base/model.php CHANGED
@@ -2,6 +2,7 @@
2
  /**
3
  * Author: Hoang Ngo
4
  */
 
5
  namespace Hammer\Base;
6
 
7
  class Model extends Component {
@@ -69,6 +70,9 @@ class Model extends Component {
69
  }
70
 
71
  if ( ! empty( $validators ) ) {
 
 
 
72
  \GUMP::set_field_names( $this->getAttributeLabels() );
73
  $gump = new \GUMP();
74
  foreach ( $validators as $key => $rule ) {
2
  /**
3
  * Author: Hoang Ngo
4
  */
5
+
6
  namespace Hammer\Base;
7
 
8
  class Model extends Component {
70
  }
71
 
72
  if ( ! empty( $validators ) ) {
73
+ if ( ! class_exists( 'GUMP', false ) ) {
74
+ require_once dirname( __DIR__ ) . '/vendor/wixel/gump/gump.class.php';
75
+ }
76
  \GUMP::set_field_names( $this->getAttributeLabels() );
77
  $gump = new \GUMP();
78
  foreach ( $validators as $key => $rule ) {
vendor/hammer/bootstrap.php CHANGED
@@ -22,7 +22,7 @@ spl_autoload_register( function ( $class ) {
22
  } );
23
 
24
  //autoload dependencies
25
- require_once __DIR__ . '/vendor/autoload.php';
26
 
27
  //loading the dependency
28
  \Hammer\Base\Container::instance()->set( 'cache', initCacheEngine() );
22
  } );
23
 
24
  //autoload dependencies
25
+ //require_once __DIR__ . '/vendor/autoload.php';
26
 
27
  //loading the dependency
28
  \Hammer\Base\Container::instance()->set( 'cache', initCacheEngine() );
vendor/hammer/vendor/wixel/gump/gump.class.php CHANGED
@@ -10,52 +10,51 @@
10
  *
11
  * @version 1.4
12
  */
13
- if (!class_exists('GUMP')) {
14
- class GUMP
15
- {
16
- //Singleton instance of GUMP
17
- protected static $instance = null;
18
 
19
- // Validation rules for execution
20
- protected $validation_rules = array();
21
 
22
- // Filter rules for execution
23
- protected $filter_rules = array();
24
 
25
- // Instance attribute containing errors from last run
26
- protected $errors = array();
27
 
28
- // Contain readable field names that have been set manually
29
- protected static $fields = array();
30
 
31
- // Custom validation methods
32
- protected static $validation_methods = array();
33
 
34
- // Customer filter methods
35
- protected static $filter_methods = array();
36
 
37
- // ** ------------------------- Instance Helper ---------------------------- ** //
38
- /**
39
- * Function to create and return previously created instance
40
- *
41
- * @return GUMP
42
- */
43
 
44
- public static function get_instance(){
45
- if(self::$instance === null)
46
- {
47
- self::$instance = new self();
48
- }
49
- return self::$instance;
50
- }
51
 
 
 
 
 
52
 
 
 
53
 
54
- // ** ------------------------- Validation Data ------------------------------- ** //
55
 
56
- public static $basic_tags = '<br><p><a><strong><b><i><em><img><blockquote><code><dd><dl><hr><h1><h2><h3><h4><h5><h6><label><ul><li><span><sub><sup>';
57
 
58
- public static $en_noise_words = "about,after,all,also,an,and,another,any,are,as,at,be,because,been,before,
 
 
59
  being,between,both,but,by,came,can,come,could,did,do,each,for,from,get,
60
  got,has,had,he,have,her,here,him,himself,his,how,if,in,into,is,it,its,it's,like,
61
  make,many,me,might,more,most,much,must,my,never,now,of,on,only,or,other,
@@ -64,753 +63,732 @@ class GUMP
64
  very,was,way,we,well,were,what,where,which,while,who,with,would,you,your,a,
65
  b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$,1,2,3,4,5,6,7,8,9,0,_";
66
 
67
- // field characters below will be replaced with a space.
68
- protected $fieldCharsToRemove = array('_', '-');
69
-
70
- // ** ------------------------- Validation Helpers ---------------------------- ** //
71
-
72
- /**
73
- * Shorthand method for inline validation.
74
- *
75
- * @param array $data The data to be validated
76
- * @param array $validators The GUMP validators
77
- *
78
- * @return mixed True(boolean) or the array of error messages
79
- */
80
- public static function is_valid(array $data, array $validators)
81
- {
82
- $gump = self::get_instance();
83
-
84
- $gump->validation_rules($validators);
85
-
86
- if ($gump->run($data) === false) {
87
- return $gump->get_readable_errors(false);
88
- } else {
89
- return true;
90
- }
91
- }
92
-
93
- /**
94
- * Shorthand method for running only the data filters.
95
- *
96
- * @param array $data
97
- * @param array $filters
98
- *
99
- * @return mixed
100
- */
101
- public static function filter_input(array $data, array $filters)
102
- {
103
- $gump = self::get_instance();
104
-
105
- return $gump->filter($data, $filters);
106
- }
107
-
108
- /**
109
- * Magic method to generate the validation error messages.
110
- *
111
- * @return string
112
- */
113
- public function __toString()
114
- {
115
- return $this->get_readable_errors(true);
116
- }
117
-
118
- /**
119
- * Perform XSS clean to prevent cross site scripting.
120
- *
121
- * @static
122
- *
123
- * @param array $data
124
- *
125
- * @return array
126
- */
127
- public static function xss_clean(array $data)
128
- {
129
- foreach ($data as $k => $v) {
130
- $data[$k] = filter_var($v, FILTER_SANITIZE_STRING);
131
- }
132
-
133
- return $data;
134
- }
135
-
136
- /**
137
- * Adds a custom validation rule using a callback function.
138
- *
139
- * @param string $rule
140
- * @param callable $callback
141
- *
142
- * @return bool
143
- *
144
- * @throws Exception
145
- */
146
- public static function add_validator($rule, $callback)
147
- {
148
- $method = 'validate_'.$rule;
149
-
150
- if (method_exists(__CLASS__, $method) || isset(self::$validation_methods[$rule])) {
151
- throw new Exception("Validator rule '$rule' already exists.");
152
- }
153
-
154
- self::$validation_methods[$rule] = $callback;
155
-
156
- return true;
157
- }
158
-
159
- /**
160
- * Adds a custom filter using a callback function.
161
- *
162
- * @param string $rule
163
- * @param callable $callback
164
- *
165
- * @return bool
166
- *
167
- * @throws Exception
168
- */
169
- public static function add_filter($rule, $callback)
170
- {
171
- $method = 'filter_'.$rule;
172
-
173
- if (method_exists(__CLASS__, $method) || isset(self::$filter_methods[$rule])) {
174
- throw new Exception("Filter rule '$rule' already exists.");
175
- }
176
-
177
- self::$filter_methods[$rule] = $callback;
178
-
179
- return true;
180
- }
181
-
182
- /**
183
- * Helper method to extract an element from an array safely
184
- *
185
- * @param mixed $key
186
- * @param array $array
187
- * @param mixed $default
188
- * @return mixed
189
- */
190
- public static function field($key, array $array, $default = null)
191
- {
192
- if(!is_array($array)) {
193
- return null;
194
- }
195
-
196
- if(isset($array[$key])) {
197
- return $array[$key];
198
- } else {
199
- return $default;
200
- }
201
- }
202
-
203
- /**
204
- * Getter/Setter for the validation rules.
205
- *
206
- * @param array $rules
207
- *
208
- * @return array
209
- */
210
- public function validation_rules(array $rules = array())
211
- {
212
- if (empty($rules)) {
213
- return $this->validation_rules;
214
- }
215
-
216
- $this->validation_rules = $rules;
217
- }
218
-
219
- /**
220
- * Getter/Setter for the filter rules.
221
- *
222
- * @param array $rules
223
- *
224
- * @return array
225
- */
226
- public function filter_rules(array $rules = array())
227
- {
228
- if (empty($rules)) {
229
- return $this->filter_rules;
230
- }
231
-
232
- $this->filter_rules = $rules;
233
- }
234
-
235
- /**
236
- * Run the filtering and validation after each other.
237
- *
238
- * @param array $data
239
- * @param bool $check_fields
240
- *
241
- * @return array
242
- *
243
- * @throws Exception
244
- */
245
- public function run(array $data, $check_fields = false)
246
- {
247
- $data = $this->filter($data, $this->filter_rules());
248
-
249
- $validated = $this->validate(
250
- $data, $this->validation_rules()
251
- );
252
-
253
- if ($check_fields === true) {
254
- $this->check_fields($data);
255
- }
256
-
257
- if ($validated !== true) {
258
- return false;
259
- }
260
-
261
- return $data;
262
- }
263
-
264
- /**
265
- * Ensure that the field counts match the validation rule counts.
266
- *
267
- * @param array $data
268
- */
269
- private function check_fields(array $data)
270
- {
271
- $ruleset = $this->validation_rules();
272
- $mismatch = array_diff_key($data, $ruleset);
273
- $fields = array_keys($mismatch);
274
-
275
- foreach ($fields as $field) {
276
- $this->errors[] = array(
277
- 'field' => $field,
278
- 'value' => $data[$field],
279
- 'rule' => 'mismatch',
280
- 'param' => null,
281
- );
282
- }
283
- }
284
-
285
- /**
286
- * Sanitize the input data.
287
- *
288
- * @param array $input
289
- * @param null $fields
290
- * @param bool $utf8_encode
291
- *
292
- * @return array
293
- */
294
- public function sanitize(array $input, array $fields = array(), $utf8_encode = true)
295
- {
296
- $magic_quotes = (bool) get_magic_quotes_gpc();
297
-
298
- if (empty($fields)) {
299
- $fields = array_keys($input);
300
- }
301
-
302
- $return = array();
303
-
304
- foreach ($fields as $field) {
305
- if (!isset($input[$field])) {
306
- continue;
307
- } else {
308
- $value = $input[$field];
309
- if (is_array($value)) {
310
- $value = sanitize($value);
311
- }
312
- if (is_string($value)) {
313
- if ($magic_quotes === true) {
314
- $value = stripslashes($value);
315
- }
316
-
317
- if (strpos($value, "\r") !== false) {
318
- $value = trim($value);
319
- }
320
-
321
- if (function_exists('iconv') && function_exists('mb_detect_encoding') && $utf8_encode) {
322
- $current_encoding = mb_detect_encoding($value);
323
-
324
- if ($current_encoding != 'UTF-8' && $current_encoding != 'UTF-16') {
325
- $value = iconv($current_encoding, 'UTF-8', $value);
326
- }
327
- }
328
-
329
- $value = filter_var($value, FILTER_SANITIZE_STRING);
330
- }
331
-
332
- $return[$field] = $value;
333
- }
334
- }
335
-
336
- return $return;
337
- }
338
-
339
- /**
340
- * Return the error array from the last validation run.
341
- *
342
- * @return array
343
- */
344
- public function errors()
345
- {
346
- return $this->errors;
347
- }
348
-
349
- /**
350
- * Perform data validation against the provided ruleset.
351
- *
352
- * @param mixed $input
353
- * @param array $ruleset
354
- *
355
- * @return mixed
356
- *
357
- * @throws Exception
358
- */
359
- public function validate(array $input, array $ruleset)
360
- {
361
- $this->errors = array();
362
-
363
- foreach ($ruleset as $field => $rules) {
364
-
365
- $rules = explode('|', $rules);
366
-
367
- if (in_array('required', $rules) || (isset($input[$field]) && !is_array($input[$field]))) {
368
- foreach ($rules as $rule) {
369
- $method = null;
370
- $param = null;
371
-
372
- // Check if we have rule parameters
373
- if (strstr($rule, ',') !== false) {
374
- $rule = explode(',', $rule);
375
- $method = 'validate_'.$rule[0];
376
- $param = $rule[1];
377
- $rule = $rule[0];
378
- } else {
379
- $method = 'validate_'.$rule;
380
- }
381
-
382
- //self::$validation_methods[$rule] = $callback;
383
-
384
- if (is_callable(array($this, $method))) {
385
- $result = $this->$method(
386
- $field, $input, $param
387
- );
388
-
389
- if (is_array($result)) {
390
- $this->errors[] = $result;
391
- }
392
- } elseif(isset(self::$validation_methods[$rule])) {
393
-
394
- $result = call_user_func(self::$validation_methods[$rule], $field, $input, $param);
395
-
396
- if($result === false) {
397
- $this->errors[] = array(
398
- 'field' => $field,
399
- 'value' => $input,
400
- 'rule' => self::$validation_methods[$rule],
401
- 'param' => $param,
402
- );
403
- }
404
-
405
- } else {
406
- throw new Exception("Validator method '$method' does not exist.");
407
- }
408
- }
409
- }
410
- }
411
-
412
- return (count($this->errors) > 0) ? $this->errors : true;
413
- }
414
-
415
- /**
416
- * Overloadable method to invoke validation.
417
- *
418
- * @param array $input
419
- * @param $rules
420
- * @param $field
421
- *
422
- * @return bool
423
- */
424
- protected function shouldRunValidation(array $input, $rules, $field)
425
- {
426
- return in_array('required', $rules) || (isset($input[$field]) && trim($input[$field]) != '');
427
- }
428
-
429
- /**
430
- * Set a readable name for a specified field names.
431
- *
432
- * @param string $field
433
- * @param string $readable_name
434
- */
435
- public static function set_field_name($field, $readable_name)
436
- {
437
- self::$fields[$field] = $readable_name;
438
- }
439
-
440
- /**
441
- * Set readable name for specified fields in an array.
442
- *
443
- * Usage:
444
- *
445
- * GUMP::set_field_names(array(
446
- * "name" => "My Lovely Name",
447
- * "username" => "My Beloved Username",
448
- * ));
449
- *
450
- * @param array $array
451
- */
452
- public static function set_field_names(array $array)
453
- {
454
- foreach ($array as $field => $readable_name) {
455
- self::$fields[$field] = $readable_name;
456
- }
457
- }
458
-
459
- /**
460
- * Process the validation errors and return human readable error messages.
461
- *
462
- * @param bool $convert_to_string = false
463
- * @param string $field_class
464
- * @param string $error_class
465
- *
466
- * @return array
467
- * @return string
468
- */
469
- public function get_readable_errors($convert_to_string = false, $field_class = 'gump-field', $error_class = 'gump-error-message')
470
- {
471
- if (empty($this->errors)) {
472
- return ($convert_to_string) ? null : array();
473
- }
474
-
475
- $resp = array();
476
-
477
- foreach ($this->errors as $e) {
478
- $field = ucwords(str_replace($this->fieldCharsToRemove, chr(32), $e['field']));
479
- $param = $e['param'];
480
-
481
- // Let's fetch explicit field names if they exist
482
- if (array_key_exists($e['field'], self::$fields)) {
483
- $field = self::$fields[$e['field']];
484
- }
485
-
486
- switch ($e['rule']) {
487
- case 'mismatch' :
488
- $resp[] = "There is no validation rule for <span class=\"$field_class\">$field</span>";
489
- break;
490
- case 'validate_required' :
491
- $resp[] = "The <span class=\"$field_class\">$field</span> field is required";
492
- break;
493
- case 'validate_valid_email':
494
- $resp[] = "The <span class=\"$field_class\">$field</span> field is required to be a valid email address";
495
- break;
496
- case 'validate_max_len':
497
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be $param or shorter in length";
498
- break;
499
- case 'validate_min_len':
500
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be $param or longer in length";
501
- break;
502
- case 'validate_exact_len':
503
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be exactly $param characters in length";
504
- break;
505
- case 'validate_alpha':
506
- $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain alpha characters(a-z)";
507
- break;
508
- case 'validate_alpha_numeric':
509
- $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain alpha-numeric characters";
510
- break;
511
- case 'validate_alpha_dash':
512
- $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain alpha characters &amp; dashes";
513
- break;
514
- case 'validate_numeric':
515
- $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain numeric characters";
516
- break;
517
- case 'validate_integer':
518
- $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain a numeric value";
519
- break;
520
- case 'validate_boolean':
521
- $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain a true or false value";
522
- break;
523
- case 'validate_float':
524
- $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain a float value";
525
- break;
526
- case 'validate_valid_url':
527
- $resp[] = "The <span class=\"$field_class\">$field</span> field is required to be a valid URL";
528
- break;
529
- case 'validate_url_exists':
530
- $resp[] = "The <span class=\"$field_class\">$field</span> URL does not exist";
531
- break;
532
- case 'validate_valid_ip':
533
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to contain a valid IP address";
534
- break;
535
- case 'validate_valid_cc':
536
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to contain a valid credit card number";
537
- break;
538
- case 'validate_valid_name':
539
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to contain a valid human name";
540
- break;
541
- case 'validate_contains':
542
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to contain one of these values: ".implode(', ', $param);
543
- break;
544
- case 'validate_contains_list':
545
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to contain a value from its drop down list";
546
- break;
547
- case 'validate_doesnt_contain_list':
548
- $resp[] = "The <span class=\"$field_class\">$field</span> field contains a value that is not accepted";
549
- break;
550
- case 'validate_street_address':
551
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be a valid street address";
552
- break;
553
- case 'validate_date':
554
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be a valid date";
555
- break;
556
- case 'validate_min_numeric':
557
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be a numeric value, equal to, or higher than $param";
558
- break;
559
- case 'validate_max_numeric':
560
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be a numeric value, equal to, or lower than $param";
561
- break;
562
- case 'validate_starts':
563
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to start with $param";
564
- break;
565
- case 'validate_extension':
566
- $resp[] = "The <span class=\"$field_class\">$field</span> field can have the following extensions $param";
567
- break;
568
- case 'validate_required_file':
569
- $resp[] = "The <span class=\"$field_class\">$field</span> field is required";
570
- break;
571
- case 'validate_equalsfield':
572
- $resp[] = "The <span class=\"$field_class\">$field</span> field does not equal $param field";
573
- break;
574
- case 'validate_min_age':
575
- $resp[] = "The <span class=\"$field_class\">$field</span> field needs to have an age greater than or equal to $param";
576
- break;
577
- default:
578
- $resp[] = "The <span class=\"$field_class\">$field</span> field is invalid";
579
- }
580
- }
581
-
582
- if (!$convert_to_string) {
583
- return $resp;
584
- } else {
585
- $buffer = '';
586
- foreach ($resp as $s) {
587
- $buffer .= "<span class=\"$error_class\">$s</span>";
588
- }
589
-
590
- return $buffer;
591
- }
592
- }
593
-
594
- /**
595
- * Process the validation errors and return an array of errors with field names as keys.
596
- *
597
- * @param $convert_to_string
598
- *
599
- * @return array | null (if empty)
600
- */
601
- public function get_errors_array($convert_to_string = null)
602
- {
603
- if (empty($this->errors)) {
604
- return ($convert_to_string) ? null : array();
605
- }
606
-
607
- $resp = array();
608
-
609
- foreach ($this->errors as $e) {
610
- $field = ucwords(str_replace(array('_', '-'), chr(32), $e['field']));
611
- $param = $e['param'];
612
-
613
- // Let's fetch explicit field names if they exist
614
- if (array_key_exists($e['field'], self::$fields)) {
615
- $field = self::$fields[$e['field']];
616
- }
617
-
618
- switch ($e['rule']) {
619
- case 'mismatch' :
620
- $resp[$field] = "There is no validation rule for $field";
621
- break;
622
- case 'validate_required':
623
- $resp[$field] = "The $field field is required";
624
- break;
625
- case 'validate_valid_email':
626
- $resp[$field] = "The $field field is required to be a valid email address";
627
- break;
628
- case 'validate_max_len':
629
- $resp[$field] = "The $field field needs to be $param or shorter in length";
630
- break;
631
- case 'validate_min_len':
632
- $resp[$field] = "The $field field needs to be $param or longer in length";
633
- break;
634
- case 'validate_exact_len':
635
- $resp[$field] = "The $field field needs to be exactly $param characters in length";
636
- break;
637
- case 'validate_alpha':
638
- $resp[$field] = "The $field field may only contain alpha characters(a-z)";
639
- break;
640
- case 'validate_alpha_numeric':
641
- $resp[$field] = "The $field field may only contain alpha-numeric characters";
642
- break;
643
- case 'validate_alpha_dash':
644
- $resp[$field] = "The $field field may only contain alpha characters &amp; dashes";
645
- break;
646
- case 'validate_numeric':
647
- $resp[$field] = "The $field field may only contain numeric characters";
648
- break;
649
- case 'validate_integer':
650
- $resp[$field] = "The $field field may only contain a numeric value";
651
- break;
652
- case 'validate_boolean':
653
- $resp[$field] = "The $field field may only contain a true or false value";
654
- break;
655
- case 'validate_float':
656
- $resp[$field] = "The $field field may only contain a float value";
657
- break;
658
- case 'validate_valid_url':
659
- $resp[$field] = "The $field field is required to be a valid URL";
660
- break;
661
- case 'validate_url_exists':
662
- $resp[$field] = "The $field URL does not exist";
663
- break;
664
- case 'validate_valid_ip':
665
- $resp[$field] = "The $field field needs to contain a valid IP address";
666
- break;
667
- case 'validate_valid_cc':
668
- $resp[$field] = "The $field field needs to contain a valid credit card number";
669
- break;
670
- case 'validate_valid_name':
671
- $resp[$field] = "The $field field needs to contain a valid human name";
672
- break;
673
- case 'validate_contains':
674
- $resp[$field] = "The $field field needs to contain one of these values: ".implode(', ', $param);
675
- break;
676
- case 'validate_contains_list':
677
- $resp[$field] = "The $field field needs to contain a value from its drop down list";
678
- break;
679
- case 'validate_doesnt_contain_list':
680
- $resp[$field] = "The $field field contains a value that is not accepted";
681
- break;
682
- case 'validate_street_address':
683
- $resp[$field] = "The $field field needs to be a valid street address";
684
- break;
685
- case 'validate_date':
686
- $resp[$field] = "The $field field needs to be a valid date";
687
- break;
688
- case 'validate_min_numeric':
689
- $resp[$field] = "The $field field needs to be a numeric value, equal to, or higher than $param";
690
- break;
691
- case 'validate_max_numeric':
692
- $resp[$field] = "The $field field needs to be a numeric value, equal to, or lower than $param";
693
- break;
694
- case 'validate_min_age':
695
- $resp[$field] = "The $field field needs to have an age greater than or equal to $param";
696
- break;
697
- default:
698
- $resp[$field] = "The $field field is invalid";
699
- }
700
- }
701
-
702
- return $resp;
703
- }
704
-
705
- /**
706
- * Filter the input data according to the specified filter set.
707
- *
708
- * @param mixed $input
709
- * @param array $filterset
710
- *
711
- * @throws Exception
712
- *
713
- * @return mixed
714
- *
715
- * @throws Exception
716
- */
717
- public function filter(array $input, array $filterset)
718
- {
719
- foreach ($filterset as $field => $filters) {
720
- if (!array_key_exists($field, $input)) {
721
- continue;
722
- }
723
-
724
- $filters = explode('|', $filters);
725
-
726
- foreach ($filters as $filter) {
727
- $params = null;
728
-
729
- if (strstr($filter, ',') !== false) {
730
- $filter = explode(',', $filter);
731
-
732
- $params = array_slice($filter, 1, count($filter) - 1);
733
-
734
- $filter = $filter[0];
735
- }
736
-
737
- if (is_callable(array($this, 'filter_'.$filter))) {
738
- $method = 'filter_'.$filter;
739
- $input[$field] = $this->$method($input[$field], $params);
740
- } elseif (function_exists($filter)) {
741
- $input[$field] = $filter($input[$field]);
742
- } elseif (isset(self::$filter_methods[$filter])) {
743
- $input[$field] = call_user_func(self::$filter_methods[$filter], $input[$field], $params);
744
- } else {
745
- throw new Exception("Filter method '$filter' does not exist.");
746
- }
747
- }
748
- }
749
-
750
- return $input;
751
- }
752
-
753
- // ** ------------------------- Filters --------------------------------------- ** //
754
-
755
- /**
756
- * Replace noise words in a string (http://tax.cchgroup.com/help/Avoiding_noise_words_in_your_search.htm).
757
- *
758
- * Usage: '<index>' => 'noise_words'
759
- *
760
- * @param string $value
761
- * @param array $params
762
- *
763
- * @return string
764
- */
765
- protected function filter_noise_words($value, $params = null)
766
- {
767
- $value = preg_replace('/\s\s+/u', chr(32), $value);
768
-
769
- $value = " $value ";
770
-
771
- $words = explode(',', self::$en_noise_words);
772
-
773
- foreach ($words as $word) {
774
- $word = trim($word);
775
-
776
- $word = " $word "; // Normalize
777
-
778
- if (stripos($value, $word) !== false) {
779
- $value = str_ireplace($word, chr(32), $value);
780
- }
781
- }
782
-
783
- return trim($value);
784
- }
785
-
786
- /**
787
- * Remove all known punctuation from a string.
788
- *
789
- * Usage: '<index>' => 'rmpunctuataion'
790
- *
791
- * @param string $value
792
- * @param array $params
793
- *
794
- * @return string
795
- */
796
- protected function filter_rmpunctuation($value, $params = null)
797
- {
798
- return preg_replace("/(?![.=$'€%-])\p{P}/u", '', $value);
799
- }
800
-
801
- /**
802
- * Translate an input string to a desired language [DEPRECIATED].
803
- *
804
- * Any ISO 639-1 2 character language code may be used
805
- *
806
- * See: http://www.science.co.il/language/Codes.asp?s=code2
807
- *
808
- * @param string $value
809
- * @param array $params
810
- *
811
- * @return string
812
- */
813
- /*
814
  protected function filter_translate($value, $params = NULL)
815
  {
816
  $input_lang = 'en';
@@ -851,1283 +829,1260 @@ class GUMP
851
  }
852
  */
853
 
854
- /**
855
- * Sanitize the string by removing any script tags.
856
- *
857
- * Usage: '<index>' => 'sanitize_string'
858
- *
859
- * @param string $value
860
- * @param array $params
861
- *
862
- * @return string
863
- */
864
- protected function filter_sanitize_string($value, $params = null)
865
- {
866
- return filter_var($value, FILTER_SANITIZE_STRING);
867
- }
868
-
869
- /**
870
- * Sanitize the string by urlencoding characters.
871
- *
872
- * Usage: '<index>' => 'urlencode'
873
- *
874
- * @param string $value
875
- * @param array $params
876
- *
877
- * @return string
878
- */
879
- protected function filter_urlencode($value, $params = null)
880
- {
881
- return filter_var($value, FILTER_SANITIZE_ENCODED);
882
- }
883
-
884
- /**
885
- * Sanitize the string by converting HTML characters to their HTML entities.
886
- *
887
- * Usage: '<index>' => 'htmlencode'
888
- *
889
- * @param string $value
890
- * @param array $params
891
- *
892
- * @return string
893
- */
894
- protected function filter_htmlencode($value, $params = null)
895
- {
896
- return filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS);
897
- }
898
-
899
- /**
900
- * Sanitize the string by removing illegal characters from emails.
901
- *
902
- * Usage: '<index>' => 'sanitize_email'
903
- *
904
- * @param string $value
905
- * @param array $params
906
- *
907
- * @return string
908
- */
909
- protected function filter_sanitize_email($value, $params = null)
910
- {
911
- return filter_var($value, FILTER_SANITIZE_EMAIL);
912
- }
913
-
914
- /**
915
- * Sanitize the string by removing illegal characters from numbers.
916
- *
917
- * @param string $value
918
- * @param array $params
919
- *
920
- * @return string
921
- */
922
- protected function filter_sanitize_numbers($value, $params = null)
923
- {
924
- return filter_var($value, FILTER_SANITIZE_NUMBER_INT);
925
- }
926
-
927
- /**
928
- * Sanitize the string by removing illegal characters from float numbers.
929
- *
930
- * @param string $value
931
- * @param array $params
932
- *
933
- * @return string
934
- */
935
- protected function filter_sanitize_floats($value, $params = null)
936
- {
937
- return filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
938
- }
939
-
940
- /**
941
- * Filter out all HTML tags except the defined basic tags.
942
- *
943
- * @param string $value
944
- * @param array $params
945
- *
946
- * @return string
947
- */
948
- protected function filter_basic_tags($value, $params = null)
949
- {
950
- return strip_tags($value, self::$basic_tags);
951
- }
952
-
953
- /**
954
- * Convert the provided numeric value to a whole number.
955
- *
956
- * @param string $value
957
- * @param array $params
958
- *
959
- * @return string
960
- */
961
- protected function filter_whole_number($value, $params = null)
962
- {
963
- return intval($value);
964
- }
965
-
966
- // ** ------------------------- Validators ------------------------------------ ** //
967
-
968
-
969
- /**
970
- * Verify that a value is contained within the pre-defined value set.
971
- *
972
- * Usage: '<index>' => 'contains,value value value'
973
- *
974
- * @param string $field
975
- * @param array $input
976
- * @param null $param
977
- *
978
- * @return mixed
979
- */
980
- protected function validate_contains($field, $input, $param = null)
981
- {
982
- if (!isset($input[$field])) {
983
- return;
984
- }
985
-
986
- $param = trim(strtolower($param));
987
-
988
- $value = trim(strtolower($input[$field]));
989
-
990
- if (preg_match_all('#\'(.+?)\'#', $param, $matches, PREG_PATTERN_ORDER)) {
991
- $param = $matches[1];
992
- } else {
993
- $param = explode(chr(32), $param);
994
- }
995
-
996
- if (in_array($value, $param)) { // valid, return nothing
997
- return;
998
- }
999
-
1000
- return array(
1001
- 'field' => $field,
1002
- 'value' => $value,
1003
- 'rule' => __FUNCTION__,
1004
- 'param' => $param,
1005
- );
1006
- }
1007
-
1008
- /**
1009
- * Verify that a value is contained within the pre-defined value set.
1010
- * OUTPUT: will NOT show the list of values.
1011
- *
1012
- * Usage: '<index>' => 'contains_list,value;value;value'
1013
- *
1014
- * @param string $field
1015
- * @param array $input
1016
- *
1017
- * @return mixed
1018
- */
1019
- protected function validate_contains_list($field, $input, $param = null)
1020
- {
1021
- $param = trim(strtolower($param));
1022
-
1023
- $value = trim(strtolower($input[$field]));
1024
-
1025
- $param = explode(';', $param);
1026
-
1027
- // consider: in_array(strtolower($value), array_map('strtolower', $param)
1028
-
1029
- if (in_array($value, $param)) { // valid, return nothing
1030
- return;
1031
- } else {
1032
- return array(
1033
- 'field' => $field,
1034
- 'value' => $value,
1035
- 'rule' => __FUNCTION__,
1036
- 'param' => $param,
1037
- );
1038
- }
1039
- }
1040
-
1041
- /**
1042
- * Verify that a value is NOT contained within the pre-defined value set.
1043
- * OUTPUT: will NOT show the list of values.
1044
- *
1045
- * Usage: '<index>' => 'doesnt_contain_list,value;value;value'
1046
- *
1047
- * @param string $field
1048
- * @param array $input
1049
- *
1050
- * @return mixed
1051
- */
1052
- protected function validate_doesnt_contain_list($field, $input, $param = null)
1053
- {
1054
- $param = trim(strtolower($param));
1055
-
1056
- $value = trim(strtolower($input[$field]));
1057
-
1058
- $param = explode(';', $param);
1059
-
1060
- if (!in_array($value, $param)) { // valid, return nothing
1061
- return;
1062
- } else {
1063
- return array(
1064
- 'field' => $field,
1065
- 'value' => $value,
1066
- 'rule' => __FUNCTION__,
1067
- 'param' => $param,
1068
- );
1069
- }
1070
- }
1071
-
1072
- /**
1073
- * Check if the specified key is present and not empty.
1074
- *
1075
- * Usage: '<index>' => 'required'
1076
- *
1077
- * @param string $field
1078
- * @param array $input
1079
- * @param null $param
1080
- *
1081
- * @return mixed
1082
- */
1083
- protected function validate_required($field, $input, $param = null)
1084
- {
1085
- if (isset($input[$field]) && ($input[$field] === false || $input[$field] === 0 || $input[$field] === 0.0 || $input[$field] === '0' || !empty($input[$field]))) {
1086
- return;
1087
- }
1088
-
1089
- return array(
1090
- 'field' => $field,
1091
- 'value' => null,
1092
- 'rule' => __FUNCTION__,
1093
- 'param' => $param,
1094
- );
1095
- }
1096
-
1097
- /**
1098
- * Determine if the provided email is valid.
1099
- *
1100
- * Usage: '<index>' => 'valid_email'
1101
- *
1102
- * @param string $field
1103
- * @param array $input
1104
- * @param null $param
1105
- *
1106
- * @return mixed
1107
- */
1108
- protected function validate_valid_email($field, $input, $param = null)
1109
- {
1110
- if (!isset($input[$field]) || empty($input[$field])) {
1111
- return;
1112
- }
1113
-
1114
- if (!filter_var($input[$field], FILTER_VALIDATE_EMAIL)) {
1115
- return array(
1116
- 'field' => $field,
1117
- 'value' => $input[$field],
1118
- 'rule' => __FUNCTION__,
1119
- 'param' => $param,
1120
- );
1121
- }
1122
- }
1123
-
1124
- /**
1125
- * Determine if the provided value length is less or equal to a specific value.
1126
- *
1127
- * Usage: '<index>' => 'max_len,240'
1128
- *
1129
- * @param string $field
1130
- * @param array $input
1131
- * @param null $param
1132
- *
1133
- * @return mixed
1134
- */
1135
- protected function validate_max_len($field, $input, $param = null)
1136
- {
1137
- if (!isset($input[$field])) {
1138
- return;
1139
- }
1140
-
1141
- if (function_exists('mb_strlen')) {
1142
- if (mb_strlen($input[$field]) <= (int) $param) {
1143
- return;
1144
- }
1145
- } else {
1146
- if (strlen($input[$field]) <= (int) $param) {
1147
- return;
1148
- }
1149
- }
1150
-
1151
- return array(
1152
- 'field' => $field,
1153
- 'value' => $input[$field],
1154
- 'rule' => __FUNCTION__,
1155
- 'param' => $param,
1156
- );
1157
- }
1158
-
1159
- /**
1160
- * Determine if the provided value length is more or equal to a specific value.
1161
- *
1162
- * Usage: '<index>' => 'min_len,4'
1163
- *
1164
- * @param string $field
1165
- * @param array $input
1166
- * @param null $param
1167
- *
1168
- * @return mixed
1169
- */
1170
- protected function validate_min_len($field, $input, $param = null)
1171
- {
1172
- if (!isset($input[$field])) {
1173
- return;
1174
- }
1175
-
1176
- if (function_exists('mb_strlen')) {
1177
- if (mb_strlen($input[$field]) >= (int) $param) {
1178
- return;
1179
- }
1180
- } else {
1181
- if (strlen($input[$field]) >= (int) $param) {
1182
- return;
1183
- }
1184
- }
1185
-
1186
- return array(
1187
- 'field' => $field,
1188
- 'value' => $input[$field],
1189
- 'rule' => __FUNCTION__,
1190
- 'param' => $param,
1191
- );
1192
- }
1193
-
1194
- /**
1195
- * Determine if the provided value length matches a specific value.
1196
- *
1197
- * Usage: '<index>' => 'exact_len,5'
1198
- *
1199
- * @param string $field
1200
- * @param array $input
1201
- * @param null $param
1202
- *
1203
- * @return mixed
1204
- */
1205
- protected function validate_exact_len($field, $input, $param = null)
1206
- {
1207
- if (!isset($input[$field])) {
1208
- return;
1209
- }
1210
-
1211
- if (function_exists('mb_strlen')) {
1212
- if (mb_strlen($input[$field]) == (int) $param) {
1213
- return;
1214
- }
1215
- } else {
1216
- if (strlen($input[$field]) == (int) $param) {
1217
- return;
1218
- }
1219
- }
1220
-
1221
- return array(
1222
- 'field' => $field,
1223
- 'value' => $input[$field],
1224
- 'rule' => __FUNCTION__,
1225
- 'param' => $param,
1226
- );
1227
- }
1228
-
1229
- /**
1230
- * Determine if the provided value contains only alpha characters.
1231
- *
1232
- * Usage: '<index>' => 'alpha'
1233
- *
1234
- * @param string $field
1235
- * @param array $input
1236
- * @param null $param
1237
- *
1238
- * @return mixed
1239
- */
1240
- protected function validate_alpha($field, $input, $param = null)
1241
- {
1242
- if (!isset($input[$field]) || empty($input[$field])) {
1243
- return;
1244
- }
1245
-
1246
- if (!preg_match('/^([a-zÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ])+$/i', $input[$field]) !== false) {
1247
- return array(
1248
- 'field' => $field,
1249
- 'value' => $input[$field],
1250
- 'rule' => __FUNCTION__,
1251
- 'param' => $param,
1252
- );
1253
- }
1254
- }
1255
-
1256
- /**
1257
- * Determine if the provided value contains only alpha-numeric characters.
1258
- *
1259
- * Usage: '<index>' => 'alpha_numeric'
1260
- *
1261
- * @param string $field
1262
- * @param array $input
1263
- * @param null $param
1264
- *
1265
- * @return mixed
1266
- */
1267
- protected function validate_alpha_numeric($field, $input, $param = null)
1268
- {
1269
- if (!isset($input[$field]) || empty($input[$field])) {
1270
- return;
1271
- }
1272
-
1273
- if (!preg_match('/^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ])+$/i', $input[$field]) !== false) {
1274
- return array(
1275
- 'field' => $field,
1276
- 'value' => $input[$field],
1277
- 'rule' => __FUNCTION__,
1278
- 'param' => $param,
1279
- );
1280
- }
1281
- }
1282
-
1283
- /**
1284
- * Determine if the provided value contains only alpha characters with dashed and underscores.
1285
- *
1286
- * Usage: '<index>' => 'alpha_dash'
1287
- *
1288
- * @param string $field
1289
- * @param array $input
1290
- * @param null $param
1291
- *
1292
- * @return mixed
1293
- */
1294
- protected function validate_alpha_dash($field, $input, $param = null)
1295
- {
1296
- if (!isset($input[$field]) || empty($input[$field])) {
1297
- return;
1298
- }
1299
-
1300
- if (!preg_match('/^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ_-])+$/i', $input[$field]) !== false) {
1301
- return array(
1302
- 'field' => $field,
1303
- 'value' => $input[$field],
1304
- 'rule' => __FUNCTION__,
1305
- 'param' => $param,
1306
- );
1307
- }
1308
- }
1309
-
1310
- /**
1311
- * Determine if the provided value contains only alpha numeric characters with spaces.
1312
- *
1313
- * Usage: '<index>' => 'alpha_space'
1314
- *
1315
- * @param string $field
1316
- * @param array $input
1317
- * @param null $param
1318
- *
1319
- * @return mixed
1320
- */
1321
- protected function validate_alpha_space($field, $input, $param = null)
1322
- {
1323
- if (!isset($input[$field]) || empty($input[$field])) {
1324
- return;
1325
- }
1326
-
1327
- if (!preg_match("/^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ\s])+$/i", $input[$field]) !== false) {
1328
- return array(
1329
- 'field' => $field,
1330
- 'value' => $input[$field],
1331
- 'rule' => __FUNCTION__,
1332
- 'param' => $param,
1333
- );
1334
- }
1335
- }
1336
-
1337
- /**
1338
- * Determine if the provided value is a valid number or numeric string.
1339
- *
1340
- * Usage: '<index>' => 'numeric'
1341
- *
1342
- * @param string $field
1343
- * @param array $input
1344
- * @param null $param
1345
- *
1346
- * @return mixed
1347
- */
1348
- protected function validate_numeric($field, $input, $param = null)
1349
- {
1350
- if (!isset($input[$field]) || empty($input[$field])) {
1351
- return;
1352
- }
1353
-
1354
- if (!is_numeric($input[$field])) {
1355
- return array(
1356
- 'field' => $field,
1357
- 'value' => $input[$field],
1358
- 'rule' => __FUNCTION__,
1359
- 'param' => $param,
1360
- );
1361
- }
1362
- }
1363
-
1364
- /**
1365
- * Determine if the provided value is a valid integer.
1366
- *
1367
- * Usage: '<index>' => 'integer'
1368
- *
1369
- * @param string $field
1370
- * @param array $input
1371
- * @param null $param
1372
- *
1373
- * @return mixed
1374
- */
1375
- protected function validate_integer($field, $input, $param = null)
1376
- {
1377
- if (!isset($input[$field]) || empty($input[$field])) {
1378
- return;
1379
- }
1380
-
1381
- if (filter_var($input[$field], FILTER_VALIDATE_INT) === false) {
1382
- return array(
1383
- 'field' => $field,
1384
- 'value' => $input[$field],
1385
- 'rule' => __FUNCTION__,
1386
- 'param' => $param,
1387
- );
1388
- }
1389
- }
1390
-
1391
- /**
1392
- * Determine if the provided value is a PHP accepted boolean.
1393
- *
1394
- * Usage: '<index>' => 'boolean'
1395
- *
1396
- * @param string $field
1397
- * @param array $input
1398
- * @param null $param
1399
- *
1400
- * @return mixed
1401
- */
1402
- protected function validate_boolean($field, $input, $param = null)
1403
- {
1404
- if (!isset($input[$field]) || empty($input[$field]) && $input[$field] !== 0) {
1405
- return;
1406
- }
1407
-
1408
- if($input[$field] === true || $input[$field] === false) {
1409
- return;
1410
- }
1411
-
1412
- return array(
1413
- 'field' => $field,
1414
- 'value' => $input[$field],
1415
- 'rule' => __FUNCTION__,
1416
- 'param' => $param,
1417
- );
1418
- }
1419
-
1420
- /**
1421
- * Determine if the provided value is a valid float.
1422
- *
1423
- * Usage: '<index>' => 'float'
1424
- *
1425
- * @param string $field
1426
- * @param array $input
1427
- * @param null $param
1428
- *
1429
- * @return mixed
1430
- */
1431
- protected function validate_float($field, $input, $param = null)
1432
- {
1433
- if (!isset($input[$field]) || empty($input[$field])) {
1434
- return;
1435
- }
1436
-
1437
- if (filter_var($input[$field], FILTER_VALIDATE_FLOAT) === false) {
1438
- return array(
1439
- 'field' => $field,
1440
- 'value' => $input[$field],
1441
- 'rule' => __FUNCTION__,
1442
- 'param' => $param,
1443
- );
1444
- }
1445
- }
1446
-
1447
- /**
1448
- * Determine if the provided value is a valid URL.
1449
- *
1450
- * Usage: '<index>' => 'valid_url'
1451
- *
1452
- * @param string $field
1453
- * @param array $input
1454
- * @param null $param
1455
- *
1456
- * @return mixed
1457
- */
1458
- protected function validate_valid_url($field, $input, $param = null)
1459
- {
1460
- if (!isset($input[$field]) || empty($input[$field])) {
1461
- return;
1462
- }
1463
-
1464
- if (!filter_var($input[$field], FILTER_VALIDATE_URL)) {
1465
- return array(
1466
- 'field' => $field,
1467
- 'value' => $input[$field],
1468
- 'rule' => __FUNCTION__,
1469
- 'param' => $param,
1470
- );
1471
- }
1472
- }
1473
-
1474
- /**
1475
- * Determine if a URL exists & is accessible.
1476
- *
1477
- * Usage: '<index>' => 'url_exists'
1478
- *
1479
- * @param string $field
1480
- * @param array $input
1481
- * @param null $param
1482
- *
1483
- * @return mixed
1484
- */
1485
- protected function validate_url_exists($field, $input, $param = null)
1486
- {
1487
- if (!isset($input[$field]) || empty($input[$field])) {
1488
- return;
1489
- }
1490
-
1491
- $url = parse_url(strtolower($input[$field]));
1492
-
1493
- if (isset($url['host'])) {
1494
- $url = $url['host'];
1495
- }
1496
-
1497
- if (function_exists('checkdnsrr')) {
1498
- if (checkdnsrr($url) === false) {
1499
- return array(
1500
- 'field' => $field,
1501
- 'value' => $input[$field],
1502
- 'rule' => __FUNCTION__,
1503
- 'param' => $param,
1504
- );
1505
- }
1506
- } else {
1507
- if (gethostbyname($url) == $url) {
1508
- return array(
1509
- 'field' => $field,
1510
- 'value' => $input[$field],
1511
- 'rule' => __FUNCTION__,
1512
- 'param' => $param,
1513
- );
1514
- }
1515
- }
1516
- }
1517
-
1518
- /**
1519
- * Determine if the provided value is a valid IP address.
1520
- *
1521
- * Usage: '<index>' => 'valid_ip'
1522
- *
1523
- * @param string $field
1524
- * @param array $input
1525
- *
1526
- * @return mixed
1527
- */
1528
- protected function validate_valid_ip($field, $input, $param = null)
1529
- {
1530
- if (!isset($input[$field]) || empty($input[$field])) {
1531
- return;
1532
- }
1533
-
1534
- if (!filter_var($input[$field], FILTER_VALIDATE_IP) !== false) {
1535
- return array(
1536
- 'field' => $field,
1537
- 'value' => $input[$field],
1538
- 'rule' => __FUNCTION__,
1539
- 'param' => $param,
1540
- );
1541
- }
1542
- }
1543
-
1544
- /**
1545
- * Determine if the provided value is a valid IPv4 address.
1546
- *
1547
- * Usage: '<index>' => 'valid_ipv4'
1548
- *
1549
- * @param string $field
1550
- * @param array $input
1551
- *
1552
- * @return mixed
1553
- *
1554
- * @see http://pastebin.com/UvUPPYK0
1555
- */
1556
-
1557
- /*
1558
  * What about private networks? http://en.wikipedia.org/wiki/Private_network
1559
  * What about loop-back address? 127.0.0.1
1560
  */
1561
- protected function validate_valid_ipv4($field, $input, $param = null)
1562
- {
1563
- if (!isset($input[$field]) || empty($input[$field])) {
1564
- return;
1565
- }
1566
-
1567
- if (!filter_var($input[$field], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
1568
- // removed !== FALSE
1569
-
1570
- return array(
1571
- 'field' => $field,
1572
- 'value' => $input[$field],
1573
- 'rule' => __FUNCTION__,
1574
- 'param' => $param,
1575
- );
1576
- }
1577
- }
1578
-
1579
- /**
1580
- * Determine if the provided value is a valid IPv6 address.
1581
- *
1582
- * Usage: '<index>' => 'valid_ipv6'
1583
- *
1584
- * @param string $field
1585
- * @param array $input
1586
- *
1587
- * @return mixed
1588
- */
1589
- protected function validate_valid_ipv6($field, $input, $param = null)
1590
- {
1591
- if (!isset($input[$field]) || empty($input[$field])) {
1592
- return;
1593
- }
1594
-
1595
- if (!filter_var($input[$field], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
1596
- return array(
1597
- 'field' => $field,
1598
- 'value' => $input[$field],
1599
- 'rule' => __FUNCTION__,
1600
- 'param' => $param,
1601
- );
1602
- }
1603
- }
1604
-
1605
- /**
1606
- * Determine if the input is a valid credit card number.
1607
- *
1608
- * See: http://stackoverflow.com/questions/174730/what-is-the-best-way-to-validate-a-credit-card-in-php
1609
- * Usage: '<index>' => 'valid_cc'
1610
- *
1611
- * @param string $field
1612
- * @param array $input
1613
- *
1614
- * @return mixed
1615
- */
1616
- protected function validate_valid_cc($field, $input, $param = null)
1617
- {
1618
- if (!isset($input[$field]) || empty($input[$field])) {
1619
- return;
1620
- }
1621
-
1622
- $number = preg_replace('/\D/', '', $input[$field]);
1623
-
1624
- if (function_exists('mb_strlen')) {
1625
- $number_length = mb_strlen($number);
1626
- } else {
1627
- $number_length = strlen($number);
1628
- }
1629
-
1630
- $parity = $number_length % 2;
1631
-
1632
- $total = 0;
1633
-
1634
- for ($i = 0; $i < $number_length; ++$i) {
1635
- $digit = $number[$i];
1636
-
1637
- if ($i % 2 == $parity) {
1638
- $digit *= 2;
1639
-
1640
- if ($digit > 9) {
1641
- $digit -= 9;
1642
- }
1643
- }
1644
-
1645
- $total += $digit;
1646
- }
1647
-
1648
- if ($total % 10 == 0) {
1649
- return; // Valid
1650
- }
1651
-
1652
- return array(
1653
- 'field' => $field,
1654
- 'value' => $input[$field],
1655
- 'rule' => __FUNCTION__,
1656
- 'param' => $param,
1657
- );
1658
- }
1659
-
1660
- /**
1661
- * Determine if the input is a valid human name [Credits to http://github.com/ben-s].
1662
- *
1663
- * See: https://github.com/Wixel/GUMP/issues/5
1664
- * Usage: '<index>' => 'valid_name'
1665
- *
1666
- * @param string $field
1667
- * @param array $input
1668
- *
1669
- * @return mixed
1670
- */
1671
- protected function validate_valid_name($field, $input, $param = null)
1672
- {
1673
- if (!isset($input[$field]) || empty($input[$field])) {
1674
- return;
1675
- }
1676
-
1677
- if (!preg_match("/^([a-zÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïñðòóôõöùúûüýÿ '-])+$/i", $input[$field]) !== false) {
1678
- return array(
1679
- 'field' => $field,
1680
- 'value' => $input[$field],
1681
- 'rule' => __FUNCTION__,
1682
- 'param' => $param,
1683
- );
1684
- }
1685
- }
1686
-
1687
- /**
1688
- * Determine if the provided input is likely to be a street address using weak detection.
1689
- *
1690
- * Usage: '<index>' => 'street_address'
1691
- *
1692
- * @param string $field
1693
- * @param array $input
1694
- *
1695
- * @return mixed
1696
- */
1697
- protected function validate_street_address($field, $input, $param = null)
1698
- {
1699
- if (!isset($input[$field]) || empty($input[$field])) {
1700
- return;
1701
- }
1702
-
1703
- // Theory: 1 number, 1 or more spaces, 1 or more words
1704
- $hasLetter = preg_match('/[a-zA-Z]/', $input[$field]);
1705
- $hasDigit = preg_match('/\d/', $input[$field]);
1706
- $hasSpace = preg_match('/\s/', $input[$field]);
1707
-
1708
- $passes = $hasLetter && $hasDigit && $hasSpace;
1709
-
1710
- if (!$passes) {
1711
- return array(
1712
- 'field' => $field,
1713
- 'value' => $input[$field],
1714
- 'rule' => __FUNCTION__,
1715
- 'param' => $param,
1716
- );
1717
- }
1718
- }
1719
-
1720
- /**
1721
- * Determine if the provided value is a valid IBAN.
1722
- *
1723
- * Usage: '<index>' => 'iban'
1724
- *
1725
- * @param string $field
1726
- * @param array $input
1727
- *
1728
- * @return mixed
1729
- */
1730
- protected function validate_iban($field, $input, $param = null)
1731
- {
1732
- if (!isset($input[$field]) || empty($input[$field])) {
1733
- return;
1734
- }
1735
-
1736
- static $character = array(
1737
- 'A' => 10, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15, 'G' => 16,
1738
- 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'M' => 22,
1739
- 'N' => 23, 'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28,
1740
- 'T' => 29, 'U' => 30, 'V' => 31, 'W' => 32, 'X' => 33, 'Y' => 34,
1741
- 'Z' => 35, 'B' => 11
1742
- );
1743
-
1744
- if (!preg_match("/\A[A-Z]{2}\d{2} ?[A-Z\d]{4}( ?\d{4}){1,} ?\d{1,4}\z/", $input[$field])) {
1745
- return array(
1746
- 'field' => $field,
1747
- 'value' => $input[$field],
1748
- 'rule' => __FUNCTION__,
1749
- 'param' => $param,
1750
- );
1751
- }
1752
-
1753
- $iban = str_replace(' ', '', $input[$field]);
1754
- $iban = substr($iban, 4).substr($iban, 0, 4);
1755
- $iban = strtr($iban, $character);
1756
-
1757
- if (bcmod($iban, 97) != 1) {
1758
- return array(
1759
- 'field' => $field,
1760
- 'value' => $input[$field],
1761
- 'rule' => __FUNCTION__,
1762
- 'param' => $param,
1763
- );
1764
- }
1765
- }
1766
-
1767
- /**
1768
- * Determine if the provided input is a valid date (ISO 8601).
1769
- *
1770
- * Usage: '<index>' => 'date'
1771
- *
1772
- * @param string $field
1773
- * @param string $input date ('Y-m-d') or datetime ('Y-m-d H:i:s')
1774
- * @param null $param
1775
- *
1776
- * @return mixed
1777
- */
1778
- protected function validate_date($field, $input, $param = null)
1779
- {
1780
- if (!isset($input[$field]) || empty($input[$field])) {
1781
- return;
1782
- }
1783
-
1784
- $cdate1 = date('Y-m-d', strtotime($input[$field]));
1785
- $cdate2 = date('Y-m-d H:i:s', strtotime($input[$field]));
1786
-
1787
- if ($cdate1 != $input[$field] && $cdate2 != $input[$field]) {
1788
- return array(
1789
- 'field' => $field,
1790
- 'value' => $input[$field],
1791
- 'rule' => __FUNCTION__,
1792
- 'param' => $param,
1793
- );
1794
- }
1795
- }
1796
-
1797
- /**
1798
- * Determine if the provided input meets age requirement (ISO 8601).
1799
- *
1800
- * Usage: '<index>' => 'min_age,13'
1801
- *
1802
- * @param string $field
1803
- * @param string $input date ('Y-m-d') or datetime ('Y-m-d H:i:s')
1804
- * @param string $param int
1805
- *
1806
- * @return mixed
1807
- */
1808
- protected function validate_min_age($field, $input, $param = null)
1809
- {
1810
- if (!isset($input[$field]) || empty($input[$field])) {
1811
- return;
1812
- }
1813
-
1814
- $cdate1 = new DateTime(date('Y-m-d', strtotime($input[$field])));
1815
- $today = new DateTime(date('d-m-Y'));
1816
-
1817
- $interval = $cdate1->diff($today);
1818
- $age = $interval->y;
1819
-
1820
- if ($age <= $param) {
1821
- return array(
1822
- 'field' => $field,
1823
- 'value' => $input[$field],
1824
- 'rule' => __FUNCTION__,
1825
- 'param' => $param,
1826
- );
1827
- }
1828
- }
1829
-
1830
- /**
1831
- * Determine if the provided numeric value is lower or equal to a specific value.
1832
- *
1833
- * Usage: '<index>' => 'max_numeric,50'
1834
- *
1835
- * @param string $field
1836
- * @param array $input
1837
- * @param null $param
1838
- *
1839
- * @return mixed
1840
- */
1841
- protected function validate_max_numeric($field, $input, $param = null)
1842
- {
1843
- if (!isset($input[$field]) || empty($input[$field])) {
1844
- return;
1845
- }
1846
-
1847
- if (is_numeric($input[$field]) && is_numeric($param) && ($input[$field] <= $param)) {
1848
- return;
1849
- }
1850
-
1851
- return array(
1852
- 'field' => $field,
1853
- 'value' => $input[$field],
1854
- 'rule' => __FUNCTION__,
1855
- 'param' => $param,
1856
- );
1857
- }
1858
-
1859
- /**
1860
- * Determine if the provided numeric value is higher or equal to a specific value.
1861
- *
1862
- * Usage: '<index>' => 'min_numeric,1'
1863
- *
1864
- * @param string $field
1865
- * @param array $input
1866
- * @param null $param
1867
- * @return mixed
1868
- */
1869
- protected function validate_min_numeric($field, $input, $param = null)
1870
- {
1871
- if (!isset($input[$field])) {
1872
- return;
1873
- }
1874
-
1875
- if (is_numeric($input[$field]) && is_numeric($param) && ($input[$field] >= $param)) {
1876
- return;
1877
- }
1878
-
1879
- return array(
1880
- 'field' => $field,
1881
- 'value' => $input[$field],
1882
- 'rule' => __FUNCTION__,
1883
- 'param' => $param,
1884
- );
1885
- }
1886
-
1887
- /**
1888
- * Determine if the provided value starts with param.
1889
- *
1890
- * Usage: '<index>' => 'starts,Z'
1891
- *
1892
- * @param string $field
1893
- * @param array $input
1894
- *
1895
- * @return mixed
1896
- */
1897
- protected function validate_starts($field, $input, $param = null)
1898
- {
1899
- if (!isset($input[$field]) || empty($input[$field])) {
1900
- return;
1901
- }
1902
-
1903
- if (strpos($input[$field], $param) !== 0) {
1904
- return array(
1905
- 'field' => $field,
1906
- 'value' => $input[$field],
1907
- 'rule' => __FUNCTION__,
1908
- 'param' => $param,
1909
- );
1910
- }
1911
- }
1912
-
1913
- /**
1914
- * checks if a file was uploaded.
1915
- *
1916
- * Usage: '<index>' => 'required_file'
1917
- *
1918
- * @param string $field
1919
- * @param array $input
1920
- *
1921
- * @return mixed
1922
- */
1923
- protected function validate_required_file($field, $input, $param = null)
1924
- {
1925
- if ($input[$field]['error'] !== 4) {
1926
- return;
1927
- }
1928
-
1929
- return array(
1930
- 'field' => $field,
1931
- 'value' => $input[$field],
1932
- 'rule' => __FUNCTION__,
1933
- 'param' => $param,
1934
- );
1935
- }
1936
-
1937
- /**
1938
- * check the uploaded file for extension
1939
- * for now checks onlt the ext should add mime type check.
1940
- *
1941
- * Usage: '<index>' => 'starts,Z'
1942
- *
1943
- * @param string $field
1944
- * @param array $input
1945
- *
1946
- * @return mixed
1947
- */
1948
- protected function validate_extension($field, $input, $param = null)
1949
- {
1950
- if ($input[$field]['error'] !== 4) {
1951
- $param = trim(strtolower($param));
1952
- $allowed_extensions = explode(';', $param);
1953
-
1954
- $path_info = pathinfo($input[$field]['name']);
1955
- $extension = $path_info['extension'];
1956
-
1957
- if (in_array($extension, $allowed_extensions)) {
1958
- return;
1959
- }
1960
-
1961
- return array(
1962
- 'field' => $field,
1963
- 'value' => $input[$field],
1964
- 'rule' => __FUNCTION__,
1965
- 'param' => $param,
1966
- );
1967
- }
1968
- }
1969
-
1970
- /**
1971
- * Determine if the provided field value equals current field value.
1972
- *
1973
- * Usage: '<index>' => 'equalsfield,Z'
1974
- *
1975
- * @param string $field
1976
- * @param string $input
1977
- * @param string $param field to compare with
1978
- *
1979
- * @return mixed
1980
- */
1981
- protected function validate_equalsfield($field, $input, $param = null)
1982
- {
1983
- if (!isset($input[$field]) || empty($input[$field])) {
1984
- return;
1985
- }
1986
-
1987
- if ($input[$field] == $input[$param]) {
1988
- return;
1989
- }
1990
-
1991
- return array(
1992
- 'field' => $field,
1993
- 'value' => $input[$field],
1994
- 'rule' => __FUNCTION__,
1995
- 'param' => $param,
1996
- );
1997
- }
1998
-
1999
- /**
2000
- * Determine if the provided field value is a valid GUID (v4)
2001
- *
2002
- * Usage: '<index>' => 'guidv4'
2003
- *
2004
- * @param string $field
2005
- * @param string $input
2006
- * @param string $param field to compare with
2007
- * @return mixed
2008
- */
2009
- protected function validate_guidv4($field, $input, $param = null)
2010
- {
2011
- if (!isset($input[$field]) || empty($input[$field])) {
2012
- return;
2013
- }
2014
-
2015
- if (preg_match("/\{?[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}\}?$/", $input[$field])) {
2016
- return;
2017
- }
2018
-
2019
- return array(
2020
- 'field' => $field,
2021
- 'value' => $input[$field],
2022
- 'rule' => __FUNCTION__,
2023
- 'param' => $param,
2024
- );
2025
- }
2026
-
2027
- /**
2028
- * Trims whitespace only when the value is a scalar.
2029
- *
2030
- * @param mixed $value
2031
- *
2032
- * @return mixed
2033
- */
2034
- private function trimScalar($value)
2035
- {
2036
- if (is_scalar($value)) {
2037
- $value = trim($value);
2038
- }
2039
-
2040
- return $value;
2041
- }
2042
-
2043
- /**
2044
- * Determine if the provided value is a valid phone number.
2045
- *
2046
- * Usage: '<index>' => 'phone_number'
2047
- *
2048
- * @param string $field
2049
- * @param array $input
2050
- *
2051
- * @return mixed
2052
- *
2053
- * Examples:
2054
- *
2055
- * 555-555-5555: valid
2056
- * 5555425555: valid
2057
- * 555 555 5555: valid
2058
- * 1(519) 555-4444: valid
2059
- * 1 (519) 555-4422: valid
2060
- * 1-555-555-5555: valid
2061
- * 1-(555)-555-5555: valid
2062
- */
2063
- protected function validate_phone_number($field, $input, $param = null)
2064
- {
2065
- if (!isset($input[$field]) || empty($input[$field])) {
2066
- return;
2067
- }
2068
-
2069
- $regex = '/^(\d[\s-]?)?[\(\[\s-]{0,2}?\d{3}[\)\]\s-]{0,2}?\d{3}[\s-]?\d{4}$/i';
2070
- if (!preg_match($regex, $input[$field])) {
2071
- return array(
2072
- 'field' => $field,
2073
- 'value' => $input[$field],
2074
- 'rule' => __FUNCTION__,
2075
- 'param' => $param,
2076
- );
2077
- }
2078
- }
2079
-
2080
- /**
2081
- * Custom regex validator.
2082
- *
2083
- * Usage: '<index>' => 'regex,/your-regex-expression/'
2084
- *
2085
- * @param string $field
2086
- * @param array $input
2087
- *
2088
- * @return mixed
2089
- */
2090
- protected function validate_regex($field, $input, $param = null)
2091
- {
2092
- if (!isset($input[$field]) || empty($input[$field])) {
2093
- return;
2094
- }
2095
-
2096
- $regex = $param;
2097
- if (!preg_match($regex, $input[$field])) {
2098
- return array(
2099
- 'field' => $field,
2100
- 'value' => $input[$field],
2101
- 'rule' => __FUNCTION__,
2102
- 'param' => $param,
2103
- );
2104
- }
2105
- }
2106
-
2107
- /**
2108
- * Json validatior.
2109
- *
2110
- * Usage: '<index>' => 'valid_json_string'
2111
- *
2112
- * @param string $field
2113
- * @param array $input
2114
- *
2115
- * @return mixed
2116
- */
2117
- protected function validate_valid_json_string($field, $input, $param = null)
2118
- {
2119
- if (!isset($input[$field]) || empty($input[$field])) {
2120
- return;
2121
- }
2122
-
2123
- if (!is_string($input[$field]) || !is_object(json_decode($input[$field]))) {
2124
- return array(
2125
- 'field' => $field,
2126
- 'value' => $input[$field],
2127
- 'rule' => __FUNCTION__,
2128
- 'param' => $param,
2129
- );
2130
- }
2131
- }
2132
- } // EOC
 
 
 
 
2133
  }
10
  *
11
  * @version 1.4
12
  */
13
+ if ( ! class_exists( 'GUMP', false ) ) {
14
+ class GUMP {
15
+ //Singleton instance of GUMP
16
+ protected static $instance = null;
 
17
 
18
+ // Validation rules for execution
19
+ protected $validation_rules = array();
20
 
21
+ // Filter rules for execution
22
+ protected $filter_rules = array();
23
 
24
+ // Instance attribute containing errors from last run
25
+ protected $errors = array();
26
 
27
+ // Contain readable field names that have been set manually
28
+ protected static $fields = array();
29
 
30
+ // Custom validation methods
31
+ protected static $validation_methods = array();
32
 
33
+ // Customer filter methods
34
+ protected static $filter_methods = array();
35
 
36
+ // ** ------------------------- Instance Helper ---------------------------- ** //
 
 
 
 
 
37
 
38
+ /**
39
+ * Function to create and return previously created instance
40
+ *
41
+ * @return GUMP
42
+ */
 
 
43
 
44
+ public static function get_instance() {
45
+ if ( self::$instance === null ) {
46
+ self::$instance = new self();
47
+ }
48
 
49
+ return self::$instance;
50
+ }
51
 
 
52
 
53
+ // ** ------------------------- Validation Data ------------------------------- ** //
54
 
55
+ public static $basic_tags = '<br><p><a><strong><b><i><em><img><blockquote><code><dd><dl><hr><h1><h2><h3><h4><h5><h6><label><ul><li><span><sub><sup>';
56
+
57
+ public static $en_noise_words = "about,after,all,also,an,and,another,any,are,as,at,be,because,been,before,
58
  being,between,both,but,by,came,can,come,could,did,do,each,for,from,get,
59
  got,has,had,he,have,her,here,him,himself,his,how,if,in,into,is,it,its,it's,like,
60
  make,many,me,might,more,most,much,must,my,never,now,of,on,only,or,other,
63
  very,was,way,we,well,were,what,where,which,while,who,with,would,you,your,a,
64
  b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,$,1,2,3,4,5,6,7,8,9,0,_";
65
 
66
+ // field characters below will be replaced with a space.
67
+ protected $fieldCharsToRemove = array( '_', '-' );
68
+
69
+ // ** ------------------------- Validation Helpers ---------------------------- ** //
70
+
71
+ /**
72
+ * Shorthand method for inline validation.
73
+ *
74
+ * @param array $data The data to be validated
75
+ * @param array $validators The GUMP validators
76
+ *
77
+ * @return mixed True(boolean) or the array of error messages
78
+ */
79
+ public static function is_valid( array $data, array $validators ) {
80
+ $gump = self::get_instance();
81
+
82
+ $gump->validation_rules( $validators );
83
+
84
+ if ( $gump->run( $data ) === false ) {
85
+ return $gump->get_readable_errors( false );
86
+ } else {
87
+ return true;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Shorthand method for running only the data filters.
93
+ *
94
+ * @param array $data
95
+ * @param array $filters
96
+ *
97
+ * @return mixed
98
+ */
99
+ public static function filter_input( array $data, array $filters ) {
100
+ $gump = self::get_instance();
101
+
102
+ return $gump->filter( $data, $filters );
103
+ }
104
+
105
+ /**
106
+ * Magic method to generate the validation error messages.
107
+ *
108
+ * @return string
109
+ */
110
+ public function __toString() {
111
+ return $this->get_readable_errors( true );
112
+ }
113
+
114
+ /**
115
+ * Perform XSS clean to prevent cross site scripting.
116
+ *
117
+ * @static
118
+ *
119
+ * @param array $data
120
+ *
121
+ * @return array
122
+ */
123
+ public static function xss_clean( array $data ) {
124
+ foreach ( $data as $k => $v ) {
125
+ $data[ $k ] = filter_var( $v, FILTER_SANITIZE_STRING );
126
+ }
127
+
128
+ return $data;
129
+ }
130
+
131
+ /**
132
+ * Adds a custom validation rule using a callback function.
133
+ *
134
+ * @param string $rule
135
+ * @param callable $callback
136
+ *
137
+ * @return bool
138
+ *
139
+ * @throws Exception
140
+ */
141
+ public static function add_validator( $rule, $callback ) {
142
+ $method = 'validate_' . $rule;
143
+
144
+ if ( method_exists( __CLASS__, $method ) || isset( self::$validation_methods[ $rule ] ) ) {
145
+ throw new Exception( "Validator rule '$rule' already exists." );
146
+ }
147
+
148
+ self::$validation_methods[ $rule ] = $callback;
149
+
150
+ return true;
151
+ }
152
+
153
+ /**
154
+ * Adds a custom filter using a callback function.
155
+ *
156
+ * @param string $rule
157
+ * @param callable $callback
158
+ *
159
+ * @return bool
160
+ *
161
+ * @throws Exception
162
+ */
163
+ public static function add_filter( $rule, $callback ) {
164
+ $method = 'filter_' . $rule;
165
+
166
+ if ( method_exists( __CLASS__, $method ) || isset( self::$filter_methods[ $rule ] ) ) {
167
+ throw new Exception( "Filter rule '$rule' already exists." );
168
+ }
169
+
170
+ self::$filter_methods[ $rule ] = $callback;
171
+
172
+ return true;
173
+ }
174
+
175
+ /**
176
+ * Helper method to extract an element from an array safely
177
+ *
178
+ * @param mixed $key
179
+ * @param array $array
180
+ * @param mixed $default
181
+ *
182
+ * @return mixed
183
+ */
184
+ public static function field( $key, array $array, $default = null ) {
185
+ if ( ! is_array( $array ) ) {
186
+ return null;
187
+ }
188
+
189
+ if ( isset( $array[ $key ] ) ) {
190
+ return $array[ $key ];
191
+ } else {
192
+ return $default;
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Getter/Setter for the validation rules.
198
+ *
199
+ * @param array $rules
200
+ *
201
+ * @return array
202
+ */
203
+ public function validation_rules( array $rules = array() ) {
204
+ if ( empty( $rules ) ) {
205
+ return $this->validation_rules;
206
+ }
207
+
208
+ $this->validation_rules = $rules;
209
+ }
210
+
211
+ /**
212
+ * Getter/Setter for the filter rules.
213
+ *
214
+ * @param array $rules
215
+ *
216
+ * @return array
217
+ */
218
+ public function filter_rules( array $rules = array() ) {
219
+ if ( empty( $rules ) ) {
220
+ return $this->filter_rules;
221
+ }
222
+
223
+ $this->filter_rules = $rules;
224
+ }
225
+
226
+ /**
227
+ * Run the filtering and validation after each other.
228
+ *
229
+ * @param array $data
230
+ * @param bool $check_fields
231
+ *
232
+ * @return array
233
+ *
234
+ * @throws Exception
235
+ */
236
+ public function run( array $data, $check_fields = false ) {
237
+ $data = $this->filter( $data, $this->filter_rules() );
238
+
239
+ $validated = $this->validate(
240
+ $data, $this->validation_rules()
241
+ );
242
+
243
+ if ( $check_fields === true ) {
244
+ $this->check_fields( $data );
245
+ }
246
+
247
+ if ( $validated !== true ) {
248
+ return false;
249
+ }
250
+
251
+ return $data;
252
+ }
253
+
254
+ /**
255
+ * Ensure that the field counts match the validation rule counts.
256
+ *
257
+ * @param array $data
258
+ */
259
+ private function check_fields( array $data ) {
260
+ $ruleset = $this->validation_rules();
261
+ $mismatch = array_diff_key( $data, $ruleset );
262
+ $fields = array_keys( $mismatch );
263
+
264
+ foreach ( $fields as $field ) {
265
+ $this->errors[] = array(
266
+ 'field' => $field,
267
+ 'value' => $data[ $field ],
268
+ 'rule' => 'mismatch',
269
+ 'param' => null,
270
+ );
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Sanitize the input data.
276
+ *
277
+ * @param array $input
278
+ * @param null $fields
279
+ * @param bool $utf8_encode
280
+ *
281
+ * @return array
282
+ */
283
+ public function sanitize( array $input, array $fields = array(), $utf8_encode = true ) {
284
+ $magic_quotes = (bool) get_magic_quotes_gpc();
285
+
286
+ if ( empty( $fields ) ) {
287
+ $fields = array_keys( $input );
288
+ }
289
+
290
+ $return = array();
291
+
292
+ foreach ( $fields as $field ) {
293
+ if ( ! isset( $input[ $field ] ) ) {
294
+ continue;
295
+ } else {
296
+ $value = $input[ $field ];
297
+ if ( is_array( $value ) ) {
298
+ $value = sanitize( $value );
299
+ }
300
+ if ( is_string( $value ) ) {
301
+ if ( $magic_quotes === true ) {
302
+ $value = stripslashes( $value );
303
+ }
304
+
305
+ if ( strpos( $value, "\r" ) !== false ) {
306
+ $value = trim( $value );
307
+ }
308
+
309
+ if ( function_exists( 'iconv' ) && function_exists( 'mb_detect_encoding' ) && $utf8_encode ) {
310
+ $current_encoding = mb_detect_encoding( $value );
311
+
312
+ if ( $current_encoding != 'UTF-8' && $current_encoding != 'UTF-16' ) {
313
+ $value = iconv( $current_encoding, 'UTF-8', $value );
314
+ }
315
+ }
316
+
317
+ $value = filter_var( $value, FILTER_SANITIZE_STRING );
318
+ }
319
+
320
+ $return[ $field ] = $value;
321
+ }
322
+ }
323
+
324
+ return $return;
325
+ }
326
+
327
+ /**
328
+ * Return the error array from the last validation run.
329
+ *
330
+ * @return array
331
+ */
332
+ public function errors() {
333
+ return $this->errors;
334
+ }
335
+
336
+ /**
337
+ * Perform data validation against the provided ruleset.
338
+ *
339
+ * @param mixed $input
340
+ * @param array $ruleset
341
+ *
342
+ * @return mixed
343
+ *
344
+ * @throws Exception
345
+ */
346
+ public function validate( array $input, array $ruleset ) {
347
+ $this->errors = array();
348
+
349
+ foreach ( $ruleset as $field => $rules ) {
350
+
351
+ $rules = explode( '|', $rules );
352
+
353
+ if ( in_array( 'required', $rules ) || ( isset( $input[ $field ] ) && ! is_array( $input[ $field ] ) ) ) {
354
+ foreach ( $rules as $rule ) {
355
+ $method = null;
356
+ $param = null;
357
+
358
+ // Check if we have rule parameters
359
+ if ( strstr( $rule, ',' ) !== false ) {
360
+ $rule = explode( ',', $rule );
361
+ $method = 'validate_' . $rule[0];
362
+ $param = $rule[1];
363
+ $rule = $rule[0];
364
+ } else {
365
+ $method = 'validate_' . $rule;
366
+ }
367
+
368
+ //self::$validation_methods[$rule] = $callback;
369
+
370
+ if ( is_callable( array( $this, $method ) ) ) {
371
+ $result = $this->$method(
372
+ $field, $input, $param
373
+ );
374
+
375
+ if ( is_array( $result ) ) {
376
+ $this->errors[] = $result;
377
+ }
378
+ } elseif ( isset( self::$validation_methods[ $rule ] ) ) {
379
+
380
+ $result = call_user_func( self::$validation_methods[ $rule ], $field, $input, $param );
381
+
382
+ if ( $result === false ) {
383
+ $this->errors[] = array(
384
+ 'field' => $field,
385
+ 'value' => $input,
386
+ 'rule' => self::$validation_methods[ $rule ],
387
+ 'param' => $param,
388
+ );
389
+ }
390
+
391
+ } else {
392
+ throw new Exception( "Validator method '$method' does not exist." );
393
+ }
394
+ }
395
+ }
396
+ }
397
+
398
+ return ( count( $this->errors ) > 0 ) ? $this->errors : true;
399
+ }
400
+
401
+ /**
402
+ * Overloadable method to invoke validation.
403
+ *
404
+ * @param array $input
405
+ * @param $rules
406
+ * @param $field
407
+ *
408
+ * @return bool
409
+ */
410
+ protected function shouldRunValidation( array $input, $rules, $field ) {
411
+ return in_array( 'required', $rules ) || ( isset( $input[ $field ] ) && trim( $input[ $field ] ) != '' );
412
+ }
413
+
414
+ /**
415
+ * Set a readable name for a specified field names.
416
+ *
417
+ * @param string $field
418
+ * @param string $readable_name
419
+ */
420
+ public static function set_field_name( $field, $readable_name ) {
421
+ self::$fields[ $field ] = $readable_name;
422
+ }
423
+
424
+ /**
425
+ * Set readable name for specified fields in an array.
426
+ *
427
+ * Usage:
428
+ *
429
+ * GUMP::set_field_names(array(
430
+ * "name" => "My Lovely Name",
431
+ * "username" => "My Beloved Username",
432
+ * ));
433
+ *
434
+ * @param array $array
435
+ */
436
+ public static function set_field_names( array $array ) {
437
+ foreach ( $array as $field => $readable_name ) {
438
+ self::$fields[ $field ] = $readable_name;
439
+ }
440
+ }
441
+
442
+ /**
443
+ * Process the validation errors and return human readable error messages.
444
+ *
445
+ * @param bool $convert_to_string = false
446
+ * @param string $field_class
447
+ * @param string $error_class
448
+ *
449
+ * @return array
450
+ * @return string
451
+ */
452
+ public function get_readable_errors( $convert_to_string = false, $field_class = 'gump-field', $error_class = 'gump-error-message' ) {
453
+ if ( empty( $this->errors ) ) {
454
+ return ( $convert_to_string ) ? null : array();
455
+ }
456
+
457
+ $resp = array();
458
+
459
+ foreach ( $this->errors as $e ) {
460
+ $field = ucwords( str_replace( $this->fieldCharsToRemove, chr( 32 ), $e['field'] ) );
461
+ $param = $e['param'];
462
+
463
+ // Let's fetch explicit field names if they exist
464
+ if ( array_key_exists( $e['field'], self::$fields ) ) {
465
+ $field = self::$fields[ $e['field'] ];
466
+ }
467
+
468
+ switch ( $e['rule'] ) {
469
+ case 'mismatch' :
470
+ $resp[] = "There is no validation rule for <span class=\"$field_class\">$field</span>";
471
+ break;
472
+ case 'validate_required' :
473
+ $resp[] = "The <span class=\"$field_class\">$field</span> field is required";
474
+ break;
475
+ case 'validate_valid_email':
476
+ $resp[] = "The <span class=\"$field_class\">$field</span> field is required to be a valid email address";
477
+ break;
478
+ case 'validate_max_len':
479
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be $param or shorter in length";
480
+ break;
481
+ case 'validate_min_len':
482
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be $param or longer in length";
483
+ break;
484
+ case 'validate_exact_len':
485
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be exactly $param characters in length";
486
+ break;
487
+ case 'validate_alpha':
488
+ $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain alpha characters(a-z)";
489
+ break;
490
+ case 'validate_alpha_numeric':
491
+ $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain alpha-numeric characters";
492
+ break;
493
+ case 'validate_alpha_dash':
494
+ $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain alpha characters &amp; dashes";
495
+ break;
496
+ case 'validate_numeric':
497
+ $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain numeric characters";
498
+ break;
499
+ case 'validate_integer':
500
+ $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain a numeric value";
501
+ break;
502
+ case 'validate_boolean':
503
+ $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain a true or false value";
504
+ break;
505
+ case 'validate_float':
506
+ $resp[] = "The <span class=\"$field_class\">$field</span> field may only contain a float value";
507
+ break;
508
+ case 'validate_valid_url':
509
+ $resp[] = "The <span class=\"$field_class\">$field</span> field is required to be a valid URL";
510
+ break;
511
+ case 'validate_url_exists':
512
+ $resp[] = "The <span class=\"$field_class\">$field</span> URL does not exist";
513
+ break;
514
+ case 'validate_valid_ip':
515
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to contain a valid IP address";
516
+ break;
517
+ case 'validate_valid_cc':
518
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to contain a valid credit card number";
519
+ break;
520
+ case 'validate_valid_name':
521
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to contain a valid human name";
522
+ break;
523
+ case 'validate_contains':
524
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to contain one of these values: " . implode( ', ', $param );
525
+ break;
526
+ case 'validate_contains_list':
527
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to contain a value from its drop down list";
528
+ break;
529
+ case 'validate_doesnt_contain_list':
530
+ $resp[] = "The <span class=\"$field_class\">$field</span> field contains a value that is not accepted";
531
+ break;
532
+ case 'validate_street_address':
533
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be a valid street address";
534
+ break;
535
+ case 'validate_date':
536
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be a valid date";
537
+ break;
538
+ case 'validate_min_numeric':
539
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be a numeric value, equal to, or higher than $param";
540
+ break;
541
+ case 'validate_max_numeric':
542
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to be a numeric value, equal to, or lower than $param";
543
+ break;
544
+ case 'validate_starts':
545
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to start with $param";
546
+ break;
547
+ case 'validate_extension':
548
+ $resp[] = "The <span class=\"$field_class\">$field</span> field can have the following extensions $param";
549
+ break;
550
+ case 'validate_required_file':
551
+ $resp[] = "The <span class=\"$field_class\">$field</span> field is required";
552
+ break;
553
+ case 'validate_equalsfield':
554
+ $resp[] = "The <span class=\"$field_class\">$field</span> field does not equal $param field";
555
+ break;
556
+ case 'validate_min_age':
557
+ $resp[] = "The <span class=\"$field_class\">$field</span> field needs to have an age greater than or equal to $param";
558
+ break;
559
+ default:
560
+ $resp[] = "The <span class=\"$field_class\">$field</span> field is invalid";
561
+ }
562
+ }
563
+
564
+ if ( ! $convert_to_string ) {
565
+ return $resp;
566
+ } else {
567
+ $buffer = '';
568
+ foreach ( $resp as $s ) {
569
+ $buffer .= "<span class=\"$error_class\">$s</span>";
570
+ }
571
+
572
+ return $buffer;
573
+ }
574
+ }
575
+
576
+ /**
577
+ * Process the validation errors and return an array of errors with field names as keys.
578
+ *
579
+ * @param $convert_to_string
580
+ *
581
+ * @return array | null (if empty)
582
+ */
583
+ public function get_errors_array( $convert_to_string = null ) {
584
+ if ( empty( $this->errors ) ) {
585
+ return ( $convert_to_string ) ? null : array();
586
+ }
587
+
588
+ $resp = array();
589
+
590
+ foreach ( $this->errors as $e ) {
591
+ $field = ucwords( str_replace( array( '_', '-' ), chr( 32 ), $e['field'] ) );
592
+ $param = $e['param'];
593
+
594
+ // Let's fetch explicit field names if they exist
595
+ if ( array_key_exists( $e['field'], self::$fields ) ) {
596
+ $field = self::$fields[ $e['field'] ];
597
+ }
598
+
599
+ switch ( $e['rule'] ) {
600
+ case 'mismatch' :
601
+ $resp[ $field ] = "There is no validation rule for $field";
602
+ break;
603
+ case 'validate_required':
604
+ $resp[ $field ] = "The $field field is required";
605
+ break;
606
+ case 'validate_valid_email':
607
+ $resp[ $field ] = "The $field field is required to be a valid email address";
608
+ break;
609
+ case 'validate_max_len':
610
+ $resp[ $field ] = "The $field field needs to be $param or shorter in length";
611
+ break;
612
+ case 'validate_min_len':
613
+ $resp[ $field ] = "The $field field needs to be $param or longer in length";
614
+ break;
615
+ case 'validate_exact_len':
616
+ $resp[ $field ] = "The $field field needs to be exactly $param characters in length";
617
+ break;
618
+ case 'validate_alpha':
619
+ $resp[ $field ] = "The $field field may only contain alpha characters(a-z)";
620
+ break;
621
+ case 'validate_alpha_numeric':
622
+ $resp[ $field ] = "The $field field may only contain alpha-numeric characters";
623
+ break;
624
+ case 'validate_alpha_dash':
625
+ $resp[ $field ] = "The $field field may only contain alpha characters &amp; dashes";
626
+ break;
627
+ case 'validate_numeric':
628
+ $resp[ $field ] = "The $field field may only contain numeric characters";
629
+ break;
630
+ case 'validate_integer':
631
+ $resp[ $field ] = "The $field field may only contain a numeric value";
632
+ break;
633
+ case 'validate_boolean':
634
+ $resp[ $field ] = "The $field field may only contain a true or false value";
635
+ break;
636
+ case 'validate_float':
637
+ $resp[ $field ] = "The $field field may only contain a float value";
638
+ break;
639
+ case 'validate_valid_url':
640
+ $resp[ $field ] = "The $field field is required to be a valid URL";
641
+ break;
642
+ case 'validate_url_exists':
643
+ $resp[ $field ] = "The $field URL does not exist";
644
+ break;
645
+ case 'validate_valid_ip':
646
+ $resp[ $field ] = "The $field field needs to contain a valid IP address";
647
+ break;
648
+ case 'validate_valid_cc':
649
+ $resp[ $field ] = "The $field field needs to contain a valid credit card number";
650
+ break;
651
+ case 'validate_valid_name':
652
+ $resp[ $field ] = "The $field field needs to contain a valid human name";
653
+ break;
654
+ case 'validate_contains':
655
+ $resp[ $field ] = "The $field field needs to contain one of these values: " . implode( ', ', $param );
656
+ break;
657
+ case 'validate_contains_list':
658
+ $resp[ $field ] = "The $field field needs to contain a value from its drop down list";
659
+ break;
660
+ case 'validate_doesnt_contain_list':
661
+ $resp[ $field ] = "The $field field contains a value that is not accepted";
662
+ break;
663
+ case 'validate_street_address':
664
+ $resp[ $field ] = "The $field field needs to be a valid street address";
665
+ break;
666
+ case 'validate_date':
667
+ $resp[ $field ] = "The $field field needs to be a valid date";
668
+ break;
669
+ case 'validate_min_numeric':
670
+ $resp[ $field ] = "The $field field needs to be a numeric value, equal to, or higher than $param";
671
+ break;
672
+ case 'validate_max_numeric':
673
+ $resp[ $field ] = "The $field field needs to be a numeric value, equal to, or lower than $param";
674
+ break;
675
+ case 'validate_min_age':
676
+ $resp[ $field ] = "The $field field needs to have an age greater than or equal to $param";
677
+ break;
678
+ default:
679
+ $resp[ $field ] = "The $field field is invalid";
680
+ }
681
+ }
682
+
683
+ return $resp;
684
+ }
685
+
686
+ /**
687
+ * Filter the input data according to the specified filter set.
688
+ *
689
+ * @param mixed $input
690
+ * @param array $filterset
691
+ *
692
+ * @throws Exception
693
+ *
694
+ * @return mixed
695
+ *
696
+ * @throws Exception
697
+ */
698
+ public function filter( array $input, array $filterset ) {
699
+ foreach ( $filterset as $field => $filters ) {
700
+ if ( ! array_key_exists( $field, $input ) ) {
701
+ continue;
702
+ }
703
+
704
+ $filters = explode( '|', $filters );
705
+
706
+ foreach ( $filters as $filter ) {
707
+ $params = null;
708
+
709
+ if ( strstr( $filter, ',' ) !== false ) {
710
+ $filter = explode( ',', $filter );
711
+
712
+ $params = array_slice( $filter, 1, count( $filter ) - 1 );
713
+
714
+ $filter = $filter[0];
715
+ }
716
+
717
+ if ( is_callable( array( $this, 'filter_' . $filter ) ) ) {
718
+ $method = 'filter_' . $filter;
719
+ $input[ $field ] = $this->$method( $input[ $field ], $params );
720
+ } elseif ( function_exists( $filter ) ) {
721
+ $input[ $field ] = $filter( $input[ $field ] );
722
+ } elseif ( isset( self::$filter_methods[ $filter ] ) ) {
723
+ $input[ $field ] = call_user_func( self::$filter_methods[ $filter ], $input[ $field ], $params );
724
+ } else {
725
+ throw new Exception( "Filter method '$filter' does not exist." );
726
+ }
727
+ }
728
+ }
729
+
730
+ return $input;
731
+ }
732
+
733
+ // ** ------------------------- Filters --------------------------------------- ** //
734
+
735
+ /**
736
+ * Replace noise words in a string (http://tax.cchgroup.com/help/Avoiding_noise_words_in_your_search.htm).
737
+ *
738
+ * Usage: '<index>' => 'noise_words'
739
+ *
740
+ * @param string $value
741
+ * @param array $params
742
+ *
743
+ * @return string
744
+ */
745
+ protected function filter_noise_words( $value, $params = null ) {
746
+ $value = preg_replace( '/\s\s+/u', chr( 32 ), $value );
747
+
748
+ $value = " $value ";
749
+
750
+ $words = explode( ',', self::$en_noise_words );
751
+
752
+ foreach ( $words as $word ) {
753
+ $word = trim( $word );
754
+
755
+ $word = " $word "; // Normalize
756
+
757
+ if ( stripos( $value, $word ) !== false ) {
758
+ $value = str_ireplace( $word, chr( 32 ), $value );
759
+ }
760
+ }
761
+
762
+ return trim( $value );
763
+ }
764
+
765
+ /**
766
+ * Remove all known punctuation from a string.
767
+ *
768
+ * Usage: '<index>' => 'rmpunctuataion'
769
+ *
770
+ * @param string $value
771
+ * @param array $params
772
+ *
773
+ * @return string
774
+ */
775
+ protected function filter_rmpunctuation( $value, $params = null ) {
776
+ return preg_replace( "/(?![.=$'€%-])\p{P}/u", '', $value );
777
+ }
778
+
779
+ /**
780
+ * Translate an input string to a desired language [DEPRECIATED].
781
+ *
782
+ * Any ISO 639-1 2 character language code may be used
783
+ *
784
+ * See: http://www.science.co.il/language/Codes.asp?s=code2
785
+ *
786
+ * @param string $value
787
+ * @param array $params
788
+ *
789
+ * @return string
790
+ */
791
+ /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
792
  protected function filter_translate($value, $params = NULL)
793
  {
794
  $input_lang = 'en';
829
  }
830
  */
831
 
832
+ /**
833
+ * Sanitize the string by removing any script tags.
834
+ *
835
+ * Usage: '<index>' => 'sanitize_string'
836
+ *
837
+ * @param string $value
838
+ * @param array $params
839
+ *
840
+ * @return string
841
+ */
842
+ protected function filter_sanitize_string( $value, $params = null ) {
843
+ return filter_var( $value, FILTER_SANITIZE_STRING );
844
+ }
845
+
846
+ /**
847
+ * Sanitize the string by urlencoding characters.
848
+ *
849
+ * Usage: '<index>' => 'urlencode'
850
+ *
851
+ * @param string $value
852
+ * @param array $params
853
+ *
854
+ * @return string
855
+ */
856
+ protected function filter_urlencode( $value, $params = null ) {
857
+ return filter_var( $value, FILTER_SANITIZE_ENCODED );
858
+ }
859
+
860
+ /**
861
+ * Sanitize the string by converting HTML characters to their HTML entities.
862
+ *
863
+ * Usage: '<index>' => 'htmlencode'
864
+ *
865
+ * @param string $value
866
+ * @param array $params
867
+ *
868
+ * @return string
869
+ */
870
+ protected function filter_htmlencode( $value, $params = null ) {
871
+ return filter_var( $value, FILTER_SANITIZE_SPECIAL_CHARS );
872
+ }
873
+
874
+ /**
875
+ * Sanitize the string by removing illegal characters from emails.
876
+ *
877
+ * Usage: '<index>' => 'sanitize_email'
878
+ *
879
+ * @param string $value
880
+ * @param array $params
881
+ *
882
+ * @return string
883
+ */
884
+ protected function filter_sanitize_email( $value, $params = null ) {
885
+ return filter_var( $value, FILTER_SANITIZE_EMAIL );
886
+ }
887
+
888
+ /**
889
+ * Sanitize the string by removing illegal characters from numbers.
890
+ *
891
+ * @param string $value
892
+ * @param array $params
893
+ *
894
+ * @return string
895
+ */
896
+ protected function filter_sanitize_numbers( $value, $params = null ) {
897
+ return filter_var( $value, FILTER_SANITIZE_NUMBER_INT );
898
+ }
899
+
900
+ /**
901
+ * Sanitize the string by removing illegal characters from float numbers.
902
+ *
903
+ * @param string $value
904
+ * @param array $params
905
+ *
906
+ * @return string
907
+ */
908
+ protected function filter_sanitize_floats( $value, $params = null ) {
909
+ return filter_var( $value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION );
910
+ }
911
+
912
+ /**
913
+ * Filter out all HTML tags except the defined basic tags.
914
+ *
915
+ * @param string $value
916
+ * @param array $params
917
+ *
918
+ * @return string
919
+ */
920
+ protected function filter_basic_tags( $value, $params = null ) {
921
+ return strip_tags( $value, self::$basic_tags );
922
+ }
923
+
924
+ /**
925
+ * Convert the provided numeric value to a whole number.
926
+ *
927
+ * @param string $value
928
+ * @param array $params
929
+ *
930
+ * @return string
931
+ */
932
+ protected function filter_whole_number( $value, $params = null ) {
933
+ return intval( $value );
934
+ }
935
+
936
+ // ** ------------------------- Validators ------------------------------------ ** //
937
+
938
+
939
+ /**
940
+ * Verify that a value is contained within the pre-defined value set.
941
+ *
942
+ * Usage: '<index>' => 'contains,value value value'
943
+ *
944
+ * @param string $field
945
+ * @param array $input
946
+ * @param null $param
947
+ *
948
+ * @return mixed
949
+ */
950
+ protected function validate_contains( $field, $input, $param = null ) {
951
+ if ( ! isset( $input[ $field ] ) ) {
952
+ return;
953
+ }
954
+
955
+ $param = trim( strtolower( $param ) );
956
+
957
+ $value = trim( strtolower( $input[ $field ] ) );
958
+
959
+ if ( preg_match_all( '#\'(.+?)\'#', $param, $matches, PREG_PATTERN_ORDER ) ) {
960
+ $param = $matches[1];
961
+ } else {
962
+ $param = explode( chr( 32 ), $param );
963
+ }
964
+
965
+ if ( in_array( $value, $param ) ) { // valid, return nothing
966
+ return;
967
+ }
968
+
969
+ return array(
970
+ 'field' => $field,
971
+ 'value' => $value,
972
+ 'rule' => __FUNCTION__,
973
+ 'param' => $param,
974
+ );
975
+ }
976
+
977
+ /**
978
+ * Verify that a value is contained within the pre-defined value set.
979
+ * OUTPUT: will NOT show the list of values.
980
+ *
981
+ * Usage: '<index>' => 'contains_list,value;value;value'
982
+ *
983
+ * @param string $field
984
+ * @param array $input
985
+ *
986
+ * @return mixed
987
+ */
988
+ protected function validate_contains_list( $field, $input, $param = null ) {
989
+ $param = trim( strtolower( $param ) );
990
+
991
+ $value = trim( strtolower( $input[ $field ] ) );
992
+
993
+ $param = explode( ';', $param );
994
+
995
+ // consider: in_array(strtolower($value), array_map('strtolower', $param)
996
+
997
+ if ( in_array( $value, $param ) ) { // valid, return nothing
998
+ return;
999
+ } else {
1000
+ return array(
1001
+ 'field' => $field,
1002
+ 'value' => $value,
1003
+ 'rule' => __FUNCTION__,
1004
+ 'param' => $param,
1005
+ );
1006
+ }
1007
+ }
1008
+
1009
+ /**
1010
+ * Verify that a value is NOT contained within the pre-defined value set.
1011
+ * OUTPUT: will NOT show the list of values.
1012
+ *
1013
+ * Usage: '<index>' => 'doesnt_contain_list,value;value;value'
1014
+ *
1015
+ * @param string $field
1016
+ * @param array $input
1017
+ *
1018
+ * @return mixed
1019
+ */
1020
+ protected function validate_doesnt_contain_list( $field, $input, $param = null ) {
1021
+ $param = trim( strtolower( $param ) );
1022
+
1023
+ $value = trim( strtolower( $input[ $field ] ) );
1024
+
1025
+ $param = explode( ';', $param );
1026
+
1027
+ if ( ! in_array( $value, $param ) ) { // valid, return nothing
1028
+ return;
1029
+ } else {
1030
+ return array(
1031
+ 'field' => $field,
1032
+ 'value' => $value,
1033
+ 'rule' => __FUNCTION__,
1034
+ 'param' => $param,
1035
+ );
1036
+ }
1037
+ }
1038
+
1039
+ /**
1040
+ * Check if the specified key is present and not empty.
1041
+ *
1042
+ * Usage: '<index>' => 'required'
1043
+ *
1044
+ * @param string $field
1045
+ * @param array $input
1046
+ * @param null $param
1047
+ *
1048
+ * @return mixed
1049
+ */
1050
+ protected function validate_required( $field, $input, $param = null ) {
1051
+ if ( isset( $input[ $field ] ) && ( $input[ $field ] === false || $input[ $field ] === 0 || $input[ $field ] === 0.0 || $input[ $field ] === '0' || ! empty( $input[ $field ] ) ) ) {
1052
+ return;
1053
+ }
1054
+
1055
+ return array(
1056
+ 'field' => $field,
1057
+ 'value' => null,
1058
+ 'rule' => __FUNCTION__,
1059
+ 'param' => $param,
1060
+ );
1061
+ }
1062
+
1063
+ /**
1064
+ * Determine if the provided email is valid.
1065
+ *
1066
+ * Usage: '<index>' => 'valid_email'
1067
+ *
1068
+ * @param string $field
1069
+ * @param array $input
1070
+ * @param null $param
1071
+ *
1072
+ * @return mixed
1073
+ */
1074
+ protected function validate_valid_email( $field, $input, $param = null ) {
1075
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1076
+ return;
1077
+ }
1078
+
1079
+ if ( ! filter_var( $input[ $field ], FILTER_VALIDATE_EMAIL ) ) {
1080
+ return array(
1081
+ 'field' => $field,
1082
+ 'value' => $input[ $field ],
1083
+ 'rule' => __FUNCTION__,
1084
+ 'param' => $param,
1085
+ );
1086
+ }
1087
+ }
1088
+
1089
+ /**
1090
+ * Determine if the provided value length is less or equal to a specific value.
1091
+ *
1092
+ * Usage: '<index>' => 'max_len,240'
1093
+ *
1094
+ * @param string $field
1095
+ * @param array $input
1096
+ * @param null $param
1097
+ *
1098
+ * @return mixed
1099
+ */
1100
+ protected function validate_max_len( $field, $input, $param = null ) {
1101
+ if ( ! isset( $input[ $field ] ) ) {
1102
+ return;
1103
+ }
1104
+
1105
+ if ( function_exists( 'mb_strlen' ) ) {
1106
+ if ( mb_strlen( $input[ $field ] ) <= (int) $param ) {
1107
+ return;
1108
+ }
1109
+ } else {
1110
+ if ( strlen( $input[ $field ] ) <= (int) $param ) {
1111
+ return;
1112
+ }
1113
+ }
1114
+
1115
+ return array(
1116
+ 'field' => $field,
1117
+ 'value' => $input[ $field ],
1118
+ 'rule' => __FUNCTION__,
1119
+ 'param' => $param,
1120
+ );
1121
+ }
1122
+
1123
+ /**
1124
+ * Determine if the provided value length is more or equal to a specific value.
1125
+ *
1126
+ * Usage: '<index>' => 'min_len,4'
1127
+ *
1128
+ * @param string $field
1129
+ * @param array $input
1130
+ * @param null $param
1131
+ *
1132
+ * @return mixed
1133
+ */
1134
+ protected function validate_min_len( $field, $input, $param = null ) {
1135
+ if ( ! isset( $input[ $field ] ) ) {
1136
+ return;
1137
+ }
1138
+
1139
+ if ( function_exists( 'mb_strlen' ) ) {
1140
+ if ( mb_strlen( $input[ $field ] ) >= (int) $param ) {
1141
+ return;
1142
+ }
1143
+ } else {
1144
+ if ( strlen( $input[ $field ] ) >= (int) $param ) {
1145
+ return;
1146
+ }
1147
+ }
1148
+
1149
+ return array(
1150
+ 'field' => $field,
1151
+ 'value' => $input[ $field ],
1152
+ 'rule' => __FUNCTION__,
1153
+ 'param' => $param,
1154
+ );
1155
+ }
1156
+
1157
+ /**
1158
+ * Determine if the provided value length matches a specific value.
1159
+ *
1160
+ * Usage: '<index>' => 'exact_len,5'
1161
+ *
1162
+ * @param string $field
1163
+ * @param array $input
1164
+ * @param null $param
1165
+ *
1166
+ * @return mixed
1167
+ */
1168
+ protected function validate_exact_len( $field, $input, $param = null ) {
1169
+ if ( ! isset( $input[ $field ] ) ) {
1170
+ return;
1171
+ }
1172
+
1173
+ if ( function_exists( 'mb_strlen' ) ) {
1174
+ if ( mb_strlen( $input[ $field ] ) == (int) $param ) {
1175
+ return;
1176
+ }
1177
+ } else {
1178
+ if ( strlen( $input[ $field ] ) == (int) $param ) {
1179
+ return;
1180
+ }
1181
+ }
1182
+
1183
+ return array(
1184
+ 'field' => $field,
1185
+ 'value' => $input[ $field ],
1186
+ 'rule' => __FUNCTION__,
1187
+ 'param' => $param,
1188
+ );
1189
+ }
1190
+
1191
+ /**
1192
+ * Determine if the provided value contains only alpha characters.
1193
+ *
1194
+ * Usage: '<index>' => 'alpha'
1195
+ *
1196
+ * @param string $field
1197
+ * @param array $input
1198
+ * @param null $param
1199
+ *
1200
+ * @return mixed
1201
+ */
1202
+ protected function validate_alpha( $field, $input, $param = null ) {
1203
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1204
+ return;
1205
+ }
1206
+
1207
+ if ( ! preg_match( '/^([a-zÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ])+$/i', $input[ $field ] ) !== false ) {
1208
+ return array(
1209
+ 'field' => $field,
1210
+ 'value' => $input[ $field ],
1211
+ 'rule' => __FUNCTION__,
1212
+ 'param' => $param,
1213
+ );
1214
+ }
1215
+ }
1216
+
1217
+ /**
1218
+ * Determine if the provided value contains only alpha-numeric characters.
1219
+ *
1220
+ * Usage: '<index>' => 'alpha_numeric'
1221
+ *
1222
+ * @param string $field
1223
+ * @param array $input
1224
+ * @param null $param
1225
+ *
1226
+ * @return mixed
1227
+ */
1228
+ protected function validate_alpha_numeric( $field, $input, $param = null ) {
1229
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1230
+ return;
1231
+ }
1232
+
1233
+ if ( ! preg_match( '/^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ])+$/i', $input[ $field ] ) !== false ) {
1234
+ return array(
1235
+ 'field' => $field,
1236
+ 'value' => $input[ $field ],
1237
+ 'rule' => __FUNCTION__,
1238
+ 'param' => $param,
1239
+ );
1240
+ }
1241
+ }
1242
+
1243
+ /**
1244
+ * Determine if the provided value contains only alpha characters with dashed and underscores.
1245
+ *
1246
+ * Usage: '<index>' => 'alpha_dash'
1247
+ *
1248
+ * @param string $field
1249
+ * @param array $input
1250
+ * @param null $param
1251
+ *
1252
+ * @return mixed
1253
+ */
1254
+ protected function validate_alpha_dash( $field, $input, $param = null ) {
1255
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1256
+ return;
1257
+ }
1258
+
1259
+ if ( ! preg_match( '/^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ_-])+$/i', $input[ $field ] ) !== false ) {
1260
+ return array(
1261
+ 'field' => $field,
1262
+ 'value' => $input[ $field ],
1263
+ 'rule' => __FUNCTION__,
1264
+ 'param' => $param,
1265
+ );
1266
+ }
1267
+ }
1268
+
1269
+ /**
1270
+ * Determine if the provided value contains only alpha numeric characters with spaces.
1271
+ *
1272
+ * Usage: '<index>' => 'alpha_space'
1273
+ *
1274
+ * @param string $field
1275
+ * @param array $input
1276
+ * @param null $param
1277
+ *
1278
+ * @return mixed
1279
+ */
1280
+ protected function validate_alpha_space( $field, $input, $param = null ) {
1281
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1282
+ return;
1283
+ }
1284
+
1285
+ if ( ! preg_match( "/^([a-z0-9ÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ\s])+$/i", $input[ $field ] ) !== false ) {
1286
+ return array(
1287
+ 'field' => $field,
1288
+ 'value' => $input[ $field ],
1289
+ 'rule' => __FUNCTION__,
1290
+ 'param' => $param,
1291
+ );
1292
+ }
1293
+ }
1294
+
1295
+ /**
1296
+ * Determine if the provided value is a valid number or numeric string.
1297
+ *
1298
+ * Usage: '<index>' => 'numeric'
1299
+ *
1300
+ * @param string $field
1301
+ * @param array $input
1302
+ * @param null $param
1303
+ *
1304
+ * @return mixed
1305
+ */
1306
+ protected function validate_numeric( $field, $input, $param = null ) {
1307
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1308
+ return;
1309
+ }
1310
+
1311
+ if ( ! is_numeric( $input[ $field ] ) ) {
1312
+ return array(
1313
+ 'field' => $field,
1314
+ 'value' => $input[ $field ],
1315
+ 'rule' => __FUNCTION__,
1316
+ 'param' => $param,
1317
+ );
1318
+ }
1319
+ }
1320
+
1321
+ /**
1322
+ * Determine if the provided value is a valid integer.
1323
+ *
1324
+ * Usage: '<index>' => 'integer'
1325
+ *
1326
+ * @param string $field
1327
+ * @param array $input
1328
+ * @param null $param
1329
+ *
1330
+ * @return mixed
1331
+ */
1332
+ protected function validate_integer( $field, $input, $param = null ) {
1333
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1334
+ return;
1335
+ }
1336
+
1337
+ if ( filter_var( $input[ $field ], FILTER_VALIDATE_INT ) === false ) {
1338
+ return array(
1339
+ 'field' => $field,
1340
+ 'value' => $input[ $field ],
1341
+ 'rule' => __FUNCTION__,
1342
+ 'param' => $param,
1343
+ );
1344
+ }
1345
+ }
1346
+
1347
+ /**
1348
+ * Determine if the provided value is a PHP accepted boolean.
1349
+ *
1350
+ * Usage: '<index>' => 'boolean'
1351
+ *
1352
+ * @param string $field
1353
+ * @param array $input
1354
+ * @param null $param
1355
+ *
1356
+ * @return mixed
1357
+ */
1358
+ protected function validate_boolean( $field, $input, $param = null ) {
1359
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) && $input[ $field ] !== 0 ) {
1360
+ return;
1361
+ }
1362
+
1363
+ if ( $input[ $field ] === true || $input[ $field ] === false ) {
1364
+ return;
1365
+ }
1366
+
1367
+ return array(
1368
+ 'field' => $field,
1369
+ 'value' => $input[ $field ],
1370
+ 'rule' => __FUNCTION__,
1371
+ 'param' => $param,
1372
+ );
1373
+ }
1374
+
1375
+ /**
1376
+ * Determine if the provided value is a valid float.
1377
+ *
1378
+ * Usage: '<index>' => 'float'
1379
+ *
1380
+ * @param string $field
1381
+ * @param array $input
1382
+ * @param null $param
1383
+ *
1384
+ * @return mixed
1385
+ */
1386
+ protected function validate_float( $field, $input, $param = null ) {
1387
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1388
+ return;
1389
+ }
1390
+
1391
+ if ( filter_var( $input[ $field ], FILTER_VALIDATE_FLOAT ) === false ) {
1392
+ return array(
1393
+ 'field' => $field,
1394
+ 'value' => $input[ $field ],
1395
+ 'rule' => __FUNCTION__,
1396
+ 'param' => $param,
1397
+ );
1398
+ }
1399
+ }
1400
+
1401
+ /**
1402
+ * Determine if the provided value is a valid URL.
1403
+ *
1404
+ * Usage: '<index>' => 'valid_url'
1405
+ *
1406
+ * @param string $field
1407
+ * @param array $input
1408
+ * @param null $param
1409
+ *
1410
+ * @return mixed
1411
+ */
1412
+ protected function validate_valid_url( $field, $input, $param = null ) {
1413
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1414
+ return;
1415
+ }
1416
+
1417
+ if ( ! filter_var( $input[ $field ], FILTER_VALIDATE_URL ) ) {
1418
+ return array(
1419
+ 'field' => $field,
1420
+ 'value' => $input[ $field ],
1421
+ 'rule' => __FUNCTION__,
1422
+ 'param' => $param,
1423
+ );
1424
+ }
1425
+ }
1426
+
1427
+ /**
1428
+ * Determine if a URL exists & is accessible.
1429
+ *
1430
+ * Usage: '<index>' => 'url_exists'
1431
+ *
1432
+ * @param string $field
1433
+ * @param array $input
1434
+ * @param null $param
1435
+ *
1436
+ * @return mixed
1437
+ */
1438
+ protected function validate_url_exists( $field, $input, $param = null ) {
1439
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1440
+ return;
1441
+ }
1442
+
1443
+ $url = parse_url( strtolower( $input[ $field ] ) );
1444
+
1445
+ if ( isset( $url['host'] ) ) {
1446
+ $url = $url['host'];
1447
+ }
1448
+
1449
+ if ( function_exists( 'checkdnsrr' ) ) {
1450
+ if ( checkdnsrr( $url ) === false ) {
1451
+ return array(
1452
+ 'field' => $field,
1453
+ 'value' => $input[ $field ],
1454
+ 'rule' => __FUNCTION__,
1455
+ 'param' => $param,
1456
+ );
1457
+ }
1458
+ } else {
1459
+ if ( gethostbyname( $url ) == $url ) {
1460
+ return array(
1461
+ 'field' => $field,
1462
+ 'value' => $input[ $field ],
1463
+ 'rule' => __FUNCTION__,
1464
+ 'param' => $param,
1465
+ );
1466
+ }
1467
+ }
1468
+ }
1469
+
1470
+ /**
1471
+ * Determine if the provided value is a valid IP address.
1472
+ *
1473
+ * Usage: '<index>' => 'valid_ip'
1474
+ *
1475
+ * @param string $field
1476
+ * @param array $input
1477
+ *
1478
+ * @return mixed
1479
+ */
1480
+ protected function validate_valid_ip( $field, $input, $param = null ) {
1481
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1482
+ return;
1483
+ }
1484
+
1485
+ if ( ! filter_var( $input[ $field ], FILTER_VALIDATE_IP ) !== false ) {
1486
+ return array(
1487
+ 'field' => $field,
1488
+ 'value' => $input[ $field ],
1489
+ 'rule' => __FUNCTION__,
1490
+ 'param' => $param,
1491
+ );
1492
+ }
1493
+ }
1494
+
1495
+ /**
1496
+ * Determine if the provided value is a valid IPv4 address.
1497
+ *
1498
+ * Usage: '<index>' => 'valid_ipv4'
1499
+ *
1500
+ * @param string $field
1501
+ * @param array $input
1502
+ *
1503
+ * @return mixed
1504
+ *
1505
+ * @see http://pastebin.com/UvUPPYK0
1506
+ */
1507
+
1508
+ /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1509
  * What about private networks? http://en.wikipedia.org/wiki/Private_network
1510
  * What about loop-back address? 127.0.0.1
1511
  */
1512
+ protected function validate_valid_ipv4( $field, $input, $param = null ) {
1513
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1514
+ return;
1515
+ }
1516
+
1517
+ if ( ! filter_var( $input[ $field ], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
1518
+ // removed !== FALSE
1519
+
1520
+ return array(
1521
+ 'field' => $field,
1522
+ 'value' => $input[ $field ],
1523
+ 'rule' => __FUNCTION__,
1524
+ 'param' => $param,
1525
+ );
1526
+ }
1527
+ }
1528
+
1529
+ /**
1530
+ * Determine if the provided value is a valid IPv6 address.
1531
+ *
1532
+ * Usage: '<index>' => 'valid_ipv6'
1533
+ *
1534
+ * @param string $field
1535
+ * @param array $input
1536
+ *
1537
+ * @return mixed
1538
+ */
1539
+ protected function validate_valid_ipv6( $field, $input, $param = null ) {
1540
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1541
+ return;
1542
+ }
1543
+
1544
+ if ( ! filter_var( $input[ $field ], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
1545
+ return array(
1546
+ 'field' => $field,
1547
+ 'value' => $input[ $field ],
1548
+ 'rule' => __FUNCTION__,
1549
+ 'param' => $param,
1550
+ );
1551
+ }
1552
+ }
1553
+
1554
+ /**
1555
+ * Determine if the input is a valid credit card number.
1556
+ *
1557
+ * See: http://stackoverflow.com/questions/174730/what-is-the-best-way-to-validate-a-credit-card-in-php
1558
+ * Usage: '<index>' => 'valid_cc'
1559
+ *
1560
+ * @param string $field
1561
+ * @param array $input
1562
+ *
1563
+ * @return mixed
1564
+ */
1565
+ protected function validate_valid_cc( $field, $input, $param = null ) {
1566
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1567
+ return;
1568
+ }
1569
+
1570
+ $number = preg_replace( '/\D/', '', $input[ $field ] );
1571
+
1572
+ if ( function_exists( 'mb_strlen' ) ) {
1573
+ $number_length = mb_strlen( $number );
1574
+ } else {
1575
+ $number_length = strlen( $number );
1576
+ }
1577
+
1578
+ $parity = $number_length % 2;
1579
+
1580
+ $total = 0;
1581
+
1582
+ for ( $i = 0; $i < $number_length; ++ $i ) {
1583
+ $digit = $number[ $i ];
1584
+
1585
+ if ( $i % 2 == $parity ) {
1586
+ $digit *= 2;
1587
+
1588
+ if ( $digit > 9 ) {
1589
+ $digit -= 9;
1590
+ }
1591
+ }
1592
+
1593
+ $total += $digit;
1594
+ }
1595
+
1596
+ if ( $total % 10 == 0 ) {
1597
+ return; // Valid
1598
+ }
1599
+
1600
+ return array(
1601
+ 'field' => $field,
1602
+ 'value' => $input[ $field ],
1603
+ 'rule' => __FUNCTION__,
1604
+ 'param' => $param,
1605
+ );
1606
+ }
1607
+
1608
+ /**
1609
+ * Determine if the input is a valid human name [Credits to http://github.com/ben-s].
1610
+ *
1611
+ * See: https://github.com/Wixel/GUMP/issues/5
1612
+ * Usage: '<index>' => 'valid_name'
1613
+ *
1614
+ * @param string $field
1615
+ * @param array $input
1616
+ *
1617
+ * @return mixed
1618
+ */
1619
+ protected function validate_valid_name( $field, $input, $param = null ) {
1620
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1621
+ return;
1622
+ }
1623
+
1624
+ if ( ! preg_match( "/^([a-zÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖßÙÚÛÜÝàáâãäåçèéêëìíîïñðòóôõöùúûüýÿ '-])+$/i", $input[ $field ] ) !== false ) {
1625
+ return array(
1626
+ 'field' => $field,
1627
+ 'value' => $input[ $field ],
1628
+ 'rule' => __FUNCTION__,
1629
+ 'param' => $param,
1630
+ );
1631
+ }
1632
+ }
1633
+
1634
+ /**
1635
+ * Determine if the provided input is likely to be a street address using weak detection.
1636
+ *
1637
+ * Usage: '<index>' => 'street_address'
1638
+ *
1639
+ * @param string $field
1640
+ * @param array $input
1641
+ *
1642
+ * @return mixed
1643
+ */
1644
+ protected function validate_street_address( $field, $input, $param = null ) {
1645
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1646
+ return;
1647
+ }
1648
+
1649
+ // Theory: 1 number, 1 or more spaces, 1 or more words
1650
+ $hasLetter = preg_match( '/[a-zA-Z]/', $input[ $field ] );
1651
+ $hasDigit = preg_match( '/\d/', $input[ $field ] );
1652
+ $hasSpace = preg_match( '/\s/', $input[ $field ] );
1653
+
1654
+ $passes = $hasLetter && $hasDigit && $hasSpace;
1655
+
1656
+ if ( ! $passes ) {
1657
+ return array(
1658
+ 'field' => $field,
1659
+ 'value' => $input[ $field ],
1660
+ 'rule' => __FUNCTION__,
1661
+ 'param' => $param,
1662
+ );
1663
+ }
1664
+ }
1665
+
1666
+ /**
1667
+ * Determine if the provided value is a valid IBAN.
1668
+ *
1669
+ * Usage: '<index>' => 'iban'
1670
+ *
1671
+ * @param string $field
1672
+ * @param array $input
1673
+ *
1674
+ * @return mixed
1675
+ */
1676
+ protected function validate_iban( $field, $input, $param = null ) {
1677
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1678
+ return;
1679
+ }
1680
+
1681
+ static $character = array(
1682
+ 'A' => 10,
1683
+ 'C' => 12,
1684
+ 'D' => 13,
1685
+ 'E' => 14,
1686
+ 'F' => 15,
1687
+ 'G' => 16,
1688
+ 'H' => 17,
1689
+ 'I' => 18,
1690
+ 'J' => 19,
1691
+ 'K' => 20,
1692
+ 'L' => 21,
1693
+ 'M' => 22,
1694
+ 'N' => 23,
1695
+ 'O' => 24,
1696
+ 'P' => 25,
1697
+ 'Q' => 26,
1698
+ 'R' => 27,
1699
+ 'S' => 28,
1700
+ 'T' => 29,
1701
+ 'U' => 30,
1702
+ 'V' => 31,
1703
+ 'W' => 32,
1704
+ 'X' => 33,
1705
+ 'Y' => 34,
1706
+ 'Z' => 35,
1707
+ 'B' => 11
1708
+ );
1709
+
1710
+ if ( ! preg_match( "/\A[A-Z]{2}\d{2} ?[A-Z\d]{4}( ?\d{4}){1,} ?\d{1,4}\z/", $input[ $field ] ) ) {
1711
+ return array(
1712
+ 'field' => $field,
1713
+ 'value' => $input[ $field ],
1714
+ 'rule' => __FUNCTION__,
1715
+ 'param' => $param,
1716
+ );
1717
+ }
1718
+
1719
+ $iban = str_replace( ' ', '', $input[ $field ] );
1720
+ $iban = substr( $iban, 4 ) . substr( $iban, 0, 4 );
1721
+ $iban = strtr( $iban, $character );
1722
+
1723
+ if ( bcmod( $iban, 97 ) != 1 ) {
1724
+ return array(
1725
+ 'field' => $field,
1726
+ 'value' => $input[ $field ],
1727
+ 'rule' => __FUNCTION__,
1728
+ 'param' => $param,
1729
+ );
1730
+ }
1731
+ }
1732
+
1733
+ /**
1734
+ * Determine if the provided input is a valid date (ISO 8601).
1735
+ *
1736
+ * Usage: '<index>' => 'date'
1737
+ *
1738
+ * @param string $field
1739
+ * @param string $input date ('Y-m-d') or datetime ('Y-m-d H:i:s')
1740
+ * @param null $param
1741
+ *
1742
+ * @return mixed
1743
+ */
1744
+ protected function validate_date( $field, $input, $param = null ) {
1745
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1746
+ return;
1747
+ }
1748
+
1749
+ $cdate1 = date( 'Y-m-d', strtotime( $input[ $field ] ) );
1750
+ $cdate2 = date( 'Y-m-d H:i:s', strtotime( $input[ $field ] ) );
1751
+
1752
+ if ( $cdate1 != $input[ $field ] && $cdate2 != $input[ $field ] ) {
1753
+ return array(
1754
+ 'field' => $field,
1755
+ 'value' => $input[ $field ],
1756
+ 'rule' => __FUNCTION__,
1757
+ 'param' => $param,
1758
+ );
1759
+ }
1760
+ }
1761
+
1762
+ /**
1763
+ * Determine if the provided input meets age requirement (ISO 8601).
1764
+ *
1765
+ * Usage: '<index>' => 'min_age,13'
1766
+ *
1767
+ * @param string $field
1768
+ * @param string $input date ('Y-m-d') or datetime ('Y-m-d H:i:s')
1769
+ * @param string $param int
1770
+ *
1771
+ * @return mixed
1772
+ */
1773
+ protected function validate_min_age( $field, $input, $param = null ) {
1774
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1775
+ return;
1776
+ }
1777
+
1778
+ $cdate1 = new DateTime( date( 'Y-m-d', strtotime( $input[ $field ] ) ) );
1779
+ $today = new DateTime( date( 'd-m-Y' ) );
1780
+
1781
+ $interval = $cdate1->diff( $today );
1782
+ $age = $interval->y;
1783
+
1784
+ if ( $age <= $param ) {
1785
+ return array(
1786
+ 'field' => $field,
1787
+ 'value' => $input[ $field ],
1788
+ 'rule' => __FUNCTION__,
1789
+ 'param' => $param,
1790
+ );
1791
+ }
1792
+ }
1793
+
1794
+ /**
1795
+ * Determine if the provided numeric value is lower or equal to a specific value.
1796
+ *
1797
+ * Usage: '<index>' => 'max_numeric,50'
1798
+ *
1799
+ * @param string $field
1800
+ * @param array $input
1801
+ * @param null $param
1802
+ *
1803
+ * @return mixed
1804
+ */
1805
+ protected function validate_max_numeric( $field, $input, $param = null ) {
1806
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1807
+ return;
1808
+ }
1809
+
1810
+ if ( is_numeric( $input[ $field ] ) && is_numeric( $param ) && ( $input[ $field ] <= $param ) ) {
1811
+ return;
1812
+ }
1813
+
1814
+ return array(
1815
+ 'field' => $field,
1816
+ 'value' => $input[ $field ],
1817
+ 'rule' => __FUNCTION__,
1818
+ 'param' => $param,
1819
+ );
1820
+ }
1821
+
1822
+ /**
1823
+ * Determine if the provided numeric value is higher or equal to a specific value.
1824
+ *
1825
+ * Usage: '<index>' => 'min_numeric,1'
1826
+ *
1827
+ * @param string $field
1828
+ * @param array $input
1829
+ * @param null $param
1830
+ *
1831
+ * @return mixed
1832
+ */
1833
+ protected function validate_min_numeric( $field, $input, $param = null ) {
1834
+ if ( ! isset( $input[ $field ] ) ) {
1835
+ return;
1836
+ }
1837
+
1838
+ if ( is_numeric( $input[ $field ] ) && is_numeric( $param ) && ( $input[ $field ] >= $param ) ) {
1839
+ return;
1840
+ }
1841
+
1842
+ return array(
1843
+ 'field' => $field,
1844
+ 'value' => $input[ $field ],
1845
+ 'rule' => __FUNCTION__,
1846
+ 'param' => $param,
1847
+ );
1848
+ }
1849
+
1850
+ /**
1851
+ * Determine if the provided value starts with param.
1852
+ *
1853
+ * Usage: '<index>' => 'starts,Z'
1854
+ *
1855
+ * @param string $field
1856
+ * @param array $input
1857
+ *
1858
+ * @return mixed
1859
+ */
1860
+ protected function validate_starts( $field, $input, $param = null ) {
1861
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1862
+ return;
1863
+ }
1864
+
1865
+ if ( strpos( $input[ $field ], $param ) !== 0 ) {
1866
+ return array(
1867
+ 'field' => $field,
1868
+ 'value' => $input[ $field ],
1869
+ 'rule' => __FUNCTION__,
1870
+ 'param' => $param,
1871
+ );
1872
+ }
1873
+ }
1874
+
1875
+ /**
1876
+ * checks if a file was uploaded.
1877
+ *
1878
+ * Usage: '<index>' => 'required_file'
1879
+ *
1880
+ * @param string $field
1881
+ * @param array $input
1882
+ *
1883
+ * @return mixed
1884
+ */
1885
+ protected function validate_required_file( $field, $input, $param = null ) {
1886
+ if ( $input[ $field ]['error'] !== 4 ) {
1887
+ return;
1888
+ }
1889
+
1890
+ return array(
1891
+ 'field' => $field,
1892
+ 'value' => $input[ $field ],
1893
+ 'rule' => __FUNCTION__,
1894
+ 'param' => $param,
1895
+ );
1896
+ }
1897
+
1898
+ /**
1899
+ * check the uploaded file for extension
1900
+ * for now checks onlt the ext should add mime type check.
1901
+ *
1902
+ * Usage: '<index>' => 'starts,Z'
1903
+ *
1904
+ * @param string $field
1905
+ * @param array $input
1906
+ *
1907
+ * @return mixed
1908
+ */
1909
+ protected function validate_extension( $field, $input, $param = null ) {
1910
+ if ( $input[ $field ]['error'] !== 4 ) {
1911
+ $param = trim( strtolower( $param ) );
1912
+ $allowed_extensions = explode( ';', $param );
1913
+
1914
+ $path_info = pathinfo( $input[ $field ]['name'] );
1915
+ $extension = $path_info['extension'];
1916
+
1917
+ if ( in_array( $extension, $allowed_extensions ) ) {
1918
+ return;
1919
+ }
1920
+
1921
+ return array(
1922
+ 'field' => $field,
1923
+ 'value' => $input[ $field ],
1924
+ 'rule' => __FUNCTION__,
1925
+ 'param' => $param,
1926
+ );
1927
+ }
1928
+ }
1929
+
1930
+ /**
1931
+ * Determine if the provided field value equals current field value.
1932
+ *
1933
+ * Usage: '<index>' => 'equalsfield,Z'
1934
+ *
1935
+ * @param string $field
1936
+ * @param string $input
1937
+ * @param string $param field to compare with
1938
+ *
1939
+ * @return mixed
1940
+ */
1941
+ protected function validate_equalsfield( $field, $input, $param = null ) {
1942
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1943
+ return;
1944
+ }
1945
+
1946
+ if ( $input[ $field ] == $input[ $param ] ) {
1947
+ return;
1948
+ }
1949
+
1950
+ return array(
1951
+ 'field' => $field,
1952
+ 'value' => $input[ $field ],
1953
+ 'rule' => __FUNCTION__,
1954
+ 'param' => $param,
1955
+ );
1956
+ }
1957
+
1958
+ /**
1959
+ * Determine if the provided field value is a valid GUID (v4)
1960
+ *
1961
+ * Usage: '<index>' => 'guidv4'
1962
+ *
1963
+ * @param string $field
1964
+ * @param string $input
1965
+ * @param string $param field to compare with
1966
+ *
1967
+ * @return mixed
1968
+ */
1969
+ protected function validate_guidv4( $field, $input, $param = null ) {
1970
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
1971
+ return;
1972
+ }
1973
+
1974
+ if ( preg_match( "/\{?[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}\}?$/", $input[ $field ] ) ) {
1975
+ return;
1976
+ }
1977
+
1978
+ return array(
1979
+ 'field' => $field,
1980
+ 'value' => $input[ $field ],
1981
+ 'rule' => __FUNCTION__,
1982
+ 'param' => $param,
1983
+ );
1984
+ }
1985
+
1986
+ /**
1987
+ * Trims whitespace only when the value is a scalar.
1988
+ *
1989
+ * @param mixed $value
1990
+ *
1991
+ * @return mixed
1992
+ */
1993
+ private function trimScalar( $value ) {
1994
+ if ( is_scalar( $value ) ) {
1995
+ $value = trim( $value );
1996
+ }
1997
+
1998
+ return $value;
1999
+ }
2000
+
2001
+ /**
2002
+ * Determine if the provided value is a valid phone number.
2003
+ *
2004
+ * Usage: '<index>' => 'phone_number'
2005
+ *
2006
+ * @param string $field
2007
+ * @param array $input
2008
+ *
2009
+ * @return mixed
2010
+ *
2011
+ * Examples:
2012
+ *
2013
+ * 555-555-5555: valid
2014
+ * 5555425555: valid
2015
+ * 555 555 5555: valid
2016
+ * 1(519) 555-4444: valid
2017
+ * 1 (519) 555-4422: valid
2018
+ * 1-555-555-5555: valid
2019
+ * 1-(555)-555-5555: valid
2020
+ */
2021
+ protected function validate_phone_number( $field, $input, $param = null ) {
2022
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
2023
+ return;
2024
+ }
2025
+
2026
+ $regex = '/^(\d[\s-]?)?[\(\[\s-]{0,2}?\d{3}[\)\]\s-]{0,2}?\d{3}[\s-]?\d{4}$/i';
2027
+ if ( ! preg_match( $regex, $input[ $field ] ) ) {
2028
+ return array(
2029
+ 'field' => $field,
2030
+ 'value' => $input[ $field ],
2031
+ 'rule' => __FUNCTION__,
2032
+ 'param' => $param,
2033
+ );
2034
+ }
2035
+ }
2036
+
2037
+ /**
2038
+ * Custom regex validator.
2039
+ *
2040
+ * Usage: '<index>' => 'regex,/your-regex-expression/'
2041
+ *
2042
+ * @param string $field
2043
+ * @param array $input
2044
+ *
2045
+ * @return mixed
2046
+ */
2047
+ protected function validate_regex( $field, $input, $param = null ) {
2048
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
2049
+ return;
2050
+ }
2051
+
2052
+ $regex = $param;
2053
+ if ( ! preg_match( $regex, $input[ $field ] ) ) {
2054
+ return array(
2055
+ 'field' => $field,
2056
+ 'value' => $input[ $field ],
2057
+ 'rule' => __FUNCTION__,
2058
+ 'param' => $param,
2059
+ );
2060
+ }
2061
+ }
2062
+
2063
+ /**
2064
+ * Json validatior.
2065
+ *
2066
+ * Usage: '<index>' => 'valid_json_string'
2067
+ *
2068
+ * @param string $field
2069
+ * @param array $input
2070
+ *
2071
+ * @return mixed
2072
+ */
2073
+ protected function validate_valid_json_string( $field, $input, $param = null ) {
2074
+ if ( ! isset( $input[ $field ] ) || empty( $input[ $field ] ) ) {
2075
+ return;
2076
+ }
2077
+
2078
+ if ( ! is_string( $input[ $field ] ) || ! is_object( json_decode( $input[ $field ] ) ) ) {
2079
+ return array(
2080
+ 'field' => $field,
2081
+ 'value' => $input[ $field ],
2082
+ 'rule' => __FUNCTION__,
2083
+ 'param' => $param,
2084
+ );
2085
+ }
2086
+ }
2087
+ } // EOC
2088
  }
wp-defender.php CHANGED
@@ -1,8 +1,9 @@
1
  <?php
 
2
  /**
3
  * Plugin Name: WP Defender
4
  * Plugin URI: https://premium.wpmudev.org/project/wp-defender/
5
- * Version: 1.7.0.1
6
  * Description: Get regular security scans, vulnerability reports, safety recommendations and customized hardening for your site in just a few clicks. Defender is the analyst and enforcer who never sleeps.
7
  * Author: WPMU DEV
8
  * Author URI: http://premium.wpmudev.org/
1
  <?php
2
+
3
  /**
4
  * Plugin Name: WP Defender
5
  * Plugin URI: https://premium.wpmudev.org/project/wp-defender/
6
+ * Version: 1.7.1
7
  * Description: Get regular security scans, vulnerability reports, safety recommendations and customized hardening for your site in just a few clicks. Defender is the analyst and enforcer who never sleeps.
8
  * Author: WPMU DEV
9
  * Author URI: http://premium.wpmudev.org/