Version Description
Download this release
Release Info
Developer | paultgoodchild |
Plugin | Shield Security for WordPress |
Version | 11.3.0 |
Comparing to | |
See all releases |
Code changes from version 11.2.4 to 11.3.0
- cl.json +47 -0
- icwp-wpsf.php +1 -1
- plugin-spec.php +4 -4
- readme.txt +1 -1
- resources/js/shield/{antibot.js → notbot.js} +4 -4
- src/config/feature-admin_access_restriction.php +1 -2
- src/config/feature-ips.php +27 -2
- src/config/feature-plugin.php +0 -4
- src/lib/src/Databases/AuditTrail/Select.php +4 -4
- src/lib/src/Databases/Base/BaseQuery.php +7 -17
- src/lib/src/Databases/Base/EntryVoConsumer.php +4 -4
- src/lib/src/Databases/Base/Handler.php +0 -4
- src/lib/src/Databases/Events/Common.php +6 -6
- src/lib/src/Databases/Events/Select.php +6 -10
- src/lib/src/Modules/AuditTrail/Lib/AuditWriter.php +0 -3
- src/lib/src/Modules/AuditTrail/Lib/Ops/Commit.php +1 -1
- src/lib/src/Modules/AuditTrail/Options.php +1 -1
- src/lib/src/Modules/Base/ModCon.php +0 -55
- src/lib/src/Modules/BaseShield/ModCon.php +0 -17
- src/lib/src/Modules/Events/Consolidate/ConsolidateAllEvents.php +31 -31
- src/lib/src/Modules/Events/Lib/Reports/ScanRepairs.php +17 -17
- src/lib/src/Modules/Events/Lib/StatsWriter.php +0 -3
- src/lib/src/Modules/HackGuard/Scan/Controller/Base.php +0 -12
- src/lib/src/Modules/IPs/BotTrack/Base.php +19 -17
- src/lib/src/Modules/IPs/BotTrack/Track404.php +59 -1
- src/lib/src/Modules/IPs/BotTrack/TrackCommentSpam.php +1 -5
- src/lib/src/Modules/IPs/Components/IpAddressConsumer.php +1 -12
- src/lib/src/Modules/IPs/Lib/BlacklistHandler.php +4 -55
- src/lib/src/Modules/IPs/Lib/BlockRequest.php +11 -1
- src/lib/src/Modules/IPs/Lib/Bots/BotSignalsController.php +54 -2
- src/lib/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php +14 -3
- src/lib/src/Modules/IPs/Lib/Bots/Calculator/BaseBuildScores.php +68 -0
- src/lib/src/Modules/IPs/Lib/Bots/Calculator/BuildScores.php +28 -285
- src/lib/src/Modules/IPs/Lib/Bots/Calculator/BuildScoresFallback.php +248 -0
- src/lib/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php +1 -0
- src/lib/src/Modules/IPs/Lib/Bots/Calculator/ScoreLogic.php +159 -0
- src/lib/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php +3 -3
- src/lib/src/Modules/IPs/Lib/Bots/NotBot/TestNotBotLoading.php +21 -0
- src/lib/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php +13 -13
- src/lib/src/Modules/IPs/Lib/OffenseTracker.php +0 -4
- src/lib/src/Modules/IPs/Options.php +5 -1
- src/lib/src/Modules/IPs/Strings.php +17 -2
- src/lib/src/Modules/IPs/UI.php +10 -0
- src/lib/src/Modules/IPs/WpCli.php +1 -1
- src/lib/src/Modules/Insights/Lib/SideMenuBuilder.php +1 -1
- src/lib/src/Modules/Insights/ModCon.php +0 -11
- src/lib/src/Modules/Insights/UI.php +0 -22
- src/lib/src/Modules/Integrations/Lib/Spam/SpamController.php +0 -51
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/BaseProvider.php +0 -16
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/GoogleAuth.php +0 -15
- src/lib/src/Modules/Plugin/Lib/Debug/Collate.php +18 -14
- src/lib/src/Modules/Plugin/Lib/PluginTelemetry.php +32 -41
- src/lib/src/Modules/Reporting/Lib/ReportingController.php +0 -2
- src/lib/src/Modules/SecurityAdmin/ModCon.php +12 -43
- src/lib/src/Modules/SecurityAdmin/Options.php +0 -24
- src/lib/src/Modules/Sessions/Processor.php +0 -12
- src/lib/src/Modules/UserManagement/Processor.php +6 -3
- src/lib/src/ShieldNetApi/Common/BaseShieldNetApi.php +8 -2
- src/lib/src/ShieldNetApi/Reputation/BotScoringLogic.php +18 -0
- src/lib/src/ShieldNetApi/Telemetry/SendTelemetry.php +20 -0
- src/lib/src/Tables/Build/AuditTrail.php +3 -1
- src/lib/vendor/composer/autoload_classmap.php +23 -2
- src/lib/vendor/composer/autoload_files.php +1 -1
- src/lib/vendor/composer/autoload_psr4.php +1 -0
- src/lib/vendor/composer/autoload_static.php +29 -3
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/BaseQuery.php +466 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Delete.php +118 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Handler.php +249 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Insert.php +78 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php +88 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php +304 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/Select_IPTable.php +24 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php +119 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php +99 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php +157 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/HandlerConsumer.php +29 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/Iterator.php +113 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/RecordConsumer.php +29 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/SubQueryLoader.php +86 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableSchema.php +155 -0
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/NoSlugProvidedException.php +7 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php +35 -0
- templates/twig/wpadmin_pages/insights/ips/ip_analyse/ip_general.twig +2 -2
cl.json
CHANGED
@@ -1,4 +1,51 @@
|
|
1 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
"11.2": {
|
3 |
"version": "11.2",
|
4 |
"released_at": 1621844125,
|
1 |
{
|
2 |
+
"11.3": {
|
3 |
+
"version": "11.3",
|
4 |
+
"released_at": 1623057021,
|
5 |
+
"hrefs": {
|
6 |
+
"release": "https://shsec.io/shieldrelease113",
|
7 |
+
"upgrade": "https://shsec.io/shieldupgradeguide113"
|
8 |
+
},
|
9 |
+
"title": "",
|
10 |
+
"description": [
|
11 |
+
],
|
12 |
+
"items": [
|
13 |
+
{
|
14 |
+
"type": "new",
|
15 |
+
"pro_only": false,
|
16 |
+
"title": "High IP Reputation Bypass",
|
17 |
+
"description": [
|
18 |
+
"Added an option to ensure that IP addresses with a high-enough reputation are never blocked by Shield."
|
19 |
+
]
|
20 |
+
},
|
21 |
+
{
|
22 |
+
"type": "new",
|
23 |
+
"pro_only": false,
|
24 |
+
"title": "Bot Scoring Logic Is Provisioned From ShieldNET API",
|
25 |
+
"description": [
|
26 |
+
"To allow for easier and faster updates and improvements to the bot scoring logic, they are served from our ShieldNET API.",
|
27 |
+
"If, for whatever reason, the API is unavailable the plugin will use its built-in scoring logic."
|
28 |
+
]
|
29 |
+
},
|
30 |
+
{
|
31 |
+
"type": "new",
|
32 |
+
"pro_only": false,
|
33 |
+
"title": "NotBot Javascript Loading Check",
|
34 |
+
"description": [
|
35 |
+
"The NotBot Javascript that loads for visitor is critical to Shield's ability to detect bots - we now show a warning when we can't detect it."
|
36 |
+
]
|
37 |
+
},
|
38 |
+
{
|
39 |
+
"type": "improved",
|
40 |
+
"pro_only": false,
|
41 |
+
"title": "404 Bot Signal doesn't trigger Shield offense on certain requests for assets",
|
42 |
+
"description": [
|
43 |
+
"404s encountered for requests for assets such as images, javascript and CSS no longer trigger offenses.",
|
44 |
+
"The 1 exception is if the asset URL is within a plugin/theme directory that doesn't exist on the site."
|
45 |
+
]
|
46 |
+
}
|
47 |
+
]
|
48 |
+
},
|
49 |
"11.2": {
|
50 |
"version": "11.2",
|
51 |
"released_at": 1621844125,
|
icwp-wpsf.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
-
* Version: 11.
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
+
* Version: 11.3.0
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
plugin-spec.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "11.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
@@ -255,7 +255,7 @@
|
|
255 |
"introjs"
|
256 |
]
|
257 |
},
|
258 |
-
"shield/
|
259 |
},
|
260 |
"shield/scans": {
|
261 |
"deps": [
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "11.3.0",
|
4 |
+
"release_timestamp": 1623057021,
|
5 |
+
"build": "202106.0701",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
255 |
"introjs"
|
256 |
]
|
257 |
},
|
258 |
+
"shield/notbot": {
|
259 |
},
|
260 |
"shield/scans": {
|
261 |
"deps": [
|
readme.txt
CHANGED
@@ -8,7 +8,7 @@ Requires at least: 3.5.2
|
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 5.7
|
11 |
-
Stable tag: 11.
|
12 |
Security against hackers and brute force bots with firewall, login security hiding and hardening, Antispam, Audit Trail, Live Traffic, and much more...
|
13 |
|
14 |
== Description ==
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 5.7
|
11 |
+
Stable tag: 11.3.0
|
12 |
Security against hackers and brute force bots with firewall, login security hiding and hardening, Antispam, Audit Trail, Live Traffic, and much more...
|
13 |
|
14 |
== Description ==
|
resources/js/shield/{antibot.js → notbot.js}
RENAMED
@@ -1,4 +1,4 @@
|
|
1 |
-
if ( typeof Shield_Antibot === typeof undefined && typeof
|
2 |
|
3 |
var Shield_Antibot = new function () {
|
4 |
|
@@ -26,7 +26,7 @@ if ( typeof Shield_Antibot === typeof undefined && typeof shield_vars_antibotjs
|
|
26 |
* Early execution also helps mitigate the case where login requests are
|
27 |
* sent quickly, before browser has fired NotBot request.
|
28 |
*/
|
29 |
-
if (
|
30 |
sendReq();
|
31 |
}
|
32 |
/**
|
@@ -59,9 +59,9 @@ if ( typeof Shield_Antibot === typeof undefined && typeof shield_vars_antibotjs
|
|
59 |
|
60 |
var sendReq = function ( name ) {
|
61 |
var xhttp = new XMLHttpRequest();
|
62 |
-
xhttp.open( "POST",
|
63 |
xhttp.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded;' );
|
64 |
-
xhttp.send(
|
65 |
request_count++;
|
66 |
};
|
67 |
|
1 |
+
if ( typeof Shield_Antibot === typeof undefined && typeof shield_vars_notbotjs !== typeof undefined ) {
|
2 |
|
3 |
var Shield_Antibot = new function () {
|
4 |
|
26 |
* Early execution also helps mitigate the case where login requests are
|
27 |
* sent quickly, before browser has fired NotBot request.
|
28 |
*/
|
29 |
+
if ( shield_vars_notbotjs.flags.run ) {
|
30 |
sendReq();
|
31 |
}
|
32 |
/**
|
59 |
|
60 |
var sendReq = function ( name ) {
|
61 |
var xhttp = new XMLHttpRequest();
|
62 |
+
xhttp.open( "POST", shield_vars_notbotjs.hrefs.ajax, true );
|
63 |
xhttp.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded;' );
|
64 |
+
xhttp.send( shield_vars_notbotjs.ajax.not_bot );
|
65 |
request_count++;
|
66 |
};
|
67 |
|
src/config/feature-admin_access_restriction.php
CHANGED
@@ -55,8 +55,7 @@
|
|
55 |
"summary": [
|
56 |
"Purpose - Restricts access to key WordPress areas for all users not authenticated with the Security Admin Access system.",
|
57 |
"Recommendation - Use of this feature is highly recommend."
|
58 |
-
]
|
59 |
-
"help_video_id": "339824074"
|
60 |
},
|
61 |
{
|
62 |
"slug": "section_whitelabel",
|
55 |
"summary": [
|
56 |
"Purpose - Restricts access to key WordPress areas for all users not authenticated with the Security Admin Access system.",
|
57 |
"Recommendation - Use of this feature is highly recommend."
|
58 |
+
]
|
|
|
59 |
},
|
60 |
{
|
61 |
"slug": "section_whitelabel",
|
src/config/feature-ips.php
CHANGED
@@ -151,6 +151,19 @@
|
|
151 |
"summary": "AntiBot Testing Threshold (Percentage)",
|
152 |
"description": "When using Shield's AntiBot system, this is the threshold used for testing (between 1 and 99)."
|
153 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
{
|
155 |
"key": "transgression_limit",
|
156 |
"section": "section_auto_black_list",
|
@@ -559,6 +572,18 @@
|
|
559 |
}
|
560 |
],
|
561 |
"definitions": {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
562 |
"db_classes": {
|
563 |
"botsignals": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\BotSignals\\Handler",
|
564 |
"ip_lists": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
|
@@ -648,7 +673,7 @@
|
|
648 |
"stat": false
|
649 |
},
|
650 |
"bottrack_404": {
|
651 |
-
"cat":
|
652 |
"offense": true
|
653 |
},
|
654 |
"bottrack_fakewebcrawler": {
|
@@ -668,7 +693,7 @@
|
|
668 |
"offense": true
|
669 |
},
|
670 |
"bottrack_useragent": {
|
671 |
-
"cat":
|
672 |
"offense": true
|
673 |
},
|
674 |
"bottrack_xmlrpc": {
|
151 |
"summary": "AntiBot Testing Threshold (Percentage)",
|
152 |
"description": "When using Shield's AntiBot system, this is the threshold used for testing (between 1 and 99)."
|
153 |
},
|
154 |
+
{
|
155 |
+
"key": "antibot_high_reputation_minimum",
|
156 |
+
"section": "section_antibot",
|
157 |
+
"default": 200,
|
158 |
+
"type": "integer",
|
159 |
+
"min": 0,
|
160 |
+
"link_info": "https://shsec.io/jy",
|
161 |
+
"link_blog": "https://shsec.io/jz",
|
162 |
+
"beacon_id": 431,
|
163 |
+
"name": "High Reputation Bypass",
|
164 |
+
"summary": "Prevent IPs/Visitors With High Reputation Scores From Being Blocked",
|
165 |
+
"description": "Ensures that visitors with a high reputation are never blocked by Shield."
|
166 |
+
},
|
167 |
{
|
168 |
"key": "transgression_limit",
|
169 |
"section": "section_auto_black_list",
|
572 |
}
|
573 |
],
|
574 |
"definitions": {
|
575 |
+
"allowable_ext_404s": [
|
576 |
+
"js",
|
577 |
+
"css",
|
578 |
+
"gif",
|
579 |
+
"jpg",
|
580 |
+
"jpeg",
|
581 |
+
"png",
|
582 |
+
"map",
|
583 |
+
"ttf",
|
584 |
+
"woff",
|
585 |
+
"woff2"
|
586 |
+
],
|
587 |
"db_classes": {
|
588 |
"botsignals": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\BotSignals\\Handler",
|
589 |
"ip_lists": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\IPs\\Handler"
|
673 |
"stat": false
|
674 |
},
|
675 |
"bottrack_404": {
|
676 |
+
"cat": 1,
|
677 |
"offense": true
|
678 |
},
|
679 |
"bottrack_fakewebcrawler": {
|
693 |
"offense": true
|
694 |
},
|
695 |
"bottrack_useragent": {
|
696 |
+
"cat": 1,
|
697 |
"offense": true
|
698 |
},
|
699 |
"bottrack_xmlrpc": {
|
src/config/feature-plugin.php
CHANGED
@@ -538,10 +538,6 @@
|
|
538 |
}
|
539 |
],
|
540 |
"definitions": {
|
541 |
-
"help_video_id": "",
|
542 |
-
"tracking_cron_handle": "plugin_tracking_cron",
|
543 |
-
"tracking_post_url": "https://tracking.icontrolwp.com/track/plugin/shield",
|
544 |
-
"importexport_cron_name": "autoimport",
|
545 |
"href_privacy_policy": "https://shsec.io/wpshieldprivacypolicy",
|
546 |
"db_classes": {
|
547 |
"geoip": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\GeoIp\\Handler",
|
538 |
}
|
539 |
],
|
540 |
"definitions": {
|
|
|
|
|
|
|
|
|
541 |
"href_privacy_policy": "https://shsec.io/wpshieldprivacypolicy",
|
542 |
"db_classes": {
|
543 |
"geoip": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\GeoIp\\Handler",
|
src/lib/src/Databases/AuditTrail/Select.php
CHANGED
@@ -24,12 +24,12 @@ class Select extends Base\Select {
|
|
24 |
}
|
25 |
|
26 |
/**
|
27 |
-
* @param string $
|
28 |
* @return $this
|
29 |
*/
|
30 |
-
public function filterByEvent( $
|
31 |
-
if ( !empty( $
|
32 |
-
$this->addWhereEquals( 'event', $
|
33 |
}
|
34 |
return $this;
|
35 |
}
|
24 |
}
|
25 |
|
26 |
/**
|
27 |
+
* @param string $event
|
28 |
* @return $this
|
29 |
*/
|
30 |
+
public function filterByEvent( $event ) {
|
31 |
+
if ( !empty( $event ) && strtolower( $event ) != 'all' ) {
|
32 |
+
$this->addWhereEquals( 'event', $event );
|
33 |
}
|
34 |
return $this;
|
35 |
}
|
src/lib/src/Databases/Base/BaseQuery.php
CHANGED
@@ -194,23 +194,13 @@ abstract class BaseQuery {
|
|
194 |
* @return string
|
195 |
*/
|
196 |
public function buildWhere() {
|
197 |
-
|
198 |
-
if (
|
199 |
-
$wheres =
|
200 |
-
if ( !$this->isIncludeSoftDeletedRows() ) {
|
201 |
-
$wheres[] = [ 'deleted_at', '=', 0 ];
|
202 |
-
}
|
203 |
-
$wheres = array_map( function ( array $where ) {
|
204 |
-
return $this->rawWhereToString( $where );
|
205 |
-
}, $wheres );
|
206 |
}
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
$wheres[] = '`deleted_at`=0';
|
211 |
-
}
|
212 |
-
}
|
213 |
-
|
214 |
return implode( ' AND ', $wheres );
|
215 |
}
|
216 |
|
@@ -394,7 +384,7 @@ abstract class BaseQuery {
|
|
394 |
return $this->setLimit( 0 )
|
395 |
->setRawWheres( [] )
|
396 |
->setPage( 1 )
|
397 |
-
->setOrderBy(
|
398 |
}
|
399 |
|
400 |
/**
|
194 |
* @return string
|
195 |
*/
|
196 |
public function buildWhere() {
|
197 |
+
$wheres = $this->getRawWheres();
|
198 |
+
if ( !$this->isIncludeSoftDeletedRows() ) {
|
199 |
+
$wheres[] = [ 'deleted_at', '=', 0 ];
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
}
|
201 |
+
$wheres = array_map( function ( array $where ) {
|
202 |
+
return $this->rawWhereToString( $where );
|
203 |
+
}, $wheres );
|
|
|
|
|
|
|
|
|
204 |
return implode( ' AND ', $wheres );
|
205 |
}
|
206 |
|
384 |
return $this->setLimit( 0 )
|
385 |
->setRawWheres( [] )
|
386 |
->setPage( 1 )
|
387 |
+
->setOrderBy( '' );
|
388 |
}
|
389 |
|
390 |
/**
|
src/lib/src/Databases/Base/EntryVoConsumer.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
|
4 |
|
@@ -11,13 +11,13 @@ trait EntryVoConsumer {
|
|
11 |
/**
|
12 |
* @var EntryVO
|
13 |
*/
|
14 |
-
private $
|
15 |
|
16 |
/**
|
17 |
* @return EntryVO|mixed
|
18 |
*/
|
19 |
public function getEntryVO() {
|
20 |
-
return $this->
|
21 |
}
|
22 |
|
23 |
/**
|
@@ -25,7 +25,7 @@ trait EntryVoConsumer {
|
|
25 |
* @return $this
|
26 |
*/
|
27 |
public function setEntryVO( $entry ) {
|
28 |
-
$this->
|
29 |
return $this;
|
30 |
}
|
31 |
}
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
|
4 |
|
11 |
/**
|
12 |
* @var EntryVO
|
13 |
*/
|
14 |
+
private $entryVO;
|
15 |
|
16 |
/**
|
17 |
* @return EntryVO|mixed
|
18 |
*/
|
19 |
public function getEntryVO() {
|
20 |
+
return $this->entryVO;
|
21 |
}
|
22 |
|
23 |
/**
|
25 |
* @return $this
|
26 |
*/
|
27 |
public function setEntryVO( $entry ) {
|
28 |
+
$this->entryVO = $entry;
|
29 |
return $this;
|
30 |
}
|
31 |
}
|
src/lib/src/Databases/Base/Handler.php
CHANGED
@@ -91,10 +91,6 @@ abstract class Handler extends ExecOnceModConsumer {
|
|
91 |
}
|
92 |
}
|
93 |
|
94 |
-
protected function getColumnForOlderThanComparison() :string {
|
95 |
-
return 'created_at';
|
96 |
-
}
|
97 |
-
|
98 |
/**
|
99 |
* @param int $timestamp
|
100 |
* @return bool
|
91 |
}
|
92 |
}
|
93 |
|
|
|
|
|
|
|
|
|
94 |
/**
|
95 |
* @param int $timestamp
|
96 |
* @return bool
|
src/lib/src/Databases/Events/Common.php
CHANGED
@@ -9,18 +9,18 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Events;
|
|
9 |
trait Common {
|
10 |
|
11 |
/**
|
12 |
-
* @param string $
|
13 |
* @return $this
|
14 |
*/
|
15 |
-
public function filterByEvent( $
|
16 |
-
return $this->filterByEvents( [ $
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
-
* @param string[] $
|
21 |
* @return $this
|
22 |
*/
|
23 |
-
public function filterByEvents( $
|
24 |
-
return $this->addWhereIn( 'event', $
|
25 |
}
|
26 |
}
|
9 |
trait Common {
|
10 |
|
11 |
/**
|
12 |
+
* @param string $event
|
13 |
* @return $this
|
14 |
*/
|
15 |
+
public function filterByEvent( $event ) {
|
16 |
+
return $this->filterByEvents( [ $event ] );
|
17 |
}
|
18 |
|
19 |
/**
|
20 |
+
* @param string[] $events
|
21 |
* @return $this
|
22 |
*/
|
23 |
+
public function filterByEvents( array $events ) {
|
24 |
+
return $this->addWhereIn( 'event', $events );
|
25 |
}
|
26 |
}
|
src/lib/src/Databases/Events/Select.php
CHANGED
@@ -26,12 +26,8 @@ class Select extends Base\Select {
|
|
26 |
->sum();
|
27 |
}
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
* @return int
|
32 |
-
*/
|
33 |
-
public function sumEventsLike( $sEvent ) {
|
34 |
-
return (int)$this->addWhereLike( 'event', $sEvent )
|
35 |
->setColumnsToSelect( [ 'count' ] )
|
36 |
->sum();
|
37 |
}
|
@@ -46,17 +42,17 @@ class Select extends Base\Select {
|
|
46 |
|
47 |
natsort( $allEvents );
|
48 |
foreach ( $allEvents as $event ) {
|
49 |
-
$sums[ $event ] = $this->clearWheres()->sumEvent( $event );
|
50 |
}
|
51 |
return $sums;
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
-
* @param string $
|
56 |
* @return EntryVO|null
|
57 |
*/
|
58 |
-
public function getLatestForEvent( $
|
59 |
-
return $this->filterByEvent( $
|
60 |
->setOrderBy( 'created_at', 'DESC' )
|
61 |
->setResultsAsVo( true )
|
62 |
->first();
|
26 |
->sum();
|
27 |
}
|
28 |
|
29 |
+
public function sumEventsLike( string $event ) :int {
|
30 |
+
return (int)$this->addWhereLike( 'event', $event )
|
|
|
|
|
|
|
|
|
31 |
->setColumnsToSelect( [ 'count' ] )
|
32 |
->sum();
|
33 |
}
|
42 |
|
43 |
natsort( $allEvents );
|
44 |
foreach ( $allEvents as $event ) {
|
45 |
+
$sums[ $event ] = (int)$this->clearWheres()->sumEvent( $event );
|
46 |
}
|
47 |
return $sums;
|
48 |
}
|
49 |
|
50 |
/**
|
51 |
+
* @param string $event
|
52 |
* @return EntryVO|null
|
53 |
*/
|
54 |
+
public function getLatestForEvent( string $event ) {
|
55 |
+
return $this->filterByEvent( $event )
|
56 |
->setOrderBy( 'created_at', 'DESC' )
|
57 |
->setResultsAsVo( true )
|
58 |
->first();
|
src/lib/src/Modules/AuditTrail/Lib/AuditWriter.php
CHANGED
@@ -23,9 +23,6 @@ class AuditWriter extends EventsListener {
|
|
23 |
*/
|
24 |
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
25 |
$con = $this->getCon();
|
26 |
-
if ( empty( $def ) ) { // TODO: @deprecated 11.2 - remove this if
|
27 |
-
$def = $con->loadEventsService()->getEventDef( $evt );
|
28 |
-
}
|
29 |
if ( $def[ 'audit' ] && empty( $meta[ 'suppress_audit' ] ) ) { // only audit if it's an auditable event
|
30 |
$entry = new AuditTrail\EntryVO();
|
31 |
$entry->rid = $con->getShortRequestId();
|
23 |
*/
|
24 |
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
25 |
$con = $this->getCon();
|
|
|
|
|
|
|
26 |
if ( $def[ 'audit' ] && empty( $meta[ 'suppress_audit' ] ) ) { // only audit if it's an auditable event
|
27 |
$entry = new AuditTrail\EntryVO();
|
28 |
$entry->rid = $con->getShortRequestId();
|
src/lib/src/Modules/AuditTrail/Lib/Ops/Commit.php
CHANGED
@@ -56,7 +56,7 @@ class Commit {
|
|
56 |
->filterByCreatedAt( Services::Request()->carbon()->subDay()->timestamp, '>' )
|
57 |
->first();
|
58 |
$canCount = ( $latest instanceof AuditTrail\EntryVO )
|
59 |
-
&& (
|
60 |
}
|
61 |
|
62 |
if ( $canCount ) {
|
56 |
->filterByCreatedAt( Services::Request()->carbon()->subDay()->timestamp, '>' )
|
57 |
->first();
|
58 |
$canCount = ( $latest instanceof AuditTrail\EntryVO )
|
59 |
+
&& ( $latest->ip === $entry->ip );
|
60 |
}
|
61 |
|
62 |
if ( $canCount ) {
|
src/lib/src/Modules/AuditTrail/Options.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail;
|
4 |
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\AuditTrail;
|
4 |
|
src/lib/src/Modules/Base/ModCon.php
CHANGED
@@ -565,52 +565,6 @@ abstract class ModCon {
|
|
565 |
return $this->sModSlug;
|
566 |
}
|
567 |
|
568 |
-
/**
|
569 |
-
* @param array $items
|
570 |
-
* @return array
|
571 |
-
* @deprecated 11.2
|
572 |
-
*/
|
573 |
-
public function supplySubMenuItem( $items ) {
|
574 |
-
|
575 |
-
$title = $this->getOptions()->getFeatureProperty( 'menu_title' );
|
576 |
-
$title = empty( $title ) ? $this->getMainFeatureName() : __( $title, 'wp-simple-firewall' );
|
577 |
-
|
578 |
-
if ( !empty( $title ) ) {
|
579 |
-
$highlightedTemplate = '<span class="shield_highlighted_menu">%s</span>';
|
580 |
-
$humanName = $this->getCon()->getHumanName();
|
581 |
-
|
582 |
-
if ( $this->getOptions()->getFeatureProperty( 'highlight_menu_item' ) ) {
|
583 |
-
$title = sprintf( $highlightedTemplate, $title );
|
584 |
-
}
|
585 |
-
|
586 |
-
$menuPageTitle = $title.' - '.$humanName;
|
587 |
-
$items[ $menuPageTitle ] = [
|
588 |
-
$title,
|
589 |
-
$this->getModSlug(),
|
590 |
-
[ $this, 'displayModuleAdminPage' ],
|
591 |
-
$this->getIfShowModuleMenuItem()
|
592 |
-
];
|
593 |
-
|
594 |
-
foreach ( $this->getOptions()->getAdditionalMenuItems() as $menuItem ) {
|
595 |
-
|
596 |
-
// special case: don't show go pro if you're pro.
|
597 |
-
if ( $menuItem[ 'slug' ] !== 'pro-redirect' || !$this->isPremium() ) {
|
598 |
-
|
599 |
-
$title = __( $menuItem[ 'title' ], 'wp-simple-firewall' );
|
600 |
-
$menuPageTitle = $humanName.' - '.$title;
|
601 |
-
$isHighlighted = $menuItem[ 'highlight' ] ?? false;
|
602 |
-
$items[ $menuPageTitle ] = [
|
603 |
-
$isHighlighted ? sprintf( $highlightedTemplate, $title ) : $title,
|
604 |
-
$this->prefix( $menuItem[ 'slug' ] ),
|
605 |
-
[ $this, $menuItem[ 'callback' ] ?? '' ],
|
606 |
-
true
|
607 |
-
];
|
608 |
-
}
|
609 |
-
}
|
610 |
-
}
|
611 |
-
return $items;
|
612 |
-
}
|
613 |
-
|
614 |
/**
|
615 |
* Handles the case where we want to redirect certain menu requests to other pages
|
616 |
* of the plugin automatically. It lets us create custom menu items.
|
@@ -970,14 +924,6 @@ abstract class ModCon {
|
|
970 |
return $this;
|
971 |
}
|
972 |
|
973 |
-
/**
|
974 |
-
* @deprecated 11.2
|
975 |
-
*/
|
976 |
-
protected function isThisModAdminPage() :bool {
|
977 |
-
return is_admin() && !Services::WpGeneral()->isAjax()
|
978 |
-
&& Services::Request()->isGet() && $this->isThisModulePage();
|
979 |
-
}
|
980 |
-
|
981 |
public function isPremium() :bool {
|
982 |
return $this->getCon()->isPremiumActive();
|
983 |
}
|
@@ -1375,7 +1321,6 @@ abstract class ModCon {
|
|
1375 |
->setOptionsStorageKey( $this->getOptionsStorageKey() )
|
1376 |
->setIfLoadOptionsFromStorage( !$con->getIsResetPlugin() );
|
1377 |
$opts = $this->opts;
|
1378 |
-
/** @deprecated 11.2 */
|
1379 |
}
|
1380 |
return $opts;
|
1381 |
}
|
565 |
return $this->sModSlug;
|
566 |
}
|
567 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
568 |
/**
|
569 |
* Handles the case where we want to redirect certain menu requests to other pages
|
570 |
* of the plugin automatically. It lets us create custom menu items.
|
924 |
return $this;
|
925 |
}
|
926 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
927 |
public function isPremium() :bool {
|
928 |
return $this->getCon()->isPremiumActive();
|
929 |
}
|
1321 |
->setOptionsStorageKey( $this->getOptionsStorageKey() )
|
1322 |
->setIfLoadOptionsFromStorage( !$con->getIsResetPlugin() );
|
1323 |
$opts = $this->opts;
|
|
|
1324 |
}
|
1325 |
return $opts;
|
1326 |
}
|
src/lib/src/Modules/BaseShield/ModCon.php
CHANGED
@@ -43,13 +43,6 @@ class ModCon extends Base\ModCon {
|
|
43 |
->getCurrent();
|
44 |
}
|
45 |
|
46 |
-
/**
|
47 |
-
* @deprecated 11.2
|
48 |
-
*/
|
49 |
-
public function hasValidRequestIP() :bool {
|
50 |
-
return !empty( Services::IP()->isValidIp( Services::IP()->getRequestIp() ) );
|
51 |
-
}
|
52 |
-
|
53 |
public function onWpInit() {
|
54 |
parent::onWpInit();
|
55 |
if ( $this->isThisModulePage() && !$this->isWizardPage() && ( $this->getSlug() != 'insights' ) ) {
|
@@ -234,14 +227,4 @@ class ModCon extends Base\ModCon {
|
|
234 |
$this->getBaseNamespace(),
|
235 |
];
|
236 |
}
|
237 |
-
|
238 |
-
/**
|
239 |
-
* @return bool
|
240 |
-
* @deprecated 11.2
|
241 |
-
*/
|
242 |
-
public function isEnabledWhitelabel() :bool {
|
243 |
-
/** @var SecurityAdmin\Options $opts */
|
244 |
-
$opts = $this->getCon()->getModule_SecAdmin()->getOptions();
|
245 |
-
return $opts->isEnabledWhitelabel();
|
246 |
-
}
|
247 |
}
|
43 |
->getCurrent();
|
44 |
}
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
public function onWpInit() {
|
47 |
parent::onWpInit();
|
48 |
if ( $this->isThisModulePage() && !$this->isWizardPage() && ( $this->getSlug() != 'insights' ) ) {
|
227 |
$this->getBaseNamespace(),
|
228 |
];
|
229 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
}
|
src/lib/src/Modules/Events/Consolidate/ConsolidateAllEvents.php
CHANGED
@@ -22,9 +22,9 @@ class ConsolidateAllEvents {
|
|
22 |
}
|
23 |
|
24 |
/**
|
25 |
-
* @param $
|
26 |
*/
|
27 |
-
protected function consolidateEventIntoHourly( $
|
28 |
/** @var ModCon $mod */
|
29 |
$mod = $this->getMod();
|
30 |
$oDbH = $mod->getDbHandler_Events();
|
@@ -39,7 +39,7 @@ class ConsolidateAllEvents {
|
|
39 |
/** @var Events\Select $oSel */
|
40 |
$oSel = $oDbH->getQuerySelector();
|
41 |
$nRecords = $oSel->filterByBoundary_Hour( $oTime->timestamp )
|
42 |
-
->filterByEvent( $
|
43 |
->count();
|
44 |
|
45 |
if ( $nRecords > 1 ) {
|
@@ -47,17 +47,17 @@ class ConsolidateAllEvents {
|
|
47 |
$oSel = $oDbH->getQuerySelector();
|
48 |
/** @var Events\EntryVO[] $aRecords */
|
49 |
$nSum = $oSel->filterByBoundary_Hour( $oTime->timestamp )
|
50 |
-
->sumEvent( $
|
51 |
if ( $nSum > 0 ) {
|
52 |
|
53 |
/** @var Events\Delete $oDel */
|
54 |
$oDel = $oDbH->getQueryDeleter();
|
55 |
$oDel->filterByBoundary_Hour( $oTime->timestamp )
|
56 |
-
->filterByEvent( $
|
57 |
->query();
|
58 |
|
59 |
$oEntry = new Events\EntryVO();
|
60 |
-
$oEntry->event = $
|
61 |
$oEntry->count = $nSum;
|
62 |
$oEntry->created_at = $oTime->timestamp + 1;
|
63 |
/** @var Events\Insert $oQI */
|
@@ -74,52 +74,52 @@ class ConsolidateAllEvents {
|
|
74 |
/**
|
75 |
* Consolidates each event in Daily sums. Doesn't process events from the previous 48hrs.
|
76 |
* Processes event for the 7 days previous to the last 48 hours.
|
77 |
-
* @param $
|
78 |
*/
|
79 |
-
protected function consolidateEventIntoDaily( $
|
80 |
/** @var ModCon $mod */
|
81 |
$mod = $this->getMod();
|
82 |
-
$
|
83 |
|
84 |
-
$
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
|
89 |
$nDayCount = 0;
|
90 |
do {
|
91 |
-
/** @var Events\Select $
|
92 |
-
$
|
93 |
-
$
|
94 |
-
|
95 |
-
|
96 |
|
97 |
-
if ( $
|
98 |
/** @var Events\Select $oSel */
|
99 |
-
$
|
100 |
/** @var Events\EntryVO[] $aRecords */
|
101 |
-
$nSum = $
|
102 |
-
|
103 |
if ( $nSum > 0 ) {
|
104 |
|
105 |
-
/** @var Events\Delete $
|
106 |
-
$
|
107 |
-
$
|
108 |
-
|
109 |
-
|
110 |
|
111 |
$oEntry = new Events\EntryVO();
|
112 |
-
$oEntry->event = $
|
113 |
$oEntry->count = $nSum;
|
114 |
-
$oEntry->created_at = $
|
115 |
/** @var Events\Insert $oQI */
|
116 |
-
$oQI = $
|
117 |
$oQI->insert( $oEntry );
|
118 |
}
|
119 |
}
|
120 |
|
121 |
$nDayCount++;
|
122 |
-
$
|
123 |
} while ( $nDayCount < 13 );
|
124 |
}
|
125 |
|
22 |
}
|
23 |
|
24 |
/**
|
25 |
+
* @param $event
|
26 |
*/
|
27 |
+
protected function consolidateEventIntoHourly( $event ) {
|
28 |
/** @var ModCon $mod */
|
29 |
$mod = $this->getMod();
|
30 |
$oDbH = $mod->getDbHandler_Events();
|
39 |
/** @var Events\Select $oSel */
|
40 |
$oSel = $oDbH->getQuerySelector();
|
41 |
$nRecords = $oSel->filterByBoundary_Hour( $oTime->timestamp )
|
42 |
+
->filterByEvent( $event )
|
43 |
->count();
|
44 |
|
45 |
if ( $nRecords > 1 ) {
|
47 |
$oSel = $oDbH->getQuerySelector();
|
48 |
/** @var Events\EntryVO[] $aRecords */
|
49 |
$nSum = $oSel->filterByBoundary_Hour( $oTime->timestamp )
|
50 |
+
->sumEvent( $event );
|
51 |
if ( $nSum > 0 ) {
|
52 |
|
53 |
/** @var Events\Delete $oDel */
|
54 |
$oDel = $oDbH->getQueryDeleter();
|
55 |
$oDel->filterByBoundary_Hour( $oTime->timestamp )
|
56 |
+
->filterByEvent( $event )
|
57 |
->query();
|
58 |
|
59 |
$oEntry = new Events\EntryVO();
|
60 |
+
$oEntry->event = $event;
|
61 |
$oEntry->count = $nSum;
|
62 |
$oEntry->created_at = $oTime->timestamp + 1;
|
63 |
/** @var Events\Insert $oQI */
|
74 |
/**
|
75 |
* Consolidates each event in Daily sums. Doesn't process events from the previous 48hrs.
|
76 |
* Processes event for the 7 days previous to the last 48 hours.
|
77 |
+
* @param $event
|
78 |
*/
|
79 |
+
protected function consolidateEventIntoDaily( $event ) {
|
80 |
/** @var ModCon $mod */
|
81 |
$mod = $this->getMod();
|
82 |
+
$dbh = $mod->getDbHandler_Events();
|
83 |
|
84 |
+
$time = Services::Request()
|
85 |
+
->carbon()
|
86 |
+
->subDays( 2 )
|
87 |
+
->startOfDay();
|
88 |
|
89 |
$nDayCount = 0;
|
90 |
do {
|
91 |
+
/** @var Events\Select $select */
|
92 |
+
$select = $dbh->getQuerySelector();
|
93 |
+
$recordsCount = $select->filterByBoundary_Day( $time->timestamp )
|
94 |
+
->filterByEvent( $event )
|
95 |
+
->count();
|
96 |
|
97 |
+
if ( $recordsCount > 1 ) {
|
98 |
/** @var Events\Select $oSel */
|
99 |
+
$select = $dbh->getQuerySelector();
|
100 |
/** @var Events\EntryVO[] $aRecords */
|
101 |
+
$nSum = $select->filterByBoundary_Day( $time->timestamp )
|
102 |
+
->sumEvent( $event );
|
103 |
if ( $nSum > 0 ) {
|
104 |
|
105 |
+
/** @var Events\Delete $deleter */
|
106 |
+
$deleter = $dbh->getQueryDeleter();
|
107 |
+
$deleter->filterByBoundary_Day( $time->timestamp )
|
108 |
+
->filterByEvent( $event )
|
109 |
+
->query();
|
110 |
|
111 |
$oEntry = new Events\EntryVO();
|
112 |
+
$oEntry->event = $event;
|
113 |
$oEntry->count = $nSum;
|
114 |
+
$oEntry->created_at = $time->timestamp + 1;
|
115 |
/** @var Events\Insert $oQI */
|
116 |
+
$oQI = $dbh->getQueryInserter();
|
117 |
$oQI->insert( $oEntry );
|
118 |
}
|
119 |
}
|
120 |
|
121 |
$nDayCount++;
|
122 |
+
$time->subDay();
|
123 |
} while ( $nDayCount < 13 );
|
124 |
}
|
125 |
|
src/lib/src/Modules/Events/Lib/Reports/ScanRepairs.php
CHANGED
@@ -17,28 +17,28 @@ class ScanRepairs extends BaseReporter {
|
|
17 |
|
18 |
/** @var Events\ModCon $mod */
|
19 |
$mod = $this->getMod();
|
20 |
-
/** @var DBEvents\Select $
|
21 |
-
$
|
22 |
-
/** @var Events\Strings $
|
23 |
-
$
|
24 |
|
25 |
-
$
|
26 |
|
27 |
-
$
|
28 |
|
29 |
/** @var Options $oHGOptions */
|
30 |
$oHGOptions = $this->getCon()->getModule_HackGuard()->getOptions();
|
31 |
-
foreach ( $oHGOptions->getScanSlugs() as $
|
32 |
try {
|
33 |
-
$
|
34 |
-
$
|
35 |
-
->filterByEvent( $
|
36 |
-
->filterByBoundary( $
|
37 |
->count();
|
38 |
-
if ( $
|
39 |
-
$
|
40 |
-
'count' => $
|
41 |
-
'name' => $
|
42 |
];
|
43 |
}
|
44 |
}
|
@@ -46,12 +46,12 @@ class ScanRepairs extends BaseReporter {
|
|
46 |
}
|
47 |
}
|
48 |
|
49 |
-
if ( count( $
|
50 |
$aAlerts[] = $this->getMod()->renderTemplate(
|
51 |
'/components/reports/mod/events/info_keystats.twig',
|
52 |
[
|
53 |
'vars' => [
|
54 |
-
'counts' => $
|
55 |
],
|
56 |
'strings' => [
|
57 |
'title' => __( 'Scanner Repairs', 'wp-simple-firewall' ),
|
17 |
|
18 |
/** @var Events\ModCon $mod */
|
19 |
$mod = $this->getMod();
|
20 |
+
/** @var DBEvents\Select $selectorEvents */
|
21 |
+
$selectorEvents = $mod->getDbHandler_Events()->getQuerySelector();
|
22 |
+
/** @var Events\Strings $strings */
|
23 |
+
$strings = $mod->getStrings();
|
24 |
|
25 |
+
$report = $this->getReport();
|
26 |
|
27 |
+
$counts = [];
|
28 |
|
29 |
/** @var Options $oHGOptions */
|
30 |
$oHGOptions = $this->getCon()->getModule_HackGuard()->getOptions();
|
31 |
+
foreach ( $oHGOptions->getScanSlugs() as $scan ) {
|
32 |
try {
|
33 |
+
$event = $scan.'_item_repair_success';
|
34 |
+
$count = $selectorEvents
|
35 |
+
->filterByEvent( $event )
|
36 |
+
->filterByBoundary( $report->interval_start_at, $report->interval_end_at )
|
37 |
->count();
|
38 |
+
if ( $count > 0 ) {
|
39 |
+
$counts[ $scan ] = [
|
40 |
+
'count' => $count,
|
41 |
+
'name' => $strings->getEventName( $event ),
|
42 |
];
|
43 |
}
|
44 |
}
|
46 |
}
|
47 |
}
|
48 |
|
49 |
+
if ( count( $counts ) > 0 ) {
|
50 |
$aAlerts[] = $this->getMod()->renderTemplate(
|
51 |
'/components/reports/mod/events/info_keystats.twig',
|
52 |
[
|
53 |
'vars' => [
|
54 |
+
'counts' => $counts
|
55 |
],
|
56 |
'strings' => [
|
57 |
'title' => __( 'Scanner Repairs', 'wp-simple-firewall' ),
|
src/lib/src/Modules/Events/Lib/StatsWriter.php
CHANGED
@@ -21,9 +21,6 @@ class StatsWriter extends EventsListener {
|
|
21 |
* @param array $def
|
22 |
*/
|
23 |
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
24 |
-
if ( empty( $def ) ) { // TODO: @deprecated 11.2 - remove this if
|
25 |
-
$def = $this->getCon()->loadEventsService()->getEventDef( $evt );
|
26 |
-
}
|
27 |
if ( !empty( $def[ 'stat' ] ) ) {
|
28 |
$stats = $this->getEventStats();
|
29 |
$stats[ $evt ] = $meta[ 'ts' ] ?? Services::Request()->ts();
|
21 |
* @param array $def
|
22 |
*/
|
23 |
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
|
|
|
|
|
|
24 |
if ( !empty( $def[ 'stat' ] ) ) {
|
25 |
$stats = $this->getEventStats();
|
26 |
$stats[ $evt ] = $meta[ 'ts' ] ?? Services::Request()->ts();
|
src/lib/src/Modules/HackGuard/Scan/Controller/Base.php
CHANGED
@@ -202,18 +202,6 @@ abstract class Base extends ExecOnceModConsumer {
|
|
202 |
return $this->isPremiumOnly() && !$this->getCon()->isPremiumActive();
|
203 |
}
|
204 |
|
205 |
-
/**
|
206 |
-
* @return bool
|
207 |
-
* @deprecated 11.2
|
208 |
-
*/
|
209 |
-
public function isScanningAvailable() :bool {
|
210 |
-
/** @var ModCon $mod */
|
211 |
-
$mod = $this->getMod();
|
212 |
-
/** @var HackGuard\Options $opts */
|
213 |
-
$opts = $this->getOptions();
|
214 |
-
return $mod->isModuleEnabled() && ( !$this->isPremiumOnly() || $opts->isPremium() );
|
215 |
-
}
|
216 |
-
|
217 |
/**
|
218 |
* @return $this
|
219 |
*/
|
202 |
return $this->isPremiumOnly() && !$this->getCon()->isPremiumActive();
|
203 |
}
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
/**
|
206 |
* @return $this
|
207 |
*/
|
src/lib/src/Modules/IPs/BotTrack/Base.php
CHANGED
@@ -2,15 +2,11 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
|
4 |
|
5 |
-
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
9 |
|
10 |
-
abstract class Base {
|
11 |
-
|
12 |
-
use Shield\Modules\ModConsumer;
|
13 |
-
use ExecOnce;
|
14 |
|
15 |
const OPT_KEY = '';
|
16 |
|
@@ -18,28 +14,34 @@ abstract class Base {
|
|
18 |
$this->process();
|
19 |
}
|
20 |
|
21 |
-
protected function doTransgression() {
|
22 |
/** @var IPs\Options $opts */
|
23 |
$opts = $this->getOptions();
|
24 |
|
25 |
-
$
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
$
|
|
|
|
|
34 |
}
|
35 |
|
|
|
|
|
|
|
|
|
36 |
$this->getCon()
|
37 |
->fireEvent(
|
38 |
'bot'.static::OPT_KEY,
|
39 |
[
|
40 |
'audit' => $this->getAuditData(),
|
41 |
-
'offense_count' => $
|
42 |
-
'block' => $
|
43 |
]
|
44 |
);
|
45 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
+
abstract class Base extends Shield\Modules\Base\Common\ExecOnceModConsumer {
|
|
|
|
|
|
|
10 |
|
11 |
const OPT_KEY = '';
|
12 |
|
14 |
$this->process();
|
15 |
}
|
16 |
|
17 |
+
protected function doTransgression( bool $fireEventOnly = false ) {
|
18 |
/** @var IPs\Options $opts */
|
19 |
$opts = $this->getOptions();
|
20 |
|
21 |
+
$count = 0;
|
22 |
+
$block = false;
|
23 |
+
|
24 |
+
if ( !$fireEventOnly ) {
|
25 |
+
$block = $opts->isTrackOptImmediateBlock( static::OPT_KEY );
|
26 |
+
if ( $block ) {
|
27 |
+
$count = 1;
|
28 |
+
}
|
29 |
+
elseif ( $opts->isTrackOptTransgression( static::OPT_KEY ) ) {
|
30 |
+
$count = $opts->isTrackOptDoubleTransgression( static::OPT_KEY ) ? 2 : 1;
|
31 |
+
}
|
32 |
}
|
33 |
|
34 |
+
$this->fireEvent( $count, $block );
|
35 |
+
}
|
36 |
+
|
37 |
+
protected function fireEvent( $offenseCount = 0, $isBlock = false ) {
|
38 |
$this->getCon()
|
39 |
->fireEvent(
|
40 |
'bot'.static::OPT_KEY,
|
41 |
[
|
42 |
'audit' => $this->getAuditData(),
|
43 |
+
'offense_count' => $offenseCount,
|
44 |
+
'block' => $isBlock,
|
45 |
]
|
46 |
);
|
47 |
}
|
src/lib/src/Modules/IPs/BotTrack/Track404.php
CHANGED
@@ -2,6 +2,8 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
|
4 |
|
|
|
|
|
5 |
class Track404 extends Base {
|
6 |
|
7 |
const OPT_KEY = 'track_404';
|
@@ -9,8 +11,64 @@ class Track404 extends Base {
|
|
9 |
protected function process() {
|
10 |
add_action( 'template_redirect', function () {
|
11 |
if ( is_404() ) {
|
12 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
}
|
14 |
} );
|
15 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
class Track404 extends Base {
|
8 |
|
9 |
const OPT_KEY = 'track_404';
|
11 |
protected function process() {
|
12 |
add_action( 'template_redirect', function () {
|
13 |
if ( is_404() ) {
|
14 |
+
$reqPath = $this->getRequestPath();
|
15 |
+
$extensions = implode( '|', $this->getAllowableExtensions() );
|
16 |
+
|
17 |
+
// if the request's file extension is allowed to trigger 404s, we fire only the event, without transgression.
|
18 |
+
// However, if the requested asset is within for a plugin or theme that doesn't exists, it's not allowed.
|
19 |
+
$allowed = preg_match( sprintf( '#\.(%s)$#i', $extensions ), $reqPath ) === 1
|
20 |
+
&& !$this->isRequestToInvalidPlugin()
|
21 |
+
&& !$this->isRequestToInvalidTheme();
|
22 |
+
|
23 |
+
$this->doTransgression( $allowed );
|
24 |
}
|
25 |
} );
|
26 |
}
|
27 |
+
|
28 |
+
private function isRequestToInvalidPlugin() :bool {
|
29 |
+
$isInvalid = false;
|
30 |
+
|
31 |
+
$reqPath = $this->getRequestPath();
|
32 |
+
$pathToPlugins = ltrim( wp_parse_url( plugins_url(), PHP_URL_PATH ), '/' );
|
33 |
+
|
34 |
+
if ( strpos( $reqPath, $pathToPlugins ) === 0 ) {
|
35 |
+
$assetStub = trim( str_replace( $pathToPlugins, '', $reqPath ), '/' );
|
36 |
+
if ( substr_count( $assetStub, '/' ) > 0 ) {
|
37 |
+
$dir = explode( '/', $assetStub, 2 )[ 0 ];
|
38 |
+
$file = Services::WpPlugins()->findPluginFileFromDirName( $dir );
|
39 |
+
if ( empty( $file ) ) {
|
40 |
+
$isInvalid = true;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
return $isInvalid;
|
46 |
+
}
|
47 |
+
|
48 |
+
private function isRequestToInvalidTheme() :bool {
|
49 |
+
$isInvalid = false;
|
50 |
+
|
51 |
+
$reqPath = $this->getRequestPath();
|
52 |
+
$pathsToThemes = ltrim( dirname( wp_parse_url( get_stylesheet_directory_uri(), PHP_URL_PATH ) ), '/' );
|
53 |
+
|
54 |
+
if ( strpos( $reqPath, $pathsToThemes ) === 0 ) {
|
55 |
+
$assetStub = trim( str_replace( $pathsToThemes, '', $reqPath ), '/' );
|
56 |
+
if ( substr_count( $assetStub, '/' ) > 0 ) {
|
57 |
+
$dir = explode( '/', $assetStub, 2 )[ 0 ];
|
58 |
+
$isInvalid = !Services::WpThemes()->getExists( $dir );
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
return $isInvalid;
|
63 |
+
}
|
64 |
+
|
65 |
+
private function getAllowableExtensions() :array {
|
66 |
+
$defExts = $this->getOptions()->getDef( 'allowable_ext_404s' );
|
67 |
+
$extensions = apply_filters( 'shield/allowable_extensions_404s', $defExts );
|
68 |
+
return is_array( $extensions ) ? $extensions : $defExts;
|
69 |
+
}
|
70 |
+
|
71 |
+
private function getRequestPath() :string {
|
72 |
+
return ltrim( Services::Request()->getPath(), '/' );
|
73 |
+
}
|
74 |
}
|
src/lib/src/Modules/IPs/BotTrack/TrackCommentSpam.php
CHANGED
@@ -2,13 +2,9 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
|
4 |
|
5 |
-
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
7 |
|
8 |
-
class TrackCommentSpam {
|
9 |
-
|
10 |
-
use Shield\Modules\ModConsumer;
|
11 |
-
use ExecOnce;
|
12 |
|
13 |
protected function canRun() :bool {
|
14 |
return is_admin() || is_network_admin();
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
|
7 |
+
class TrackCommentSpam extends Shield\Modules\Base\Common\ExecOnceModConsumer {
|
|
|
|
|
|
|
8 |
|
9 |
protected function canRun() :bool {
|
10 |
return is_admin() || is_network_admin();
|
src/lib/src/Modules/IPs/Components/IpAddressConsumer.php
CHANGED
@@ -4,18 +4,8 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components;
|
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
|
7 |
-
/**
|
8 |
-
* Trait BaseIp
|
9 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components
|
10 |
-
*/
|
11 |
trait IpAddressConsumer {
|
12 |
|
13 |
-
/**
|
14 |
-
* @var string
|
15 |
-
* @deprecated 11.2
|
16 |
-
*/
|
17 |
-
private $sIpAddress;
|
18 |
-
|
19 |
/**
|
20 |
* @var string
|
21 |
*/
|
@@ -25,7 +15,7 @@ trait IpAddressConsumer {
|
|
25 |
* @return string
|
26 |
*/
|
27 |
public function getIP() {
|
28 |
-
return $this->ipAddress
|
29 |
}
|
30 |
|
31 |
/**
|
@@ -34,7 +24,6 @@ trait IpAddressConsumer {
|
|
34 |
*/
|
35 |
public function setIP( $IP ) {
|
36 |
$this->ipAddress = $IP;
|
37 |
-
$this->sIpAddress = $IP;
|
38 |
return $this;
|
39 |
}
|
40 |
}
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
|
|
|
|
|
|
|
|
|
7 |
trait IpAddressConsumer {
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
/**
|
10 |
* @var string
|
11 |
*/
|
15 |
* @return string
|
16 |
*/
|
17 |
public function getIP() {
|
18 |
+
return $this->ipAddress;
|
19 |
}
|
20 |
|
21 |
/**
|
24 |
*/
|
25 |
public function setIP( $IP ) {
|
26 |
$this->ipAddress = $IP;
|
|
|
27 |
return $this;
|
28 |
}
|
29 |
}
|
src/lib/src/Modules/IPs/Lib/BlacklistHandler.php
CHANGED
@@ -29,11 +29,9 @@ class BlacklistHandler extends Modules\Base\Common\ExecOnceModConsumer {
|
|
29 |
->setMod( $mod )
|
30 |
->run();
|
31 |
|
32 |
-
add_action( 'init', [ $this, 'loadBotDetectors' ] ); // hook in the bot detection
|
33 |
-
|
34 |
if ( !$mod->isVisitorWhitelisted() && !$this->isRequestWhitelisted() ) {
|
35 |
|
36 |
-
// We setup offenses processing immediately but run the blocks on 'init
|
37 |
( new ProcessOffenses() )
|
38 |
->setMod( $this->getMod() )
|
39 |
->execute();
|
@@ -46,59 +44,10 @@ class BlacklistHandler extends Modules\Base\Common\ExecOnceModConsumer {
|
|
46 |
}
|
47 |
}
|
48 |
|
|
|
|
|
|
|
49 |
public function loadBotDetectors() {
|
50 |
-
/** @var IPs\ModCon $mod */
|
51 |
-
$mod = $this->getMod();
|
52 |
-
/** @var IPs\Options $opts */
|
53 |
-
$opts = $this->getOptions();
|
54 |
-
|
55 |
-
if ( !Services::WpUsers()->isUserLoggedIn() ) {
|
56 |
-
|
57 |
-
if ( !$mod->isTrustedVerifiedBot() ) {
|
58 |
-
if ( $opts->isEnabledTrackXmlRpc() ) {
|
59 |
-
( new IPs\BotTrack\TrackXmlRpc() )
|
60 |
-
->setMod( $mod )
|
61 |
-
->execute();
|
62 |
-
}
|
63 |
-
if ( $opts->isEnabledTrack404() ) {
|
64 |
-
( new IPs\BotTrack\Track404() )
|
65 |
-
->setMod( $mod )
|
66 |
-
->execute();
|
67 |
-
}
|
68 |
-
if ( $opts->isEnabledTrackLoginFailed() ) {
|
69 |
-
( new IPs\BotTrack\TrackLoginFailed() )
|
70 |
-
->setMod( $mod )
|
71 |
-
->execute();
|
72 |
-
}
|
73 |
-
if ( $opts->isEnabledTrackLoginInvalid() ) {
|
74 |
-
( new IPs\BotTrack\TrackLoginInvalid() )
|
75 |
-
->setMod( $mod )
|
76 |
-
->execute();
|
77 |
-
}
|
78 |
-
if ( $opts->isEnabledTrackFakeWebCrawler() ) {
|
79 |
-
( new IPs\BotTrack\TrackFakeWebCrawler() )
|
80 |
-
->setMod( $mod )
|
81 |
-
->execute();
|
82 |
-
}
|
83 |
-
if ( $opts->isEnabledTrackInvalidScript() ) {
|
84 |
-
( new IPs\BotTrack\TrackInvalidScriptLoad() )
|
85 |
-
->setMod( $mod )
|
86 |
-
->execute();
|
87 |
-
}
|
88 |
-
}
|
89 |
-
|
90 |
-
/** Always run link cheese regardless of the verified bot or not */
|
91 |
-
if ( $opts->isEnabledTrackLinkCheese() && $mod->canLinkCheese() ) {
|
92 |
-
( new IPs\BotTrack\TrackLinkCheese() )
|
93 |
-
->setMod( $mod )
|
94 |
-
->execute();
|
95 |
-
}
|
96 |
-
}
|
97 |
-
|
98 |
-
// Capture when admins un/mark comments as spam
|
99 |
-
( new IPs\BotTrack\TrackCommentSpam() )
|
100 |
-
->setMod( $mod )
|
101 |
-
->execute();
|
102 |
}
|
103 |
|
104 |
private function isRequestWhitelisted() :bool {
|
29 |
->setMod( $mod )
|
30 |
->run();
|
31 |
|
|
|
|
|
32 |
if ( !$mod->isVisitorWhitelisted() && !$this->isRequestWhitelisted() ) {
|
33 |
|
34 |
+
// We setup offenses processing immediately but run the blocks on 'init'
|
35 |
( new ProcessOffenses() )
|
36 |
->setMod( $this->getMod() )
|
37 |
->execute();
|
44 |
}
|
45 |
}
|
46 |
|
47 |
+
/**
|
48 |
+
* @deprecated 11.3
|
49 |
+
*/
|
50 |
public function loadBotDetectors() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
}
|
52 |
|
53 |
private function isRequestWhitelisted() :bool {
|
src/lib/src/Modules/IPs/Lib/BlockRequest.php
CHANGED
@@ -10,7 +10,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Obfuscate;
|
|
10 |
class BlockRequest extends ExecOnceModConsumer {
|
11 |
|
12 |
protected function run() {
|
13 |
-
if ( $this->isBlocked() ) {
|
14 |
|
15 |
if ( $this->isAutoUnBlocked() ) {
|
16 |
Services::Response()->redirectToHome();
|
@@ -30,6 +30,16 @@ class BlockRequest extends ExecOnceModConsumer {
|
|
30 |
->run();
|
31 |
}
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
private function isAutoUnBlocked() :bool {
|
34 |
return ( new AutoUnblock() )
|
35 |
->setMod( $this->getMod() )
|
10 |
class BlockRequest extends ExecOnceModConsumer {
|
11 |
|
12 |
protected function run() {
|
13 |
+
if ( $this->isBlocked() && !$this->isHighReputationIP() ) {
|
14 |
|
15 |
if ( $this->isAutoUnBlocked() ) {
|
16 |
Services::Response()->redirectToHome();
|
30 |
->run();
|
31 |
}
|
32 |
|
33 |
+
private function isHighReputationIP() :bool {
|
34 |
+
/** @var IPs\Options $opts */
|
35 |
+
$opts = $this->getOptions();
|
36 |
+
return ( new IPs\Lib\Bots\Calculator\CalculateVisitorBotScores() )
|
37 |
+
->setMod( $this->getMod() )
|
38 |
+
->setIP( Services::IP()->getRequestIp() )
|
39 |
+
->total() >
|
40 |
+
(int)apply_filters( 'shield/high_reputation_ip_minimum', $opts->getAntiBotHighReputationMinimum() );
|
41 |
+
}
|
42 |
+
|
43 |
private function isAutoUnBlocked() :bool {
|
44 |
return ( new AutoUnblock() )
|
45 |
->setMod( $this->getMod() )
|
src/lib/src/Modules/IPs/Lib/Bots/BotSignalsController.php
CHANGED
@@ -3,8 +3,12 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\
|
7 |
-
|
|
|
|
|
|
|
|
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
9 |
|
10 |
class BotSignalsController extends ExecOnceModConsumer {
|
@@ -67,7 +71,55 @@ class BotSignalsController extends ExecOnceModConsumer {
|
|
67 |
protected function run() {
|
68 |
$this->getEventListener()->execute();
|
69 |
add_action( 'init', function () {
|
|
|
|
|
|
|
70 |
$this->getHandlerNotBot()->execute();
|
71 |
} );
|
72 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\{
|
7 |
+
BotTrack,
|
8 |
+
Lib\Bots\Calculator\CalculateVisitorBotScores,
|
9 |
+
ModCon,
|
10 |
+
Options
|
11 |
+
};
|
12 |
use FernleafSystems\Wordpress\Services\Services;
|
13 |
|
14 |
class BotSignalsController extends ExecOnceModConsumer {
|
71 |
protected function run() {
|
72 |
$this->getEventListener()->execute();
|
73 |
add_action( 'init', function () {
|
74 |
+
foreach ( $this->enumerateBotTrackers() as $botTracker ) {
|
75 |
+
$botTracker->setMod( $this->getMod() )->execute();
|
76 |
+
}
|
77 |
$this->getHandlerNotBot()->execute();
|
78 |
} );
|
79 |
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @return BotTrack\Base[]
|
83 |
+
*/
|
84 |
+
private function enumerateBotTrackers() :array {
|
85 |
+
/** @var ModCon $mod */
|
86 |
+
$mod = $this->getMod();
|
87 |
+
/** @var Options $opts */
|
88 |
+
$opts = $this->getOptions();
|
89 |
+
|
90 |
+
$trackers = [
|
91 |
+
new BotTrack\TrackCommentSpam()
|
92 |
+
];
|
93 |
+
|
94 |
+
if ( !Services::WpUsers()->isUserLoggedIn() ) {
|
95 |
+
|
96 |
+
if ( !$mod->isTrustedVerifiedBot() ) {
|
97 |
+
|
98 |
+
if ( $opts->isEnabledTrack404() ) {
|
99 |
+
$trackers[] = new BotTrack\Track404();
|
100 |
+
}
|
101 |
+
if ( $opts->isEnabledTrackXmlRpc() ) {
|
102 |
+
$trackers[] = new BotTrack\TrackXmlRpc();
|
103 |
+
}
|
104 |
+
if ( $opts->isEnabledTrackLoginFailed() ) {
|
105 |
+
$trackers[] = new BotTrack\TrackLoginFailed();
|
106 |
+
}
|
107 |
+
if ( $opts->isEnabledTrackLoginInvalid() ) {
|
108 |
+
$trackers[] = new BotTrack\TrackLoginInvalid();
|
109 |
+
}
|
110 |
+
if ( $opts->isEnabledTrackFakeWebCrawler() ) {
|
111 |
+
$trackers[] = new BotTrack\TrackFakeWebCrawler();
|
112 |
+
}
|
113 |
+
if ( $opts->isEnabledTrackInvalidScript() ) {
|
114 |
+
$trackers[] = new BotTrack\TrackInvalidScriptLoad();
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
if ( $opts->isEnabledTrackLinkCheese() && $mod->canLinkCheese() ) {
|
119 |
+
$trackers[] = new BotTrack\TrackLinkCheese();
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
return $trackers;
|
124 |
+
}
|
125 |
}
|
src/lib/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php
CHANGED
@@ -27,9 +27,8 @@ class BotSignalsRecord {
|
|
27 |
public function retrieve( bool $storeOnLoad = true ) :EntryVO {
|
28 |
/** @var ModCon $mod */
|
29 |
$mod = $this->getMod();
|
30 |
-
|
31 |
-
$
|
32 |
-
$e = $select->filterByIPHuman( $this->getIP() )->first();
|
33 |
if ( !$e instanceof EntryVO ) {
|
34 |
$e = new EntryVO();
|
35 |
$e->ip = $this->getIP();
|
@@ -75,6 +74,18 @@ class BotSignalsRecord {
|
|
75 |
return $e;
|
76 |
}
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
public function store( EntryVO $entry ) :bool {
|
79 |
/** @var ModCon $mod */
|
80 |
$mod = $this->getMod();
|
27 |
public function retrieve( bool $storeOnLoad = true ) :EntryVO {
|
28 |
/** @var ModCon $mod */
|
29 |
$mod = $this->getMod();
|
30 |
+
|
31 |
+
$e = $this->dbLoad();
|
|
|
32 |
if ( !$e instanceof EntryVO ) {
|
33 |
$e = new EntryVO();
|
34 |
$e->ip = $this->getIP();
|
74 |
return $e;
|
75 |
}
|
76 |
|
77 |
+
/**
|
78 |
+
* @return EntryVO|null
|
79 |
+
*/
|
80 |
+
private function dbLoad() {
|
81 |
+
/** @var ModCon $mod */
|
82 |
+
$mod = $this->getMod();
|
83 |
+
/** @var Select $select */
|
84 |
+
$select = $mod->getDbHandler_BotSignals()->getQuerySelector();
|
85 |
+
/** @var EntryVO $record */
|
86 |
+
return $select->filterByIPHuman( $this->getIP() )->first();
|
87 |
+
}
|
88 |
+
|
89 |
public function store( EntryVO $entry ) :bool {
|
90 |
/** @var ModCon $mod */
|
91 |
$mod = $this->getMod();
|
src/lib/src/Modules/IPs/Lib/Bots/Calculator/BaseBuildScores.php
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\Calculator;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\EntryVoConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\EntryVO;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
+
use FernleafSystems\Wordpress\Services\Services;
|
9 |
+
use FernleafSystems\Wordpress\Services\Utilities\Net\IpID;
|
10 |
+
|
11 |
+
abstract class BaseBuildScores {
|
12 |
+
|
13 |
+
use EntryVoConsumer;
|
14 |
+
use ModConsumer;
|
15 |
+
|
16 |
+
abstract public function build() :array;
|
17 |
+
|
18 |
+
protected function score_known() :int {
|
19 |
+
try {
|
20 |
+
list( $ipID, $ipName ) = ( new IpID( $this->getRecord()->ip ) )->run();
|
21 |
+
}
|
22 |
+
catch ( \Exception $e ) {
|
23 |
+
$ipID = null;
|
24 |
+
}
|
25 |
+
return ( empty( $ipID ) || in_array( $ipID, [ IpID::UNKNOWN, IpID::VISITOR ] ) )
|
26 |
+
? 0 : 100;
|
27 |
+
}
|
28 |
+
|
29 |
+
protected function lastAtTs( $fieldFunction ) :int {
|
30 |
+
$field = str_replace( 'score_', '', $fieldFunction ).'_at';
|
31 |
+
return $this->getRecord()->{$field} ?? 0;
|
32 |
+
}
|
33 |
+
|
34 |
+
protected function diffTs( $fieldFunction ) :int {
|
35 |
+
$field = str_replace( 'score_', '', $fieldFunction ).'_at';
|
36 |
+
return Services::Request()->ts() - ( $this->getRecord()->{$field} ?? 0 );
|
37 |
+
}
|
38 |
+
|
39 |
+
protected function getAllFields( $filterForMethods = false ) :array {
|
40 |
+
$botSignalDBH = shield_security_get_plugin()->getController()
|
41 |
+
->getModule_IPs()
|
42 |
+
->getDbHandler_BotSignals();
|
43 |
+
$fields = array_map(
|
44 |
+
function ( $col ) {
|
45 |
+
return str_replace( '_at', '', $col );
|
46 |
+
},
|
47 |
+
array_filter(
|
48 |
+
$botSignalDBH->getTableSchema()->getColumnNames(),
|
49 |
+
function ( $col ) {
|
50 |
+
return preg_match( '#_at$#', $col ) &&
|
51 |
+
!in_array( $col, [ 'updated_at', 'deleted_at' ] );
|
52 |
+
}
|
53 |
+
)
|
54 |
+
);
|
55 |
+
|
56 |
+
if ( $filterForMethods ) {
|
57 |
+
$fields = array_filter( $fields, function ( $field ) {
|
58 |
+
return method_exists( $this, 'score_'.$field );
|
59 |
+
} );
|
60 |
+
}
|
61 |
+
|
62 |
+
return $fields;
|
63 |
+
}
|
64 |
+
|
65 |
+
protected function getRecord() :EntryVO {
|
66 |
+
return $this->getEntryVO();
|
67 |
+
}
|
68 |
+
}
|
src/lib/src/Modules/IPs/Lib/Bots/Calculator/BuildScores.php
CHANGED
@@ -2,310 +2,53 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\Calculator;
|
4 |
|
5 |
-
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\EntryVO;
|
7 |
-
use FernleafSystems\Wordpress\Services\Services;
|
8 |
-
use FernleafSystems\Wordpress\Services\Utilities\Net\IpID;
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
13 |
|
14 |
public function build() :array {
|
15 |
$scores = [];
|
16 |
-
foreach ( $this->getAllFields(
|
17 |
-
$scores[ $field ] = $this->
|
18 |
}
|
|
|
19 |
$scores[ 'known' ] = $this->score_known();
|
20 |
|
21 |
return $scores;
|
22 |
}
|
23 |
|
24 |
-
private function
|
25 |
-
|
26 |
-
list( $ipID, $ipName ) = ( new IpID( $this->getRecord()->ip ) )->run();
|
27 |
-
}
|
28 |
-
catch ( \Exception $e ) {
|
29 |
-
$ipID = null;
|
30 |
-
}
|
31 |
-
return ( empty( $ipID ) || in_array( $ipID, [ IpID::UNKNOWN, IpID::VISITOR ] ) )
|
32 |
-
? 0 : 100;
|
33 |
-
}
|
34 |
-
|
35 |
-
private function score_auth() :int {
|
36 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
37 |
-
$score = 0;
|
38 |
-
}
|
39 |
-
else {
|
40 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? 175 : 150;
|
41 |
-
}
|
42 |
-
return $score;
|
43 |
-
}
|
44 |
-
|
45 |
-
private function score_created() :int {
|
46 |
-
$score = 0;
|
47 |
-
$tsDiff = $this->diffTs( __FUNCTION__ );
|
48 |
-
if ( $tsDiff > 3 && $tsDiff < 15 ) {
|
49 |
-
$score = 15;
|
50 |
-
}
|
51 |
-
return $score;
|
52 |
-
}
|
53 |
-
|
54 |
-
private function score_bt404() :int {
|
55 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
56 |
-
$score = 0;
|
57 |
-
}
|
58 |
-
else {
|
59 |
-
$score = $this->diffTs( __FUNCTION__ ) < HOUR_IN_SECONDS ? -15 : -5;
|
60 |
-
}
|
61 |
-
return $score;
|
62 |
-
}
|
63 |
-
|
64 |
-
private function score_btcheese() :int {
|
65 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
66 |
-
$score = 0;
|
67 |
-
}
|
68 |
-
else {
|
69 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -65 : -45;
|
70 |
-
}
|
71 |
-
return $score;
|
72 |
-
}
|
73 |
-
|
74 |
-
private function score_btfake() :int {
|
75 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
76 |
-
$score = 0;
|
77 |
-
}
|
78 |
-
else {
|
79 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -75 : -45;
|
80 |
-
}
|
81 |
-
return $score;
|
82 |
-
}
|
83 |
-
|
84 |
-
private function score_btinvalidscript() :int {
|
85 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
86 |
-
$score = 0;
|
87 |
-
}
|
88 |
-
else {
|
89 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -25 : -15;
|
90 |
-
}
|
91 |
-
return $score;
|
92 |
-
}
|
93 |
-
|
94 |
-
private function score_btloginfail() :int {
|
95 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
96 |
-
$score = 0;
|
97 |
-
}
|
98 |
-
else {
|
99 |
-
$score = $this->diffTs( __FUNCTION__ ) < MINUTE_IN_SECONDS ? -35 : -15;
|
100 |
-
}
|
101 |
-
return $score;
|
102 |
-
}
|
103 |
-
|
104 |
-
private function score_btlogininvalid() :int {
|
105 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
106 |
-
$score = 0;
|
107 |
-
}
|
108 |
-
else {
|
109 |
-
$score = $this->diffTs( __FUNCTION__ ) < HOUR_IN_SECONDS ? -85 : -55;
|
110 |
-
}
|
111 |
-
return $score;
|
112 |
-
}
|
113 |
-
|
114 |
-
private function score_btua() :int {
|
115 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
116 |
-
$score = 0;
|
117 |
-
}
|
118 |
-
else {
|
119 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -35 : -25;
|
120 |
-
}
|
121 |
-
return $score;
|
122 |
-
}
|
123 |
-
|
124 |
-
private function score_btxml() :int {
|
125 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
126 |
-
$score = 0;
|
127 |
-
}
|
128 |
-
else {
|
129 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -55 : -35;
|
130 |
-
}
|
131 |
-
return $score;
|
132 |
-
}
|
133 |
-
|
134 |
-
private function score_cooldown() :int {
|
135 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
136 |
-
$score = 0;
|
137 |
-
}
|
138 |
-
else {
|
139 |
-
$score = $this->diffTs( __FUNCTION__ ) < MINUTE_IN_SECONDS ? -25 : -15;
|
140 |
-
}
|
141 |
-
return $score;
|
142 |
-
}
|
143 |
-
|
144 |
-
private function score_firewall() :int {
|
145 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
146 |
-
$score = 0;
|
147 |
-
}
|
148 |
-
else {
|
149 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -35 : -15;
|
150 |
-
}
|
151 |
-
return $score;
|
152 |
-
}
|
153 |
-
|
154 |
-
private function score_offense() :int {
|
155 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
156 |
-
$score = 0;
|
157 |
-
}
|
158 |
-
else {
|
159 |
-
$score = $this->diffTs( __FUNCTION__ ) < MINUTE_IN_SECONDS ? -35 : -25;
|
160 |
-
}
|
161 |
-
return $score;
|
162 |
-
}
|
163 |
-
|
164 |
-
private function score_blocked() :int {
|
165 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
166 |
-
$score = 0;
|
167 |
-
}
|
168 |
-
else {
|
169 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -55 : -45;
|
170 |
-
}
|
171 |
-
return $score;
|
172 |
-
}
|
173 |
-
|
174 |
-
private function score_unblocked() :int {
|
175 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
176 |
-
$score = 0;
|
177 |
-
}
|
178 |
-
else {
|
179 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? 100 : 75;
|
180 |
-
}
|
181 |
-
return $score;
|
182 |
-
}
|
183 |
-
|
184 |
-
private function score_bypass() :int {
|
185 |
-
return $this->lastAtTs( __FUNCTION__ ) > 0 ? 150 : 0;
|
186 |
-
}
|
187 |
-
|
188 |
-
private function score_captchapass() :int {
|
189 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
190 |
-
$score = 0;
|
191 |
-
}
|
192 |
-
else {
|
193 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? 55 : 25;
|
194 |
-
}
|
195 |
-
return $score;
|
196 |
-
}
|
197 |
-
|
198 |
-
private function score_ratelimit() :int {
|
199 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
200 |
-
$score = 0;
|
201 |
-
}
|
202 |
-
else {
|
203 |
-
$score = $this->diffTs( __FUNCTION__ ) < MINUTE_IN_SECONDS ? -55 : -25;
|
204 |
-
}
|
205 |
-
return $score;
|
206 |
-
}
|
207 |
-
|
208 |
-
private function score_captchafail() :int {
|
209 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
210 |
-
$score = 0;
|
211 |
-
}
|
212 |
-
else {
|
213 |
-
$score = $this->diffTs( __FUNCTION__ ) < HOUR_IN_SECONDS ? -55 : -25;
|
214 |
-
}
|
215 |
-
return $score;
|
216 |
-
}
|
217 |
-
|
218 |
-
private function score_humanspam() :int {
|
219 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
220 |
-
$score = 0;
|
221 |
-
}
|
222 |
-
else {
|
223 |
-
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -30 : -15;
|
224 |
-
}
|
225 |
-
return $score;
|
226 |
-
}
|
227 |
|
228 |
-
|
229 |
-
|
230 |
-
$score = 0;
|
231 |
-
}
|
232 |
-
else {
|
233 |
-
$score = $this->diffTs( __FUNCTION__ ) < WEEK_IN_SECONDS ? -50 : -25;
|
234 |
-
}
|
235 |
-
return $score;
|
236 |
-
}
|
237 |
|
238 |
-
|
239 |
-
|
240 |
-
$score = 0;
|
241 |
}
|
242 |
else {
|
243 |
-
$
|
244 |
-
|
245 |
-
return $score;
|
246 |
-
}
|
247 |
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
$score = $this->diffTs( __FUNCTION__ ) < HOUR_IN_SECONDS ? 25 : 15;
|
254 |
-
}
|
255 |
-
return $score;
|
256 |
-
}
|
257 |
-
|
258 |
-
private function score_loginpage() :int {
|
259 |
-
return $this->lastAtTs( __FUNCTION__ ) > 0 ? 15 : 0;
|
260 |
-
}
|
261 |
-
|
262 |
-
private function score_notbot() :int {
|
263 |
-
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
264 |
-
$score = -10;
|
265 |
-
}
|
266 |
-
else {
|
267 |
-
$score = $this->diffTs( __FUNCTION__ ) < HOUR_IN_SECONDS ? 150 : 75;
|
268 |
-
}
|
269 |
-
return $score;
|
270 |
-
}
|
271 |
-
|
272 |
-
private function lastAtTs( $fieldFunction ) :int {
|
273 |
-
$field = str_replace( 'score_', '', $fieldFunction ).'_at';
|
274 |
-
return $this->getRecord()->{$field} ?? 0;
|
275 |
-
}
|
276 |
-
|
277 |
-
private function diffTs( $fieldFunction ) :int {
|
278 |
-
$field = str_replace( 'score_', '', $fieldFunction ).'_at';
|
279 |
-
return Services::Request()->ts() - ( $this->getRecord()->{$field} ?? 0 );
|
280 |
-
}
|
281 |
-
|
282 |
-
private function getAllFields( $filterForMethods = false ) :array {
|
283 |
-
$botSignalDBH = shield_security_get_plugin()->getController()
|
284 |
-
->getModule_IPs()
|
285 |
-
->getDbHandler_BotSignals();
|
286 |
-
$fields = array_map(
|
287 |
-
function ( $col ) {
|
288 |
-
return str_replace( '_at', '', $col );
|
289 |
-
},
|
290 |
-
array_filter(
|
291 |
-
$botSignalDBH->getTableSchema()->getColumnNames(),
|
292 |
-
function ( $col ) {
|
293 |
-
return preg_match( '#_at$#', $col ) &&
|
294 |
-
!in_array( $col, [ 'updated_at', 'deleted_at' ] );
|
295 |
}
|
296 |
-
|
297 |
-
);
|
298 |
-
|
299 |
-
if ( $filterForMethods ) {
|
300 |
-
$fields = array_filter( $fields, function ( $field ) {
|
301 |
-
return method_exists( $this, 'score_'.$field );
|
302 |
-
} );
|
303 |
}
|
304 |
|
305 |
-
return $
|
306 |
}
|
307 |
|
308 |
-
private function
|
309 |
-
|
|
|
|
|
|
|
310 |
}
|
311 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\Calculator;
|
4 |
|
5 |
+
class BuildScores extends BaseBuildScores {
|
|
|
|
|
|
|
6 |
|
7 |
+
/**
|
8 |
+
* @var ScoreLogic
|
9 |
+
*/
|
10 |
+
private $logic;
|
11 |
|
12 |
public function build() :array {
|
13 |
$scores = [];
|
14 |
+
foreach ( $this->getAllFields() as $field ) {
|
15 |
+
$scores[ $field ] = $this->calcFieldScore( $field );
|
16 |
}
|
17 |
+
|
18 |
$scores[ 'known' ] = $this->score_known();
|
19 |
|
20 |
return $scores;
|
21 |
}
|
22 |
|
23 |
+
private function calcFieldScore( string $field ) :int {
|
24 |
+
$logic = $this->getScoringLogic()->getFieldScoreLogic( $field );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
+
// -1 represents the default if none of the following boundaries are satisfied
|
27 |
+
$score = $logic[ -1 ];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
+
if ( $this->lastAtTs( $field ) === 0 ) {
|
30 |
+
$score = $logic[ 0 ];
|
|
|
31 |
}
|
32 |
else {
|
33 |
+
unset( $logic[ 0 ] );
|
34 |
+
ksort( $logic );
|
|
|
|
|
35 |
|
36 |
+
$diff = $this->diffTs( $field );
|
37 |
+
foreach ( $logic as $boundary => $boundaryScore ) {
|
38 |
+
if ( $diff < $boundary ) {
|
39 |
+
$score = $boundaryScore;
|
40 |
+
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
}
|
42 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
}
|
44 |
|
45 |
+
return (int)$score;
|
46 |
}
|
47 |
|
48 |
+
private function getScoringLogic() :ScoreLogic {
|
49 |
+
if ( !$this->logic instanceof ScoreLogic ) {
|
50 |
+
$this->logic = ( new ScoreLogic() )->setCon( $this->getCon() );
|
51 |
+
}
|
52 |
+
return $this->logic;
|
53 |
}
|
54 |
}
|
src/lib/src/Modules/IPs/Lib/Bots/Calculator/BuildScoresFallback.php
ADDED
@@ -0,0 +1,248 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\Calculator;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
+
class BuildScoresFallback extends BaseBuildScores {
|
8 |
+
|
9 |
+
public function build() :array {
|
10 |
+
$scores = [];
|
11 |
+
foreach ( $this->getAllFields( true ) as $field ) {
|
12 |
+
$scores[ $field ] = $this->{'score_'.$field}();
|
13 |
+
}
|
14 |
+
$scores[ 'known' ] = $this->score_known();
|
15 |
+
if ( Services::Request()->ts() - $this->getRecord()->created_at < 20 ) {
|
16 |
+
$scores[ 'baseline' ] = 35;
|
17 |
+
}
|
18 |
+
return $scores;
|
19 |
+
}
|
20 |
+
|
21 |
+
private function score_auth() :int {
|
22 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
23 |
+
$score = 0;
|
24 |
+
}
|
25 |
+
else {
|
26 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? 175 : 150;
|
27 |
+
}
|
28 |
+
return $score;
|
29 |
+
}
|
30 |
+
|
31 |
+
private function score_bt404() :int {
|
32 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
33 |
+
$score = 0;
|
34 |
+
}
|
35 |
+
else {
|
36 |
+
$score = $this->diffTs( __FUNCTION__ ) < HOUR_IN_SECONDS ? -15 : -5;
|
37 |
+
}
|
38 |
+
return $score;
|
39 |
+
}
|
40 |
+
|
41 |
+
private function score_btcheese() :int {
|
42 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
43 |
+
$score = 0;
|
44 |
+
}
|
45 |
+
else {
|
46 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -65 : -45;
|
47 |
+
}
|
48 |
+
return $score;
|
49 |
+
}
|
50 |
+
|
51 |
+
private function score_btfake() :int {
|
52 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
53 |
+
$score = 0;
|
54 |
+
}
|
55 |
+
else {
|
56 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -75 : -45;
|
57 |
+
}
|
58 |
+
return $score;
|
59 |
+
}
|
60 |
+
|
61 |
+
private function score_btinvalidscript() :int {
|
62 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
63 |
+
$score = 0;
|
64 |
+
}
|
65 |
+
else {
|
66 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -25 : -15;
|
67 |
+
}
|
68 |
+
return $score;
|
69 |
+
}
|
70 |
+
|
71 |
+
private function score_btloginfail() :int {
|
72 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
73 |
+
$score = 0;
|
74 |
+
}
|
75 |
+
else {
|
76 |
+
$score = $this->diffTs( __FUNCTION__ ) < MINUTE_IN_SECONDS ? -35 : -15;
|
77 |
+
}
|
78 |
+
return $score;
|
79 |
+
}
|
80 |
+
|
81 |
+
private function score_btlogininvalid() :int {
|
82 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
83 |
+
$score = 0;
|
84 |
+
}
|
85 |
+
else {
|
86 |
+
$score = $this->diffTs( __FUNCTION__ ) < HOUR_IN_SECONDS ? -85 : -55;
|
87 |
+
}
|
88 |
+
return $score;
|
89 |
+
}
|
90 |
+
|
91 |
+
private function score_btua() :int {
|
92 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
93 |
+
$score = 0;
|
94 |
+
}
|
95 |
+
else {
|
96 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -35 : -25;
|
97 |
+
}
|
98 |
+
return $score;
|
99 |
+
}
|
100 |
+
|
101 |
+
private function score_btxml() :int {
|
102 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
103 |
+
$score = 0;
|
104 |
+
}
|
105 |
+
else {
|
106 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -55 : -35;
|
107 |
+
}
|
108 |
+
return $score;
|
109 |
+
}
|
110 |
+
|
111 |
+
private function score_cooldown() :int {
|
112 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
113 |
+
$score = 0;
|
114 |
+
}
|
115 |
+
else {
|
116 |
+
$score = $this->diffTs( __FUNCTION__ ) < MINUTE_IN_SECONDS ? -25 : -15;
|
117 |
+
}
|
118 |
+
return $score;
|
119 |
+
}
|
120 |
+
|
121 |
+
private function score_firewall() :int {
|
122 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
123 |
+
$score = 0;
|
124 |
+
}
|
125 |
+
else {
|
126 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -35 : -15;
|
127 |
+
}
|
128 |
+
return $score;
|
129 |
+
}
|
130 |
+
|
131 |
+
private function score_offense() :int {
|
132 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
133 |
+
$score = 0;
|
134 |
+
}
|
135 |
+
else {
|
136 |
+
$score = $this->diffTs( __FUNCTION__ ) < MINUTE_IN_SECONDS ? -35 : -25;
|
137 |
+
}
|
138 |
+
return $score;
|
139 |
+
}
|
140 |
+
|
141 |
+
private function score_blocked() :int {
|
142 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
143 |
+
$score = 0;
|
144 |
+
}
|
145 |
+
else {
|
146 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -55 : -45;
|
147 |
+
}
|
148 |
+
return $score;
|
149 |
+
}
|
150 |
+
|
151 |
+
private function score_unblocked() :int {
|
152 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
153 |
+
$score = 0;
|
154 |
+
}
|
155 |
+
else {
|
156 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? 100 : 75;
|
157 |
+
}
|
158 |
+
return $score;
|
159 |
+
}
|
160 |
+
|
161 |
+
private function score_bypass() :int {
|
162 |
+
return $this->lastAtTs( __FUNCTION__ ) > 0 ? 150 : 0;
|
163 |
+
}
|
164 |
+
|
165 |
+
private function score_captchapass() :int {
|
166 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
167 |
+
$score = 0;
|
168 |
+
}
|
169 |
+
else {
|
170 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? 55 : 25;
|
171 |
+
}
|
172 |
+
return $score;
|
173 |
+
}
|
174 |
+
|
175 |
+
private function score_ratelimit() :int {
|
176 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
177 |
+
$score = 0;
|
178 |
+
}
|
179 |
+
else {
|
180 |
+
$score = $this->diffTs( __FUNCTION__ ) < MINUTE_IN_SECONDS ? -55 : -25;
|
181 |
+
}
|
182 |
+
return $score;
|
183 |
+
}
|
184 |
+
|
185 |
+
private function score_captchafail() :int {
|
186 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
187 |
+
$score = 0;
|
188 |
+
}
|
189 |
+
else {
|
190 |
+
$score = $this->diffTs( __FUNCTION__ ) < HOUR_IN_SECONDS ? -55 : -25;
|
191 |
+
}
|
192 |
+
return $score;
|
193 |
+
}
|
194 |
+
|
195 |
+
private function score_humanspam() :int {
|
196 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
197 |
+
$score = 0;
|
198 |
+
}
|
199 |
+
else {
|
200 |
+
$score = $this->diffTs( __FUNCTION__ ) < DAY_IN_SECONDS ? -30 : -15;
|
201 |
+
}
|
202 |
+
return $score;
|
203 |
+
}
|
204 |
+
|
205 |
+
private function score_markspam() :int {
|
206 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
207 |
+
$score = 0;
|
208 |
+
}
|
209 |
+
else {
|
210 |
+
$score = $this->diffTs( __FUNCTION__ ) < WEEK_IN_SECONDS ? -50 : -25;
|
211 |
+
}
|
212 |
+
return $score;
|
213 |
+
}
|
214 |
+
|
215 |
+
private function score_unmarkspam() :int {
|
216 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
217 |
+
$score = 0;
|
218 |
+
}
|
219 |
+
else {
|
220 |
+
$score = $this->diffTs( __FUNCTION__ ) < WEEK_IN_SECONDS ? 75 : 35;
|
221 |
+
}
|
222 |
+
return $score;
|
223 |
+
}
|
224 |
+
|
225 |
+
private function score_frontpage() :int {
|
226 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
227 |
+
$score = -15;
|
228 |
+
}
|
229 |
+
else {
|
230 |
+
$score = $this->diffTs( __FUNCTION__ ) < HOUR_IN_SECONDS ? 25 : 15;
|
231 |
+
}
|
232 |
+
return $score;
|
233 |
+
}
|
234 |
+
|
235 |
+
private function score_loginpage() :int {
|
236 |
+
return $this->lastAtTs( __FUNCTION__ ) > 0 ? 15 : 0;
|
237 |
+
}
|
238 |
+
|
239 |
+
private function score_notbot() :int {
|
240 |
+
if ( $this->lastAtTs( __FUNCTION__ ) === 0 ) {
|
241 |
+
$score = -10;
|
242 |
+
}
|
243 |
+
else {
|
244 |
+
$score = $this->diffTs( __FUNCTION__ ) < HOUR_IN_SECONDS ? 150 : 75;
|
245 |
+
}
|
246 |
+
return $score;
|
247 |
+
}
|
248 |
+
}
|
src/lib/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php
CHANGED
@@ -18,6 +18,7 @@ class CalculateVisitorBotScores {
|
|
18 |
public function scores() :array {
|
19 |
$this->scores = ( new BuildScores() )
|
20 |
->setEntryVO( $this->loadEntry() )
|
|
|
21 |
->build();
|
22 |
return $this->getActiveScores();
|
23 |
}
|
18 |
public function scores() :array {
|
19 |
$this->scores = ( new BuildScores() )
|
20 |
->setEntryVO( $this->loadEntry() )
|
21 |
+
->setMod( $this->getMod() )
|
22 |
->build();
|
23 |
return $this->getActiveScores();
|
24 |
}
|
src/lib/src/Modules/IPs/Lib/Bots/Calculator/ScoreLogic.php
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\Calculator;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Reputation\BotScoringLogic;
|
7 |
+
use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
|
8 |
+
|
9 |
+
class ScoreLogic {
|
10 |
+
|
11 |
+
use PluginControllerConsumer;
|
12 |
+
|
13 |
+
private $rawLogic = [];
|
14 |
+
|
15 |
+
public function getFieldScoreLogic( $field ) :array {
|
16 |
+
return $this->getScoringLogic()[ $field ] ?? [];
|
17 |
+
}
|
18 |
+
|
19 |
+
private function getScoringLogic() :array {
|
20 |
+
if ( empty( $this->rawLogic ) ) {
|
21 |
+
$logic = Transient::Get( 'shield-bot-scoring-logic' );
|
22 |
+
if ( empty( $logic ) ) {
|
23 |
+
$logicLoader = ( new BotScoringLogic() )
|
24 |
+
->setMod( $this->getCon()->getModule_Plugin() );
|
25 |
+
$logicLoader->shield_net_params_required = false;
|
26 |
+
$logic = $logicLoader->retrieve();
|
27 |
+
if ( !empty( $logic ) ) {
|
28 |
+
Transient::Set( 'shield-bot-scoring-logic', $logic, DAY_IN_SECONDS );
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
$this->rawLogic = empty( $logic ) ? $this->buildFallback() : $logic;
|
33 |
+
}
|
34 |
+
return $this->rawLogic;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @return array[]
|
39 |
+
* @note Copied from ShieldNET API
|
40 |
+
*/
|
41 |
+
protected function buildFallback() :array {
|
42 |
+
return array_map( function ( $score ) {
|
43 |
+
return $score + [
|
44 |
+
0 => 0,
|
45 |
+
-1 => 0,
|
46 |
+
];
|
47 |
+
}, array_merge( $this->getPositiveSignals(), $this->getNegativeSignals() ) );
|
48 |
+
}
|
49 |
+
|
50 |
+
protected function getPositiveSignals() :array {
|
51 |
+
return [
|
52 |
+
'created' => [
|
53 |
+
3 => 0,
|
54 |
+
15 => 15,
|
55 |
+
],
|
56 |
+
'notbot' => [
|
57 |
+
0 => -10,
|
58 |
+
HOUR_IN_SECONDS => 150,
|
59 |
+
-1 => 75,
|
60 |
+
],
|
61 |
+
'frontpage' => [
|
62 |
+
0 => -15,
|
63 |
+
HOUR_IN_SECONDS => 25,
|
64 |
+
-1 => 15,
|
65 |
+
],
|
66 |
+
'loginpage' => [
|
67 |
+
-1 => 15,
|
68 |
+
],
|
69 |
+
'unmarkspam' => [
|
70 |
+
WEEK_IN_SECONDS => 75,
|
71 |
+
-1 => 35,
|
72 |
+
],
|
73 |
+
'captchapass' => [
|
74 |
+
DAY_IN_SECONDS => 55,
|
75 |
+
-1 => 25,
|
76 |
+
],
|
77 |
+
'auth' => [
|
78 |
+
DAY_IN_SECONDS => 175,
|
79 |
+
-1 => 150,
|
80 |
+
],
|
81 |
+
'unblocked' => [
|
82 |
+
DAY_IN_SECONDS => 100,
|
83 |
+
-1 => 75,
|
84 |
+
],
|
85 |
+
'bypass' => [
|
86 |
+
-1 => 150,
|
87 |
+
],
|
88 |
+
];
|
89 |
+
}
|
90 |
+
|
91 |
+
protected function getNegativeSignals() :array {
|
92 |
+
return [
|
93 |
+
'bt404' => [
|
94 |
+
HOUR_IN_SECONDS => -15,
|
95 |
+
-1 => -5,
|
96 |
+
],
|
97 |
+
'btfake' => [
|
98 |
+
DAY_IN_SECONDS => -75,
|
99 |
+
-1 => -45,
|
100 |
+
],
|
101 |
+
'btcheese' => [
|
102 |
+
DAY_IN_SECONDS => -65,
|
103 |
+
-1 => -45,
|
104 |
+
],
|
105 |
+
'btloginfail' => [
|
106 |
+
MINUTE_IN_SECONDS => -75,
|
107 |
+
-1 => -45,
|
108 |
+
],
|
109 |
+
'btua' => [
|
110 |
+
DAY_IN_SECONDS => -35,
|
111 |
+
-1 => -25,
|
112 |
+
],
|
113 |
+
'btxml' => [
|
114 |
+
DAY_IN_SECONDS => -55,
|
115 |
+
-1 => -35,
|
116 |
+
],
|
117 |
+
'btlogininvalid' => [
|
118 |
+
HOUR_IN_SECONDS => -85,
|
119 |
+
-1 => -55,
|
120 |
+
],
|
121 |
+
'btinvalidscript' => [
|
122 |
+
HOUR_IN_SECONDS => -25,
|
123 |
+
-1 => -15,
|
124 |
+
],
|
125 |
+
'cooldown' => [
|
126 |
+
MINUTE_IN_SECONDS => -25,
|
127 |
+
-1 => -15,
|
128 |
+
],
|
129 |
+
'humanspam' => [
|
130 |
+
DAY_IN_SECONDS => -30,
|
131 |
+
-1 => -15,
|
132 |
+
],
|
133 |
+
'markspam' => [
|
134 |
+
WEEK_IN_SECONDS => -50,
|
135 |
+
-1 => -25,
|
136 |
+
],
|
137 |
+
'captchafail' => [
|
138 |
+
MINUTE_IN_SECONDS => -55,
|
139 |
+
-1 => -25,
|
140 |
+
],
|
141 |
+
'firewall' => [
|
142 |
+
DAY_IN_SECONDS => -35,
|
143 |
+
-1 => -15,
|
144 |
+
],
|
145 |
+
'ratelimit' => [
|
146 |
+
MINUTE_IN_SECONDS => -55,
|
147 |
+
-1 => -25,
|
148 |
+
],
|
149 |
+
'offense' => [
|
150 |
+
MINUTE_IN_SECONDS => -35,
|
151 |
+
-1 => -25,
|
152 |
+
],
|
153 |
+
'blocked' => [
|
154 |
+
DAY_IN_SECONDS => -55,
|
155 |
+
-1 => -45,
|
156 |
+
],
|
157 |
+
];
|
158 |
+
}
|
159 |
+
}
|
src/lib/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php
CHANGED
@@ -23,7 +23,7 @@ class InsertNotBotJs extends ExecOnceModConsumer {
|
|
23 |
|
24 |
protected function enqueueJS() {
|
25 |
add_filter( 'shield/custom_enqueues', function ( array $enqueues ) {
|
26 |
-
$enqueues[ Enqueue::JS ][] = 'shield/
|
27 |
return $enqueues;
|
28 |
} );
|
29 |
}
|
@@ -39,8 +39,8 @@ class InsertNotBotJs extends ExecOnceModConsumer {
|
|
39 |
unset( $ajaxData[ 'ajaxurl' ] );
|
40 |
|
41 |
$localz[] = [
|
42 |
-
'shield/
|
43 |
-
'
|
44 |
apply_filters( 'shield/notbot_data_js', [
|
45 |
'ajax' => [
|
46 |
'not_bot' => http_build_query( $ajaxData )
|
23 |
|
24 |
protected function enqueueJS() {
|
25 |
add_filter( 'shield/custom_enqueues', function ( array $enqueues ) {
|
26 |
+
$enqueues[ Enqueue::JS ][] = 'shield/notbot';
|
27 |
return $enqueues;
|
28 |
} );
|
29 |
}
|
39 |
unset( $ajaxData[ 'ajaxurl' ] );
|
40 |
|
41 |
$localz[] = [
|
42 |
+
'shield/notbot',
|
43 |
+
'shield_vars_notbotjs',
|
44 |
apply_filters( 'shield/notbot_data_js', [
|
45 |
'ajax' => [
|
46 |
'not_bot' => http_build_query( $ajaxData )
|
src/lib/src/Modules/IPs/Lib/Bots/NotBot/TestNotBotLoading.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\NotBot;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class TestNotBotLoading {
|
9 |
+
|
10 |
+
use ModConsumer;
|
11 |
+
|
12 |
+
public function test() :bool {
|
13 |
+
$urlToFind = explode( '?', $this->getCon()->urls->forJs( 'shield/notbot' ) )[ 0 ];
|
14 |
+
return preg_match(
|
15 |
+
sprintf( '#%s#i', preg_quote( $urlToFind, '#' ) ),
|
16 |
+
Services::HttpRequest()->getContent( network_home_url( '/' ), [
|
17 |
+
'timeout' => 5
|
18 |
+
] )
|
19 |
+
) === 1;
|
20 |
+
}
|
21 |
+
}
|
src/lib/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php
CHANGED
@@ -136,11 +136,11 @@ class BuildDisplay {
|
|
136 |
'delete_notbot' => __( 'Reset For This IP', 'wp-simple-firewall' ),
|
137 |
|
138 |
'status' => [
|
139 |
-
'is_you'
|
140 |
-
'offenses'
|
141 |
-
'is_blocked'
|
142 |
-
'is_bypass'
|
143 |
-
'
|
144 |
],
|
145 |
|
146 |
'yes' => __( 'Yes', 'wp-simple-firewall' ),
|
@@ -163,12 +163,12 @@ class BuildDisplay {
|
|
163 |
'vars' => [
|
164 |
'ip' => $ip,
|
165 |
'status' => [
|
166 |
-
'is_you'
|
167 |
-
'offenses'
|
168 |
-
'is_blocked'
|
169 |
-
'is_bypass'
|
170 |
-
'
|
171 |
-
'is_bot'
|
172 |
],
|
173 |
'identity' => [
|
174 |
'who_is_it' => $ipName,
|
@@ -321,9 +321,9 @@ class BuildDisplay {
|
|
321 |
'title' => __( 'Bot Signals', 'wp-simple-firewall' ),
|
322 |
'signal' => __( 'Signal', 'wp-simple-firewall' ),
|
323 |
'score' => __( 'Score', 'wp-simple-firewall' ),
|
324 |
-
'total_score' => __( 'Total
|
325 |
'when' => __( 'When', 'wp-simple-firewall' ),
|
326 |
-
'bot_probability' => __( 'Bot Probability', 'wp-simple-firewall' ),
|
327 |
'botsignal_delete' => __( 'Delete All Bot Signals', 'wp-simple-firewall' ),
|
328 |
'signal_names' => $names,
|
329 |
'no_signals' => __( 'There are no bot signals for this IP address.', 'wp-simple-firewall' ),
|
136 |
'delete_notbot' => __( 'Reset For This IP', 'wp-simple-firewall' ),
|
137 |
|
138 |
'status' => [
|
139 |
+
'is_you' => __( 'Is It You?', 'wp-simple-firewall' ),
|
140 |
+
'offenses' => __( 'Number of offenses', 'wp-simple-firewall' ),
|
141 |
+
'is_blocked' => __( 'Is Blocked', 'wp-simple-firewall' ),
|
142 |
+
'is_bypass' => __( 'Is Bypass IP', 'wp-simple-firewall' ),
|
143 |
+
'ip_reputation' => __( 'IP Reputation Score', 'wp-simple-firewall' ),
|
144 |
],
|
145 |
|
146 |
'yes' => __( 'Yes', 'wp-simple-firewall' ),
|
163 |
'vars' => [
|
164 |
'ip' => $ip,
|
165 |
'status' => [
|
166 |
+
'is_you' => Services::IP()->checkIp( $ip, Services::IP()->getRequestIp() ),
|
167 |
+
'offenses' => $blockIP instanceof Databases\IPs\EntryVO ? $blockIP->transgressions : 0,
|
168 |
+
'is_blocked' => $blockIP instanceof Databases\IPs\EntryVO ? $blockIP->blocked_at > 0 : false,
|
169 |
+
'is_bypass' => $bypassIP instanceof Databases\IPs\EntryVO,
|
170 |
+
'ip_reputation_score' => $botScore,
|
171 |
+
'is_bot' => $isBot,
|
172 |
],
|
173 |
'identity' => [
|
174 |
'who_is_it' => $ipName,
|
321 |
'title' => __( 'Bot Signals', 'wp-simple-firewall' ),
|
322 |
'signal' => __( 'Signal', 'wp-simple-firewall' ),
|
323 |
'score' => __( 'Score', 'wp-simple-firewall' ),
|
324 |
+
'total_score' => __( 'Total Reputation Score', 'wp-simple-firewall' ),
|
325 |
'when' => __( 'When', 'wp-simple-firewall' ),
|
326 |
+
'bot_probability' => __( 'Bad Bot Probability', 'wp-simple-firewall' ),
|
327 |
'botsignal_delete' => __( 'Delete All Bot Signals', 'wp-simple-firewall' ),
|
328 |
'signal_names' => $names,
|
329 |
'no_signals' => __( 'There are no bot signals for this IP address.', 'wp-simple-firewall' ),
|
src/lib/src/Modules/IPs/Lib/OffenseTracker.php
CHANGED
@@ -22,10 +22,6 @@ class OffenseTracker extends EventsListener {
|
|
22 |
* @param array $def
|
23 |
*/
|
24 |
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
25 |
-
if ( empty( $def ) ) { // TODO: @deprecated 11.2 - remove this if
|
26 |
-
$def = $this->getCon()->loadEventsService()->getEventDef( $evt );
|
27 |
-
}
|
28 |
-
|
29 |
if ( !empty( $def[ 'offense' ] ) && empty( $meta[ 'suppress_offense' ] ) ) {
|
30 |
$this->incrementCount( (int)( $meta[ 'offense_count' ] ?? 1) );
|
31 |
if ( !empty( $meta[ 'block' ] ) ) {
|
22 |
* @param array $def
|
23 |
*/
|
24 |
protected function captureEvent( string $evt, $meta = [], $def = [] ) {
|
|
|
|
|
|
|
|
|
25 |
if ( !empty( $def[ 'offense' ] ) && empty( $meta[ 'suppress_offense' ] ) ) {
|
26 |
$this->incrementCount( (int)( $meta[ 'offense_count' ] ?? 1) );
|
27 |
if ( !empty( $meta[ 'block' ] ) ) {
|
src/lib/src/Modules/IPs/Options.php
CHANGED
@@ -56,6 +56,10 @@ class Options extends BaseShield\Options {
|
|
56 |
return (int)$this->getOpt( 'antibot_minimum', 50 );
|
57 |
}
|
58 |
|
|
|
|
|
|
|
|
|
59 |
public function isEnabledAntiBotEngine() :bool {
|
60 |
return $this->getAntiBotMinimum() > 0;
|
61 |
}
|
@@ -123,7 +127,7 @@ class Options extends BaseShield\Options {
|
|
123 |
* @param string $key
|
124 |
* @return bool
|
125 |
*/
|
126 |
-
public function isTrackOptImmediateBlock( $key ) {
|
127 |
return $this->isOpt( $key, 'block' );
|
128 |
}
|
129 |
|
56 |
return (int)$this->getOpt( 'antibot_minimum', 50 );
|
57 |
}
|
58 |
|
59 |
+
public function getAntiBotHighReputationMinimum() :int {
|
60 |
+
return (int)$this->getOpt( 'antibot_high_reputation_minimum', 200 );
|
61 |
+
}
|
62 |
+
|
63 |
public function isEnabledAntiBotEngine() :bool {
|
64 |
return $this->getAntiBotMinimum() > 0;
|
65 |
}
|
127 |
* @param string $key
|
128 |
* @return bool
|
129 |
*/
|
130 |
+
public function isTrackOptImmediateBlock( $key ) :bool {
|
131 |
return $this->isOpt( $key, 'block' );
|
132 |
}
|
133 |
|
src/lib/src/Modules/IPs/Strings.php
CHANGED
@@ -161,6 +161,15 @@ class Strings extends Base\Strings {
|
|
161 |
];
|
162 |
break;
|
163 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
case 'text_loginfailed' :
|
165 |
$name = __( 'Login Failed', 'wp-simple-firewall' );
|
166 |
$summary = __( 'Visitor Triggers The IP Offense System Through A Failed Login', 'wp-simple-firewall' );
|
@@ -176,8 +185,14 @@ class Strings extends Base\Strings {
|
|
176 |
case 'track_404' :
|
177 |
$name = __( '404 Detect', 'wp-simple-firewall' );
|
178 |
$summary = __( 'Identify A Bot When It Hits A 404', 'wp-simple-firewall' );
|
179 |
-
$desc =
|
180 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
break;
|
182 |
|
183 |
case 'track_xmlrpc' :
|
161 |
];
|
162 |
break;
|
163 |
|
164 |
+
case 'antibot_high_reputation_minimum' :
|
165 |
+
$name = __( 'High Reputation Bypass', 'wp-simple-firewall' );
|
166 |
+
$summary = __( 'Prevent Visitors With A High Reputation Scores From Being Blocked', 'wp-simple-firewall' );
|
167 |
+
$desc = [
|
168 |
+
__( "Visitors that have accumulated a high IP reputation and AntiBot score should ideally never be blocked.", 'wp-simple-firewall' ),
|
169 |
+
__( "This option ensures that visitors with a high reputation never have their IP blocked by Shield.", 'wp-simple-firewall' ),
|
170 |
+
];
|
171 |
+
break;
|
172 |
+
|
173 |
case 'text_loginfailed' :
|
174 |
$name = __( 'Login Failed', 'wp-simple-firewall' );
|
175 |
$summary = __( 'Visitor Triggers The IP Offense System Through A Failed Login', 'wp-simple-firewall' );
|
185 |
case 'track_404' :
|
186 |
$name = __( '404 Detect', 'wp-simple-firewall' );
|
187 |
$summary = __( 'Identify A Bot When It Hits A 404', 'wp-simple-firewall' );
|
188 |
+
$desc = [
|
189 |
+
__( 'Detect when a visitor tries to load a non-existent page.', 'wp-simple-firewall' ),
|
190 |
+
__( "Care should be taken to ensure that your website doesn't generate 404 errors for normal visitors.", 'wp-simple-firewall' ),
|
191 |
+
sprintf( '%s: <br/><strong>%s</strong>',
|
192 |
+
__( "404 errors generated for the following file types won't trigger an offense", 'wp-simple-firewall' ),
|
193 |
+
implode( ', ', $this->getOptions()->getDef( 'allowable_ext_404s' ) )
|
194 |
+
),
|
195 |
+
];
|
196 |
break;
|
197 |
|
198 |
case 'track_xmlrpc' :
|
src/lib/src/Modules/IPs/UI.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
|
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\IpAnalyse\FindAllPluginIps;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops\RetrieveIpsForLists;
|
8 |
use FernleafSystems\Wordpress\Services\Services;
|
@@ -90,6 +91,15 @@ class UI extends BaseShield\UI {
|
|
90 |
$warnings[] = sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ),
|
91 |
sprintf( __( "The AntiBot Detection Engine is disabled when set to a minimum score of %s.", 'wp-simple-firewall' ), '0' ) );
|
92 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
break;
|
94 |
|
95 |
case 'section_behaviours':
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\BaseShield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\NotBot\TestNotBotLoading;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\IpAnalyse\FindAllPluginIps;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops\RetrieveIpsForLists;
|
9 |
use FernleafSystems\Wordpress\Services\Services;
|
91 |
$warnings[] = sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ),
|
92 |
sprintf( __( "The AntiBot Detection Engine is disabled when set to a minimum score of %s.", 'wp-simple-firewall' ), '0' ) );
|
93 |
}
|
94 |
+
else {
|
95 |
+
$notbotFound = ( new TestNotBotLoading() )
|
96 |
+
->setMod( $this->getCon()->getModule_IPs() )
|
97 |
+
->test();
|
98 |
+
if ( !$notbotFound ) {
|
99 |
+
$warnings[] = sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ),
|
100 |
+
sprintf( __( "Shield couldn't determine whether the NotBot JS was loading correctly on your site.", 'wp-simple-firewall' ), '0' ) );
|
101 |
+
}
|
102 |
+
}
|
103 |
break;
|
104 |
|
105 |
case 'section_behaviours':
|
src/lib/src/Modules/IPs/WpCli.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<?php
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
4 |
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs;
|
4 |
|
src/lib/src/Modules/Insights/Lib/SideMenuBuilder.php
CHANGED
@@ -14,7 +14,6 @@ class SideMenuBuilder {
|
|
14 |
$menu = [
|
15 |
$this->search(),
|
16 |
$this->overview(),
|
17 |
-
$this->stats(),
|
18 |
$this->configuration(),
|
19 |
$this->scans(),
|
20 |
$this->ips(),
|
@@ -22,6 +21,7 @@ class SideMenuBuilder {
|
|
22 |
$this->traffic(),
|
23 |
$this->users(),
|
24 |
$this->integrations(),
|
|
|
25 |
$this->gopro(),
|
26 |
$this->tools(),
|
27 |
$this->docs(),
|
14 |
$menu = [
|
15 |
$this->search(),
|
16 |
$this->overview(),
|
|
|
17 |
$this->configuration(),
|
18 |
$this->scans(),
|
19 |
$this->ips(),
|
21 |
$this->traffic(),
|
22 |
$this->users(),
|
23 |
$this->integrations(),
|
24 |
+
$this->stats(),
|
25 |
$this->gopro(),
|
26 |
$this->tools(),
|
27 |
$this->docs(),
|
src/lib/src/Modules/Insights/ModCon.php
CHANGED
@@ -32,17 +32,6 @@ class ModCon extends BaseShield\ModCon {
|
|
32 |
}
|
33 |
}
|
34 |
|
35 |
-
/**
|
36 |
-
* @deprecated 11.2
|
37 |
-
*/
|
38 |
-
private function maybeRedirectToAdmin() {
|
39 |
-
$con = $this->getCon();
|
40 |
-
$activeFor = $con->getModule_Plugin()->getActivateLength();
|
41 |
-
if ( !Services::WpGeneral()->isAjax() && $activeFor < 4 ) {
|
42 |
-
Services::Response()->redirect( $this->getCon()->getPluginUrl_DashboardHome() );
|
43 |
-
}
|
44 |
-
}
|
45 |
-
|
46 |
public function getUrl_IpAnalysis( string $ip ) :string {
|
47 |
return add_query_arg( [ 'analyse_ip' => $ip ], $this->getUrl_SubInsightsPage( 'ips' ) );
|
48 |
}
|
32 |
}
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
public function getUrl_IpAnalysis( string $ip ) :string {
|
36 |
return add_query_arg( [ 'analyse_ip' => $ip ], $this->getUrl_SubInsightsPage( 'ips' ) );
|
37 |
}
|
src/lib/src/Modules/Insights/UI.php
CHANGED
@@ -265,28 +265,6 @@ class UI extends BaseShield\UI {
|
|
265 |
);
|
266 |
}
|
267 |
|
268 |
-
/**
|
269 |
-
* @return string
|
270 |
-
* @deprecated 11.2
|
271 |
-
*/
|
272 |
-
private function renderFreeTrial() :string {
|
273 |
-
$user = Services::WpUsers()->getCurrentWpUser();
|
274 |
-
return $this->getMod()
|
275 |
-
->renderTemplate(
|
276 |
-
'/forms/drip_trial_signup.twig',
|
277 |
-
[
|
278 |
-
'vars' => [
|
279 |
-
'activation_url' => Services::WpGeneral()->getHomeUrl(),
|
280 |
-
'email' => $user->user_email,
|
281 |
-
'name' => $user->user_firstname,
|
282 |
-
],
|
283 |
-
'strings' => [
|
284 |
-
],
|
285 |
-
],
|
286 |
-
true
|
287 |
-
);
|
288 |
-
}
|
289 |
-
|
290 |
private function renderTabUpdates() :string {
|
291 |
try {
|
292 |
$changelog = ( new Retrieve() )
|
265 |
);
|
266 |
}
|
267 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
private function renderTabUpdates() :string {
|
269 |
try {
|
270 |
$changelog = ( new Retrieve() )
|
src/lib/src/Modules/Integrations/Lib/Spam/SpamController.php
DELETED
@@ -1,51 +0,0 @@
|
|
1 |
-
<?php declare( strict_types=1 );
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Spam;
|
4 |
-
|
5 |
-
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Class SpamController
|
10 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Spam
|
11 |
-
* @deprecated 11.2
|
12 |
-
*/
|
13 |
-
class SpamController {
|
14 |
-
|
15 |
-
use ModConsumer;
|
16 |
-
use ExecOnce;
|
17 |
-
|
18 |
-
protected function canRun() :bool {
|
19 |
-
return $this->isEnabledSpamDetect();
|
20 |
-
}
|
21 |
-
|
22 |
-
protected function run() {
|
23 |
-
foreach ( $this->enumProviders() as $provider ) {
|
24 |
-
$provider->setMod( $this->getMod() )->execute();
|
25 |
-
}
|
26 |
-
}
|
27 |
-
|
28 |
-
private function isEnabledSpamDetect() :bool {
|
29 |
-
$opts = $this->getOptions();
|
30 |
-
return ( $opts->isOpt( 'enable_spam_antibot', 'Y' ) || $opts->isOpt( 'enable_spam_human', 'Y' ) )
|
31 |
-
&& !empty( $opts->getOpt( 'form_spam_providers' ) );
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @return Handlers\Base[]
|
36 |
-
*/
|
37 |
-
private function enumProviders() :array {
|
38 |
-
return [
|
39 |
-
new Handlers\ContactForm7(),
|
40 |
-
new Handlers\ElementorPro(),
|
41 |
-
new Handlers\FormidableForms(),
|
42 |
-
new Handlers\FluentForms(),
|
43 |
-
new Handlers\Forminator(),
|
44 |
-
new Handlers\GravityForms(),
|
45 |
-
new Handlers\KaliForms(),
|
46 |
-
new Handlers\NinjaForms(),
|
47 |
-
new Handlers\WPForms(),
|
48 |
-
new Handlers\WpForo(),
|
49 |
-
];
|
50 |
-
}
|
51 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/BaseProvider.php
CHANGED
@@ -199,22 +199,6 @@ abstract class BaseProvider {
|
|
199 |
return [];
|
200 |
}
|
201 |
|
202 |
-
/**
|
203 |
-
* ONLY TO BE HOOKED TO USER PROFILE EDIT
|
204 |
-
* @param \WP_User $user
|
205 |
-
* @return string
|
206 |
-
* @deprecated 11.2
|
207 |
-
*/
|
208 |
-
public function renderUserEditProfileOptions( \WP_User $user ) {
|
209 |
-
return '';
|
210 |
-
}
|
211 |
-
|
212 |
-
/**
|
213 |
-
* @param \WP_User $user
|
214 |
-
*/
|
215 |
-
public function handleEditOtherUserProfileSubmit( \WP_User $user ) {
|
216 |
-
}
|
217 |
-
|
218 |
/**
|
219 |
* @param \WP_User $user
|
220 |
*/
|
199 |
return [];
|
200 |
}
|
201 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
/**
|
203 |
* @param \WP_User $user
|
204 |
*/
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/GoogleAuth.php
CHANGED
@@ -78,21 +78,6 @@ class GoogleAuth extends BaseProvider {
|
|
78 |
return $url;
|
79 |
}
|
80 |
|
81 |
-
/**
|
82 |
-
* The only thing we can do is REMOVE Google Authenticator from an account that is not our own
|
83 |
-
* But, only admins can do this. If Security Admin feature is enabled, then only they can do it.
|
84 |
-
* @inheritDoc
|
85 |
-
*/
|
86 |
-
public function handleEditOtherUserProfileSubmit( \WP_User $user ) {
|
87 |
-
|
88 |
-
// Can only edit other users if you're admin/security-admin
|
89 |
-
if ( $this->getCon()->isPluginAdmin() && Services::Request()->post( 'shield_turn_off_ga' ) === 'Y' ) {
|
90 |
-
$this->processRemovalFromAccount( $user );
|
91 |
-
$msg = __( 'Google Authenticator was successfully removed from the account.', 'wp-simple-firewall' );
|
92 |
-
$this->getMod()->setFlashAdminNotice( $msg );
|
93 |
-
}
|
94 |
-
}
|
95 |
-
|
96 |
public function removeGaOnAccount( \WP_User $user ) :StdResponse {
|
97 |
$this->processRemovalFromAccount( $user );
|
98 |
$response = new StdResponse();
|
78 |
return $url;
|
79 |
}
|
80 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
public function removeGaOnAccount( \WP_User $user ) :StdResponse {
|
82 |
$this->processRemovalFromAccount( $user );
|
83 |
$response = new StdResponse();
|
src/lib/src/Modules/Plugin/Lib/Debug/Collate.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib\Debug;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Options;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Time\WorldTimeApi;
|
@@ -208,10 +209,13 @@ class Collate {
|
|
208 |
}
|
209 |
|
210 |
$data = [
|
211 |
-
'Can Loopback Request'
|
212 |
-
'
|
213 |
-
|
214 |
-
|
|
|
|
|
|
|
215 |
];
|
216 |
|
217 |
$licPing = new Licenses\Keyless\Ping();
|
@@ -225,11 +229,11 @@ class Collate {
|
|
225 |
|
226 |
private function getShieldSummary() :array {
|
227 |
$con = $this->getCon();
|
228 |
-
$
|
229 |
-
$
|
230 |
-
$
|
231 |
|
232 |
-
$nPrevAttempt = $
|
233 |
if ( empty( $nPrevAttempt ) ) {
|
234 |
$sPrev = 'Never';
|
235 |
}
|
@@ -240,21 +244,21 @@ class Collate {
|
|
240 |
->diffForHumans();
|
241 |
}
|
242 |
|
243 |
-
$
|
244 |
'Version' => $con->getVersion(),
|
245 |
'PRO' => $con->isPremiumActive() ? 'Yes' : 'No',
|
246 |
-
'WP Hashes Token' => ( $
|
247 |
'Security Admin Enabled' => $con->getModule_SecAdmin()
|
248 |
->getSecurityAdminController()
|
249 |
->isEnabledSecAdmin() ? 'Yes' : 'No',
|
250 |
];
|
251 |
|
252 |
/** @var Options $oOptsIP */
|
253 |
-
$
|
254 |
-
$
|
255 |
-
$
|
256 |
|
257 |
-
return $
|
258 |
}
|
259 |
|
260 |
private function getWordPressSummary() :array {
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib\Debug;
|
4 |
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\NotBot\TestNotBotLoading;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Options;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Utilities\Time\WorldTimeApi;
|
209 |
}
|
210 |
|
211 |
$data = [
|
212 |
+
'Can Loopback Request' => $loopback,
|
213 |
+
'NotBot Frontend JS Loading' => ( new TestNotBotLoading() )
|
214 |
+
->setMod( $this->getCon()->getModule_IPs() )
|
215 |
+
->test() ? 'Yes' : 'No',
|
216 |
+
'Handshake ShieldNET' => $modPlug->getShieldNetApiController()
|
217 |
+
->canHandshake() ? 'Yes' : 'No',
|
218 |
+
'WP Hashes Ping' => ( new ApiPing() )->ping() ? 'Yes' : 'No',
|
219 |
];
|
220 |
|
221 |
$licPing = new Licenses\Keyless\Ping();
|
229 |
|
230 |
private function getShieldSummary() :array {
|
231 |
$con = $this->getCon();
|
232 |
+
$modLicense = $con->getModule_License();
|
233 |
+
$modPlugin = $con->getModule_Plugin();
|
234 |
+
$wpHashes = $modLicense->getWpHashesTokenManager();
|
235 |
|
236 |
+
$nPrevAttempt = $wpHashes->getPreviousAttemptAt();
|
237 |
if ( empty( $nPrevAttempt ) ) {
|
238 |
$sPrev = 'Never';
|
239 |
}
|
244 |
->diffForHumans();
|
245 |
}
|
246 |
|
247 |
+
$data = [
|
248 |
'Version' => $con->getVersion(),
|
249 |
'PRO' => $con->isPremiumActive() ? 'Yes' : 'No',
|
250 |
+
'WP Hashes Token' => ( $wpHashes->hasToken() ? $wpHashes->getToken() : '' ).' ('.$sPrev.')',
|
251 |
'Security Admin Enabled' => $con->getModule_SecAdmin()
|
252 |
->getSecurityAdminController()
|
253 |
->isEnabledSecAdmin() ? 'Yes' : 'No',
|
254 |
];
|
255 |
|
256 |
/** @var Options $oOptsIP */
|
257 |
+
$optsPlugin = $modPlugin->getOptions();
|
258 |
+
$source = $optsPlugin->getSelectOptionValueText( 'visitor_address_source' );
|
259 |
+
$data[ 'Visitor IP Source' ] = $source.': '.var_export( Services::IP()->getRequestIp(), true );
|
260 |
|
261 |
+
return $data;
|
262 |
}
|
263 |
|
264 |
private function getWordPressSummary() :array {
|
src/lib/src/Modules/Plugin/Lib/PluginTelemetry.php
CHANGED
@@ -7,6 +7,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Databases\Events\Select;
|
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\ModCon;
|
9 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
|
|
10 |
use FernleafSystems\Wordpress\Services\Services;
|
11 |
|
12 |
class PluginTelemetry extends ExecOnceModConsumer {
|
@@ -39,39 +40,27 @@ class PluginTelemetry extends ExecOnceModConsumer {
|
|
39 |
}
|
40 |
|
41 |
public function runDailyCron() {
|
42 |
-
$this->sendTrackingData();
|
43 |
-
}
|
44 |
-
|
45 |
-
private function sendTrackingData() {
|
46 |
/** @var Plugin\Options $opts */
|
47 |
$opts = $this->getOptions();
|
48 |
|
49 |
-
$
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
if ( $bCanSend && $opts->isTrackingEnabled() ) {
|
56 |
-
|
57 |
-
$data = $this->collectTrackingData();
|
58 |
-
if ( !empty( $data ) ) {
|
59 |
-
$opts->setOpt( 'tracking_last_sent_at', Services::Request()->ts() );
|
60 |
-
$success = Services::HttpRequest()->post(
|
61 |
-
$opts->getDef( 'tracking_post_url' ),
|
62 |
-
[
|
63 |
-
'timeout' => 20,
|
64 |
-
'redirection' => 5,
|
65 |
-
'httpversion' => '1.1',
|
66 |
-
'blocking' => true,
|
67 |
-
'body' => [ 'tracking_data' => $data ],
|
68 |
-
'user-agent' => 'SHIELD/'.$this->getCon()->getVersion().';'
|
69 |
-
]
|
70 |
-
);
|
71 |
-
}
|
72 |
}
|
|
|
73 |
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
}
|
76 |
|
77 |
/**
|
@@ -92,10 +81,12 @@ class PluginTelemetry extends ExecOnceModConsumer {
|
|
92 |
->getQuerySelector();
|
93 |
$data[ 'events' ][ 'stats' ] = $select->sumAllEvents();
|
94 |
}
|
|
|
95 |
if ( !empty( $data[ 'login_protect' ] ) ) {
|
96 |
$data[ 'login_protect' ][ 'options' ][ 'email_can_send_verified_at' ] =
|
97 |
$data[ 'login_protect' ][ 'options' ][ 'email_can_send_verified_at' ] > 0 ? 1 : 0;
|
98 |
}
|
|
|
99 |
if ( !empty( $data[ 'admin_access_restriction' ] ) ) {
|
100 |
$keys = [
|
101 |
'admin_access_restrict_plugins',
|
@@ -107,6 +98,7 @@ class PluginTelemetry extends ExecOnceModConsumer {
|
|
107 |
= empty( $data[ 'admin_access_restriction' ][ 'options' ][ $key ] ) ? 0 : 1;
|
108 |
}
|
109 |
}
|
|
|
110 |
if ( !empty( $data[ 'plugin' ] ) ) {
|
111 |
/** @var Plugin\ModCon $mod */
|
112 |
$mod = $this->getMod();
|
@@ -148,19 +140,18 @@ class PluginTelemetry extends ExecOnceModConsumer {
|
|
148 |
$WPP = Services::WpPlugins();
|
149 |
return [
|
150 |
'env' => [
|
151 |
-
'
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
]
|
164 |
]
|
165 |
];
|
166 |
}
|
7 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
|
8 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\ModCon;
|
9 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
10 |
+
use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Telemetry\SendTelemetry;
|
11 |
use FernleafSystems\Wordpress\Services\Services;
|
12 |
|
13 |
class PluginTelemetry extends ExecOnceModConsumer {
|
40 |
}
|
41 |
|
42 |
public function runDailyCron() {
|
|
|
|
|
|
|
|
|
43 |
/** @var Plugin\Options $opts */
|
44 |
$opts = $this->getOptions();
|
45 |
|
46 |
+
$canSend = $opts->isTrackingEnabled()
|
47 |
+
&& Services::Request()
|
48 |
+
->carbon()
|
49 |
+
->subWeek()->timestamp > (int)$opts->getOpt( 'tracking_last_sent_at', 0 );
|
50 |
+
if ( $canSend ) {
|
51 |
+
$this->collectAndSend();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
}
|
53 |
+
}
|
54 |
|
55 |
+
public function collectAndSend() {
|
56 |
+
$data = $this->collectTrackingData();
|
57 |
+
if ( !empty( $data ) ) {
|
58 |
+
$this->getOptions()->setOpt( 'tracking_last_sent_at', Services::Request()->ts() );
|
59 |
+
$this->getMod()->saveModOptions();
|
60 |
+
( new SendTelemetry() )
|
61 |
+
->setMod( $this->getMod() )
|
62 |
+
->sendData( $data );
|
63 |
+
}
|
64 |
}
|
65 |
|
66 |
/**
|
81 |
->getQuerySelector();
|
82 |
$data[ 'events' ][ 'stats' ] = $select->sumAllEvents();
|
83 |
}
|
84 |
+
|
85 |
if ( !empty( $data[ 'login_protect' ] ) ) {
|
86 |
$data[ 'login_protect' ][ 'options' ][ 'email_can_send_verified_at' ] =
|
87 |
$data[ 'login_protect' ][ 'options' ][ 'email_can_send_verified_at' ] > 0 ? 1 : 0;
|
88 |
}
|
89 |
+
|
90 |
if ( !empty( $data[ 'admin_access_restriction' ] ) ) {
|
91 |
$keys = [
|
92 |
'admin_access_restrict_plugins',
|
98 |
= empty( $data[ 'admin_access_restriction' ][ 'options' ][ $key ] ) ? 0 : 1;
|
99 |
}
|
100 |
}
|
101 |
+
|
102 |
if ( !empty( $data[ 'plugin' ] ) ) {
|
103 |
/** @var Plugin\ModCon $mod */
|
104 |
$mod = $this->getMod();
|
140 |
$WPP = Services::WpPlugins();
|
141 |
return [
|
142 |
'env' => [
|
143 |
+
'slug' => $this->getCon()->getPluginSlug(),
|
144 |
+
'unique_site_hash' => sha1( network_home_url( '/' ) ),
|
145 |
+
'php' => Services::Data()->getPhpVersionCleaned(),
|
146 |
+
'wordpress' => $WP->getVersion(),
|
147 |
+
'version' => $this->getCon()->getVersion(),
|
148 |
+
'is_wpms' => $WP->isMultisite() ? 1 : 0,
|
149 |
+
'is_cp' => $WP->isClassicPress() ? 1 : 0,
|
150 |
+
'ssl' => is_ssl() ? 1 : 0,
|
151 |
+
'locale' => get_locale(),
|
152 |
+
'plugins_total' => count( $WPP->getPlugins() ),
|
153 |
+
'plugins_active' => count( $WPP->getActivePlugins() ),
|
154 |
+
'plugins_updates' => count( $WPP->getUpdates() )
|
|
|
155 |
]
|
156 |
];
|
157 |
}
|
src/lib/src/Modules/Reporting/Lib/ReportingController.php
CHANGED
@@ -44,7 +44,6 @@ class ReportingController {
|
|
44 |
}
|
45 |
}
|
46 |
catch ( \Exception $e ) {
|
47 |
-
var_dump( $e->getMessage() );
|
48 |
}
|
49 |
}
|
50 |
|
@@ -57,7 +56,6 @@ class ReportingController {
|
|
57 |
}
|
58 |
}
|
59 |
catch ( \Exception $e ) {
|
60 |
-
var_dump( $e->getMessage() );
|
61 |
}
|
62 |
}
|
63 |
|
44 |
}
|
45 |
}
|
46 |
catch ( \Exception $e ) {
|
|
|
47 |
}
|
48 |
}
|
49 |
|
56 |
}
|
57 |
}
|
58 |
catch ( \Exception $e ) {
|
|
|
59 |
}
|
60 |
}
|
61 |
|
src/lib/src/Modules/SecurityAdmin/ModCon.php
CHANGED
@@ -80,34 +80,6 @@ class ModCon extends BaseShield\ModCon {
|
|
80 |
}
|
81 |
}
|
82 |
|
83 |
-
/**
|
84 |
-
* We cater for 3 options:
|
85 |
-
* Full URL
|
86 |
-
* Relative path URL: i.e. starts with /
|
87 |
-
* Or Plugin image URL i.e. doesn't start with HTTP or /
|
88 |
-
* @param string $key
|
89 |
-
* @return string
|
90 |
-
* @deprecated 11.2
|
91 |
-
*/
|
92 |
-
private function buildWlImageUrl( $key ) {
|
93 |
-
$opts = $this->getOptions();
|
94 |
-
|
95 |
-
$url = $opts->getOpt( $key );
|
96 |
-
if ( empty( $url ) ) {
|
97 |
-
$opts->resetOptToDefault( $key );
|
98 |
-
$url = $opts->getOpt( $key );
|
99 |
-
}
|
100 |
-
if ( !empty( $url ) && !Services::Data()->isValidWebUrl( $url ) && strpos( $url, '/' ) !== 0 ) {
|
101 |
-
$url = $this->getCon()->urls->forImage( $url );
|
102 |
-
if ( empty( $url ) ) {
|
103 |
-
$opts->resetOptToDefault( $key );
|
104 |
-
$url = $this->getCon()->urls->forImage( $opts->getOpt( $key ) );
|
105 |
-
}
|
106 |
-
}
|
107 |
-
|
108 |
-
return $url;
|
109 |
-
}
|
110 |
-
|
111 |
/**
|
112 |
* Used by Wizard. TODO: sort out the wizard requests!
|
113 |
* @param string $pin
|
@@ -139,11 +111,10 @@ class ModCon extends BaseShield\ModCon {
|
|
139 |
$opts = $this->getOptions();
|
140 |
|
141 |
// Restricting Activate Plugins also means restricting the rest.
|
142 |
-
$
|
143 |
-
if ( in_array( 'activate_plugins', $
|
144 |
-
$opts->setOpt(
|
145 |
-
|
146 |
-
array_unique( array_merge( $pluginsRestrictions, [
|
147 |
'install_plugins',
|
148 |
'update_plugins',
|
149 |
'delete_plugins'
|
@@ -152,11 +123,10 @@ class ModCon extends BaseShield\ModCon {
|
|
152 |
}
|
153 |
|
154 |
// Restricting Switch (Activate) Themes also means restricting the rest.
|
155 |
-
$
|
156 |
-
if ( in_array( 'switch_themes', $
|
157 |
-
$opts->setOpt(
|
158 |
-
|
159 |
-
array_unique( array_merge( $themesRestrictions, [
|
160 |
'install_themes',
|
161 |
'update_themes',
|
162 |
'delete_themes'
|
@@ -164,11 +134,10 @@ class ModCon extends BaseShield\ModCon {
|
|
164 |
);
|
165 |
}
|
166 |
|
167 |
-
$
|
168 |
-
if ( in_array( 'edit', $
|
169 |
-
$opts->setOpt(
|
170 |
-
'
|
171 |
-
array_unique( array_merge( $postRestrictions, [ 'create', 'publish', 'delete' ] ) )
|
172 |
);
|
173 |
}
|
174 |
}
|
80 |
}
|
81 |
}
|
82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
/**
|
84 |
* Used by Wizard. TODO: sort out the wizard requests!
|
85 |
* @param string $pin
|
111 |
$opts = $this->getOptions();
|
112 |
|
113 |
// Restricting Activate Plugins also means restricting the rest.
|
114 |
+
$plugins = $opts->getOpt( 'admin_access_restrict_plugins', [] );
|
115 |
+
if ( in_array( 'activate_plugins', is_array( $plugins ) ? $plugins : [] ) ) {
|
116 |
+
$opts->setOpt( 'admin_access_restrict_plugins',
|
117 |
+
array_unique( array_merge( $plugins, [
|
|
|
118 |
'install_plugins',
|
119 |
'update_plugins',
|
120 |
'delete_plugins'
|
123 |
}
|
124 |
|
125 |
// Restricting Switch (Activate) Themes also means restricting the rest.
|
126 |
+
$themes = $opts->getOpt( 'admin_access_restrict_themes', [] );
|
127 |
+
if ( is_array( $themes ) && in_array( 'switch_themes', $themes ) && in_array( 'edit_theme_options', $themes ) ) {
|
128 |
+
$opts->setOpt( 'admin_access_restrict_themes',
|
129 |
+
array_unique( array_merge( $themes, [
|
|
|
130 |
'install_themes',
|
131 |
'update_themes',
|
132 |
'delete_themes'
|
134 |
);
|
135 |
}
|
136 |
|
137 |
+
$posts = $opts->getOpt( 'admin_access_restrict_posts', [] );
|
138 |
+
if ( in_array( 'edit', is_array( $posts ) ? $posts : [] ) ) {
|
139 |
+
$opts->setOpt( 'admin_access_restrict_posts',
|
140 |
+
array_unique( array_merge( $posts, [ 'create', 'publish', 'delete' ] ) )
|
|
|
141 |
);
|
142 |
}
|
143 |
}
|
src/lib/src/Modules/SecurityAdmin/Options.php
CHANGED
@@ -86,14 +86,6 @@ class Options extends BaseShield\Options {
|
|
86 |
return strlen( $this->getSecurityPIN() ) == 32;
|
87 |
}
|
88 |
|
89 |
-
/**
|
90 |
-
* @return bool
|
91 |
-
* @deprecated 11.2
|
92 |
-
*/
|
93 |
-
public function isEnabledWhitelabel() :bool {
|
94 |
-
return $this->isOpt( 'whitelabel_enable', 'Y' ) && $this->isPremium();
|
95 |
-
}
|
96 |
-
|
97 |
public function isEmailOverridePermitted() :bool {
|
98 |
return $this->isOpt( 'allow_email_override', 'Y' );
|
99 |
}
|
@@ -101,20 +93,4 @@ class Options extends BaseShield\Options {
|
|
101 |
public function isSecAdminRestrictUsersEnabled() :bool {
|
102 |
return $this->isOpt( 'admin_access_restrict_admin_users', 'Y' );
|
103 |
}
|
104 |
-
|
105 |
-
/**
|
106 |
-
* @return bool
|
107 |
-
* @deprecated 11.2
|
108 |
-
*/
|
109 |
-
public function isReplacePluginBadge() :bool {
|
110 |
-
return $this->isOpt( 'wl_replace_badge_url', 'Y' );
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* @return bool
|
115 |
-
* @deprecated 11.2
|
116 |
-
*/
|
117 |
-
public function isWlHideUpdates() :bool {
|
118 |
-
return false;
|
119 |
-
}
|
120 |
}
|
86 |
return strlen( $this->getSecurityPIN() ) == 32;
|
87 |
}
|
88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
public function isEmailOverridePermitted() :bool {
|
90 |
return $this->isOpt( 'allow_email_override', 'Y' );
|
91 |
}
|
93 |
public function isSecAdminRestrictUsersEnabled() :bool {
|
94 |
return $this->isOpt( 'admin_access_restrict_admin_users', 'Y' );
|
95 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
}
|
src/lib/src/Modules/Sessions/Processor.php
CHANGED
@@ -97,18 +97,6 @@ class Processor extends BaseShield\Processor {
|
|
97 |
return $msg;
|
98 |
}
|
99 |
|
100 |
-
/**
|
101 |
-
* @param \WP_User $user
|
102 |
-
* @deprecated 11.2
|
103 |
-
*/
|
104 |
-
private function activateUserSession( \WP_User $user ) {
|
105 |
-
/** @var ModCon $mod */
|
106 |
-
$mod = $this->getMod();
|
107 |
-
// If they have a currently active session, terminate it (i.e. we replace it)
|
108 |
-
$mod->getSessionCon()->terminateCurrentSession();
|
109 |
-
$mod->getSessionCon()->createSession( $user );
|
110 |
-
}
|
111 |
-
|
112 |
protected function getHookPriority() :int {
|
113 |
return 100;
|
114 |
}
|
97 |
return $msg;
|
98 |
}
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
protected function getHookPriority() :int {
|
101 |
return 100;
|
102 |
}
|
src/lib/src/Modules/UserManagement/Processor.php
CHANGED
@@ -71,9 +71,12 @@ class Processor extends BaseShield\Processor {
|
|
71 |
if ( !$user instanceof \WP_User && !empty( $username ) ) {
|
72 |
$user = Services::WpUsers()->getUserByUsername( $username );
|
73 |
}
|
74 |
-
|
75 |
-
|
76 |
-
|
|
|
|
|
|
|
77 |
}
|
78 |
|
79 |
/**
|
71 |
if ( !$user instanceof \WP_User && !empty( $username ) ) {
|
72 |
$user = Services::WpUsers()->getUserByUsername( $username );
|
73 |
}
|
74 |
+
// One might think it should be. It's not always the case it seems...
|
75 |
+
if ( $user instanceof \WP_User ) {
|
76 |
+
$this->setPasswordStartedAt( $user )// used by Password Policies
|
77 |
+
->setUserLastLoginTime( $user )
|
78 |
+
->sendLoginNotifications( $user );
|
79 |
+
}
|
80 |
}
|
81 |
|
82 |
/**
|
src/lib/src/ShieldNetApi/Common/BaseShieldNetApi.php
CHANGED
@@ -10,10 +10,12 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
10 |
* Class BaseShieldNetApi
|
11 |
* @package FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Common
|
12 |
* @property array $shield_net_params
|
|
|
13 |
*/
|
14 |
class BaseShieldNetApi extends BaseApi {
|
15 |
|
16 |
use ModConsumer;
|
|
|
17 |
const DEFAULT_URL_STUB = 'https://net.getshieldsecurity.com/wp-json/apto-snapi/v1';
|
18 |
|
19 |
/**
|
@@ -40,11 +42,15 @@ class BaseShieldNetApi extends BaseApi {
|
|
40 |
|
41 |
case 'shield_net_params':
|
42 |
if ( !is_array( $value ) ) {
|
43 |
-
$value = $this->getShieldNetApiParams();
|
44 |
$this->shield_net_params = $value;
|
45 |
}
|
46 |
break;
|
47 |
|
|
|
|
|
|
|
|
|
48 |
default:
|
49 |
break;
|
50 |
}
|
@@ -55,7 +61,7 @@ class BaseShieldNetApi extends BaseApi {
|
|
55 |
/**
|
56 |
* @return string[]
|
57 |
*/
|
58 |
-
protected function getShieldNetApiParams() {
|
59 |
return [
|
60 |
'url' => Services::WpGeneral()->getHomeUrl( '', true ),
|
61 |
'install_id' => $this->getCon()->getSiteInstallationId(),
|
10 |
* Class BaseShieldNetApi
|
11 |
* @package FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Common
|
12 |
* @property array $shield_net_params
|
13 |
+
* @property bool $shield_net_params_required
|
14 |
*/
|
15 |
class BaseShieldNetApi extends BaseApi {
|
16 |
|
17 |
use ModConsumer;
|
18 |
+
|
19 |
const DEFAULT_URL_STUB = 'https://net.getshieldsecurity.com/wp-json/apto-snapi/v1';
|
20 |
|
21 |
/**
|
42 |
|
43 |
case 'shield_net_params':
|
44 |
if ( !is_array( $value ) ) {
|
45 |
+
$value = $this->shield_net_params_required ? $this->getShieldNetApiParams() : [];
|
46 |
$this->shield_net_params = $value;
|
47 |
}
|
48 |
break;
|
49 |
|
50 |
+
case 'shield_net_params_required':
|
51 |
+
$value = is_null( $value ) || $value;
|
52 |
+
break;
|
53 |
+
|
54 |
default:
|
55 |
break;
|
56 |
}
|
61 |
/**
|
62 |
* @return string[]
|
63 |
*/
|
64 |
+
protected function getShieldNetApiParams() :array {
|
65 |
return [
|
66 |
'url' => Services::WpGeneral()->getHomeUrl( '', true ),
|
67 |
'install_id' => $this->getCon()->getSiteInstallationId(),
|
src/lib/src/ShieldNetApi/Reputation/BotScoringLogic.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Reputation;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Common;
|
6 |
+
|
7 |
+
class BotScoringLogic extends Common\BaseShieldNetApi {
|
8 |
+
|
9 |
+
const API_ACTION = 'bot/antibot_scoring_logic';
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @return array|null
|
13 |
+
*/
|
14 |
+
public function retrieve() {
|
15 |
+
$raw = $this->sendReq();
|
16 |
+
return ( is_array( $raw ) && !empty( $raw[ 'data' ] ) ) ? $raw[ 'data' ] : null;
|
17 |
+
}
|
18 |
+
}
|
src/lib/src/ShieldNetApi/Telemetry/SendTelemetry.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Telemetry;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Common;
|
6 |
+
|
7 |
+
class SendTelemetry extends Common\BaseShieldNetApi {
|
8 |
+
|
9 |
+
const API_ACTION = 'telemetry/receive';
|
10 |
+
|
11 |
+
public function sendData( array $data ) :bool {
|
12 |
+
$this->shield_net_params_required = false;
|
13 |
+
$this->request_method = 'post';
|
14 |
+
$this->params_body = [
|
15 |
+
'telemetry' => $data,
|
16 |
+
];
|
17 |
+
$raw = $this->sendReq();
|
18 |
+
return !( !is_array( $raw ) || $raw[ 'error' ] ?? false );
|
19 |
+
}
|
20 |
+
}
|
src/lib/src/Tables/Build/AuditTrail.php
CHANGED
@@ -20,7 +20,9 @@ class AuditTrail extends BaseBuild {
|
|
20 |
/** @var Shield\Databases\AuditTrail\Select $selector */
|
21 |
$selector = $this->getWorkingSelector();
|
22 |
|
23 |
-
|
|
|
|
|
24 |
|
25 |
// If an IP is specified, it takes priority
|
26 |
if ( Services::IP()->isValidIp( $params[ 'fIp' ] ) ) {
|
20 |
/** @var Shield\Databases\AuditTrail\Select $selector */
|
21 |
$selector = $this->getWorkingSelector();
|
22 |
|
23 |
+
if ( !empty( $params[ 'fEvent' ] ) ) {
|
24 |
+
$selector->filterByEvent( $params[ 'fEvent' ] );
|
25 |
+
}
|
26 |
|
27 |
// If an IP is specified, it takes priority
|
28 |
if ( Services::IP()->isValidIp( $params[ 'fIp' ] ) ) {
|
src/lib/vendor/composer/autoload_classmap.php
CHANGED
@@ -99,6 +99,22 @@ return array(
|
|
99 |
'FernleafSystems\\Utilities\\Logic\\ExecOnce' => $vendorDir . '/fernleafsystems/utilities/src/Logic/ExecOnce.php',
|
100 |
'FernleafSystems\\Utilities\\Logic\\OneTimeExecute' => $vendorDir . '/fernleafsystems/utilities/src/Logic/OneTimeExecute.php',
|
101 |
'FernleafSystems\\Utilities\\Response' => $vendorDir . '/fernleafsystems/utilities/src/Response.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => $baseDir . '/src/ChangeTrack/Diff/Base.php',
|
103 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => $baseDir . '/src/ChangeTrack/Diff/DiffComments.php',
|
104 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => $baseDir . '/src/ChangeTrack/Diff/DiffMedia.php',
|
@@ -466,10 +482,14 @@ return array(
|
|
466 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotEventListener' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotEventListener.php',
|
467 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsController' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotSignalsController.php',
|
468 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsRecord' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php',
|
|
|
469 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BuildScores' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/BuildScores.php',
|
|
|
470 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\CalculateVisitorBotScores' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php',
|
|
|
471 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
|
472 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
|
|
|
473 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
|
474 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
|
475 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => $baseDir . '/src/Modules/IPs/Lib/OffenseTracker.php',
|
@@ -568,7 +588,6 @@ return array(
|
|
568 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\NinjaForms' => $baseDir . '/src/Modules/Integrations/Lib/Spam/Handlers/NinjaForms.php',
|
569 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\WPForms' => $baseDir . '/src/Modules/Integrations/Lib/Spam/Handlers/WPForms.php',
|
570 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\WpForo' => $baseDir . '/src/Modules/Integrations/Lib/Spam/Handlers/WpForo.php',
|
571 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\SpamController' => $baseDir . '/src/Modules/Integrations/Lib/Spam/SpamController.php',
|
572 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\ModCon' => $baseDir . '/src/Modules/Integrations/ModCon.php',
|
573 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Options' => $baseDir . '/src/Modules/Integrations/Options.php',
|
574 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Processor' => $baseDir . '/src/Modules/Integrations/Processor.php',
|
@@ -730,7 +749,6 @@ return array(
|
|
730 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\AdminAdd' => $baseDir . '/src/Modules/SecurityAdmin/WpCli/AdminAdd.php',
|
731 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\AdminRemove' => $baseDir . '/src/Modules/SecurityAdmin/WpCli/AdminRemove.php',
|
732 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\Pin' => $baseDir . '/src/Modules/SecurityAdmin/WpCli/Pin.php',
|
733 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\Ops\\Retrieve' => $baseDir . '/src/Modules/Sessions/Lib/Ops/Retrieve.php',
|
734 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\Ops\\Terminate' => $baseDir . '/src/Modules/Sessions/Lib/Ops/Terminate.php',
|
735 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\SessionController' => $baseDir . '/src/Modules/Sessions/Lib/SessionController.php',
|
736 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\ModCon' => $baseDir . '/src/Modules/Sessions/ModCon.php',
|
@@ -873,9 +891,11 @@ return array(
|
|
873 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\FileLocker\\GetPublicKey' => $baseDir . '/src/ShieldNetApi/FileLocker/GetPublicKey.php',
|
874 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Handshake\\Verify' => $baseDir . '/src/ShieldNetApi/Handshake/Verify.php',
|
875 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\HandshakingNonce' => $baseDir . '/src/ShieldNetApi/HandshakingNonce.php',
|
|
|
876 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiController' => $baseDir . '/src/ShieldNetApi/ShieldNetApiController.php',
|
877 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiDataVO' => $baseDir . '/src/ShieldNetApi/ShieldNetApiDataVO.php',
|
878 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\SureSend\\SendEmail' => $baseDir . '/src/ShieldNetApi/SureSend/SendEmail.php',
|
|
|
879 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AdminNotes' => $baseDir . '/src/Tables/Build/AdminNotes.php',
|
880 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AuditTrail' => $baseDir . '/src/Tables/Build/AuditTrail.php',
|
881 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\BaseBuild' => $baseDir . '/src/Tables/Build/BaseBuild.php',
|
@@ -965,6 +985,7 @@ return array(
|
|
965 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
966 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
|
967 |
'FernleafSystems\\Wordpress\\Services\\Services' => $vendorDir . '/fernleafsystems/wordpress-services/src/Services.php',
|
|
|
968 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
|
969 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
|
970 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Consumers\\PluginConsumer' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Consumers/PluginConsumer.php',
|
99 |
'FernleafSystems\\Utilities\\Logic\\ExecOnce' => $vendorDir . '/fernleafsystems/utilities/src/Logic/ExecOnce.php',
|
100 |
'FernleafSystems\\Utilities\\Logic\\OneTimeExecute' => $vendorDir . '/fernleafsystems/utilities/src/Logic/OneTimeExecute.php',
|
101 |
'FernleafSystems\\Utilities\\Response' => $vendorDir . '/fernleafsystems/utilities/src/Response.php',
|
102 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\BaseQuery' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/BaseQuery.php',
|
103 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Delete' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Delete.php',
|
104 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Handler' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Handler.php',
|
105 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Insert' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Insert.php',
|
106 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Record' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php',
|
107 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Select' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php',
|
108 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Traits\\Select_IPTable' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/Select_IPTable.php',
|
109 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Update' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php',
|
110 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\AlignTableWithSchema' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php',
|
111 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\BuildColumnFromDef' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php',
|
112 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\HandlerConsumer' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/HandlerConsumer.php',
|
113 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\Iterator' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/Iterator.php',
|
114 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\RecordConsumer' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/RecordConsumer.php',
|
115 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\SubQueryLoader' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/SubQueryLoader.php',
|
116 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\TableSchema' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableSchema.php',
|
117 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Exceptions\\NoSlugProvidedException' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/NoSlugProvidedException.php',
|
118 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => $baseDir . '/src/ChangeTrack/Diff/Base.php',
|
119 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => $baseDir . '/src/ChangeTrack/Diff/DiffComments.php',
|
120 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => $baseDir . '/src/ChangeTrack/Diff/DiffMedia.php',
|
482 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotEventListener' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotEventListener.php',
|
483 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsController' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotSignalsController.php',
|
484 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsRecord' => $baseDir . '/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php',
|
485 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BaseBuildScores' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/BaseBuildScores.php',
|
486 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BuildScores' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/BuildScores.php',
|
487 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BuildScoresFallback' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/BuildScoresFallback.php',
|
488 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\CalculateVisitorBotScores' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php',
|
489 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\ScoreLogic' => $baseDir . '/src/Modules/IPs/Lib/Bots/Calculator/ScoreLogic.php',
|
490 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
|
491 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
|
492 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\TestNotBotLoading' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/TestNotBotLoading.php',
|
493 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
|
494 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
|
495 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => $baseDir . '/src/Modules/IPs/Lib/OffenseTracker.php',
|
588 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\NinjaForms' => $baseDir . '/src/Modules/Integrations/Lib/Spam/Handlers/NinjaForms.php',
|
589 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\WPForms' => $baseDir . '/src/Modules/Integrations/Lib/Spam/Handlers/WPForms.php',
|
590 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\WpForo' => $baseDir . '/src/Modules/Integrations/Lib/Spam/Handlers/WpForo.php',
|
|
|
591 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\ModCon' => $baseDir . '/src/Modules/Integrations/ModCon.php',
|
592 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Options' => $baseDir . '/src/Modules/Integrations/Options.php',
|
593 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Processor' => $baseDir . '/src/Modules/Integrations/Processor.php',
|
749 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\AdminAdd' => $baseDir . '/src/Modules/SecurityAdmin/WpCli/AdminAdd.php',
|
750 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\AdminRemove' => $baseDir . '/src/Modules/SecurityAdmin/WpCli/AdminRemove.php',
|
751 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\Pin' => $baseDir . '/src/Modules/SecurityAdmin/WpCli/Pin.php',
|
|
|
752 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\Ops\\Terminate' => $baseDir . '/src/Modules/Sessions/Lib/Ops/Terminate.php',
|
753 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\SessionController' => $baseDir . '/src/Modules/Sessions/Lib/SessionController.php',
|
754 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\ModCon' => $baseDir . '/src/Modules/Sessions/ModCon.php',
|
891 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\FileLocker\\GetPublicKey' => $baseDir . '/src/ShieldNetApi/FileLocker/GetPublicKey.php',
|
892 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Handshake\\Verify' => $baseDir . '/src/ShieldNetApi/Handshake/Verify.php',
|
893 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\HandshakingNonce' => $baseDir . '/src/ShieldNetApi/HandshakingNonce.php',
|
894 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Reputation\\BotScoringLogic' => $baseDir . '/src/ShieldNetApi/Reputation/BotScoringLogic.php',
|
895 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiController' => $baseDir . '/src/ShieldNetApi/ShieldNetApiController.php',
|
896 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiDataVO' => $baseDir . '/src/ShieldNetApi/ShieldNetApiDataVO.php',
|
897 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\SureSend\\SendEmail' => $baseDir . '/src/ShieldNetApi/SureSend/SendEmail.php',
|
898 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Telemetry\\SendTelemetry' => $baseDir . '/src/ShieldNetApi/Telemetry/SendTelemetry.php',
|
899 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AdminNotes' => $baseDir . '/src/Tables/Build/AdminNotes.php',
|
900 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AuditTrail' => $baseDir . '/src/Tables/Build/AuditTrail.php',
|
901 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\BaseBuild' => $baseDir . '/src/Tables/Build/BaseBuild.php',
|
985 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
986 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
|
987 |
'FernleafSystems\\Wordpress\\Services\\Services' => $vendorDir . '/fernleafsystems/wordpress-services/src/Services.php',
|
988 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Autoloading\\FindClassFromNamespaceRoots' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php',
|
989 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
|
990 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
|
991 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Consumers\\PluginConsumer' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Consumers/PluginConsumer.php',
|
src/lib/vendor/composer/autoload_files.php
CHANGED
@@ -6,8 +6,8 @@ $vendorDir = dirname(dirname(__FILE__));
|
|
6 |
$baseDir = dirname($vendorDir);
|
7 |
|
8 |
return array(
|
9 |
-
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
10 |
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
|
|
11 |
'626dcc41390ebdaa619faa02d99943b0' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php',
|
12 |
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
|
13 |
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
|
6 |
$baseDir = dirname($vendorDir);
|
7 |
|
8 |
return array(
|
|
|
9 |
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
10 |
+
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
11 |
'626dcc41390ebdaa619faa02d99943b0' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php',
|
12 |
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
|
13 |
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
|
src/lib/vendor/composer/autoload_psr4.php
CHANGED
@@ -24,6 +24,7 @@ return array(
|
|
24 |
'Html2Text\\' => array($vendorDir . '/soundasleep/html2text/src'),
|
25 |
'FernleafSystems\\Wordpress\\Services\\' => array($vendorDir . '/fernleafsystems/wordpress-services/src'),
|
26 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\' => array($baseDir . '/src'),
|
|
|
27 |
'FernleafSystems\\Utilities\\' => array($vendorDir . '/fernleafsystems/utilities/src'),
|
28 |
'Endroid\\QrCode\\' => array($vendorDir . '/endroid/qr-code/src'),
|
29 |
'Dolondro\\GoogleAuthenticator\\' => array($vendorDir . '/dolondro/google-authenticator/src'),
|
24 |
'Html2Text\\' => array($vendorDir . '/soundasleep/html2text/src'),
|
25 |
'FernleafSystems\\Wordpress\\Services\\' => array($vendorDir . '/fernleafsystems/wordpress-services/src'),
|
26 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\' => array($baseDir . '/src'),
|
27 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\' => array($vendorDir . '/fernleafsystems/wordpress-plugin-core/src'),
|
28 |
'FernleafSystems\\Utilities\\' => array($vendorDir . '/fernleafsystems/utilities/src'),
|
29 |
'Endroid\\QrCode\\' => array($vendorDir . '/endroid/qr-code/src'),
|
30 |
'Dolondro\\GoogleAuthenticator\\' => array($vendorDir . '/dolondro/google-authenticator/src'),
|
src/lib/vendor/composer/autoload_static.php
CHANGED
@@ -7,8 +7,8 @@ namespace Composer\Autoload;
|
|
7 |
class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
8 |
{
|
9 |
public static $files = array (
|
10 |
-
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
11 |
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
|
|
12 |
'626dcc41390ebdaa619faa02d99943b0' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php',
|
13 |
'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php',
|
14 |
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
|
@@ -60,6 +60,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
60 |
array (
|
61 |
'FernleafSystems\\Wordpress\\Services\\' => 35,
|
62 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\' => 40,
|
|
|
63 |
'FernleafSystems\\Utilities\\' => 26,
|
64 |
),
|
65 |
'E' =>
|
@@ -149,6 +150,10 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
149 |
array (
|
150 |
0 => __DIR__ . '/../..' . '/src',
|
151 |
),
|
|
|
|
|
|
|
|
|
152 |
'FernleafSystems\\Utilities\\' =>
|
153 |
array (
|
154 |
0 => __DIR__ . '/..' . '/fernleafsystems/utilities/src',
|
@@ -301,6 +306,22 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
301 |
'FernleafSystems\\Utilities\\Logic\\ExecOnce' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Logic/ExecOnce.php',
|
302 |
'FernleafSystems\\Utilities\\Logic\\OneTimeExecute' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Logic/OneTimeExecute.php',
|
303 |
'FernleafSystems\\Utilities\\Response' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Response.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
304 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/Base.php',
|
305 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffComments.php',
|
306 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffMedia.php',
|
@@ -668,10 +689,14 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
668 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotEventListener' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotEventListener.php',
|
669 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsController' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotSignalsController.php',
|
670 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsRecord' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php',
|
|
|
671 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BuildScores' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/BuildScores.php',
|
|
|
672 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\CalculateVisitorBotScores' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php',
|
|
|
673 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
|
674 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
|
|
|
675 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
|
676 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
|
677 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/OffenseTracker.php',
|
@@ -770,7 +795,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
770 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\NinjaForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Spam/Handlers/NinjaForms.php',
|
771 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\WPForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Spam/Handlers/WPForms.php',
|
772 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\WpForo' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Spam/Handlers/WpForo.php',
|
773 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\SpamController' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Spam/SpamController.php',
|
774 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Integrations/ModCon.php',
|
775 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Options' => __DIR__ . '/../..' . '/src/Modules/Integrations/Options.php',
|
776 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Processor' => __DIR__ . '/../..' . '/src/Modules/Integrations/Processor.php',
|
@@ -932,7 +956,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
932 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\AdminAdd' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/WpCli/AdminAdd.php',
|
933 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\AdminRemove' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/WpCli/AdminRemove.php',
|
934 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\Pin' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/WpCli/Pin.php',
|
935 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\Ops\\Retrieve' => __DIR__ . '/../..' . '/src/Modules/Sessions/Lib/Ops/Retrieve.php',
|
936 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\Ops\\Terminate' => __DIR__ . '/../..' . '/src/Modules/Sessions/Lib/Ops/Terminate.php',
|
937 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\SessionController' => __DIR__ . '/../..' . '/src/Modules/Sessions/Lib/SessionController.php',
|
938 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Sessions/ModCon.php',
|
@@ -1075,9 +1098,11 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
1075 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\FileLocker\\GetPublicKey' => __DIR__ . '/../..' . '/src/ShieldNetApi/FileLocker/GetPublicKey.php',
|
1076 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Handshake\\Verify' => __DIR__ . '/../..' . '/src/ShieldNetApi/Handshake/Verify.php',
|
1077 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\HandshakingNonce' => __DIR__ . '/../..' . '/src/ShieldNetApi/HandshakingNonce.php',
|
|
|
1078 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiController' => __DIR__ . '/../..' . '/src/ShieldNetApi/ShieldNetApiController.php',
|
1079 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiDataVO' => __DIR__ . '/../..' . '/src/ShieldNetApi/ShieldNetApiDataVO.php',
|
1080 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\SureSend\\SendEmail' => __DIR__ . '/../..' . '/src/ShieldNetApi/SureSend/SendEmail.php',
|
|
|
1081 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AdminNotes' => __DIR__ . '/../..' . '/src/Tables/Build/AdminNotes.php',
|
1082 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AuditTrail' => __DIR__ . '/../..' . '/src/Tables/Build/AuditTrail.php',
|
1083 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\BaseBuild' => __DIR__ . '/../..' . '/src/Tables/Build/BaseBuild.php',
|
@@ -1167,6 +1192,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
|
1167 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
1168 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
|
1169 |
'FernleafSystems\\Wordpress\\Services\\Services' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Services.php',
|
|
|
1170 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
|
1171 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
|
1172 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Consumers\\PluginConsumer' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Consumers/PluginConsumer.php',
|
7 |
class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
|
8 |
{
|
9 |
public static $files = array (
|
|
|
10 |
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
11 |
+
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
12 |
'626dcc41390ebdaa619faa02d99943b0' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php',
|
13 |
'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php',
|
14 |
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
|
60 |
array (
|
61 |
'FernleafSystems\\Wordpress\\Services\\' => 35,
|
62 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\' => 40,
|
63 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\' => 38,
|
64 |
'FernleafSystems\\Utilities\\' => 26,
|
65 |
),
|
66 |
'E' =>
|
150 |
array (
|
151 |
0 => __DIR__ . '/../..' . '/src',
|
152 |
),
|
153 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\' =>
|
154 |
+
array (
|
155 |
+
0 => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src',
|
156 |
+
),
|
157 |
'FernleafSystems\\Utilities\\' =>
|
158 |
array (
|
159 |
0 => __DIR__ . '/..' . '/fernleafsystems/utilities/src',
|
306 |
'FernleafSystems\\Utilities\\Logic\\ExecOnce' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Logic/ExecOnce.php',
|
307 |
'FernleafSystems\\Utilities\\Logic\\OneTimeExecute' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Logic/OneTimeExecute.php',
|
308 |
'FernleafSystems\\Utilities\\Response' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Response.php',
|
309 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\BaseQuery' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/BaseQuery.php',
|
310 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Delete' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Delete.php',
|
311 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Handler' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Handler.php',
|
312 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Insert' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Insert.php',
|
313 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Record' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php',
|
314 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Select' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php',
|
315 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Traits\\Select_IPTable' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/Select_IPTable.php',
|
316 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Update' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php',
|
317 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\AlignTableWithSchema' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php',
|
318 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\BuildColumnFromDef' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php',
|
319 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\HandlerConsumer' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/HandlerConsumer.php',
|
320 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\Iterator' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/Iterator.php',
|
321 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\RecordConsumer' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/RecordConsumer.php',
|
322 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\SubQueryLoader' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/SubQueryLoader.php',
|
323 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\TableSchema' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableSchema.php',
|
324 |
+
'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Exceptions\\NoSlugProvidedException' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/NoSlugProvidedException.php',
|
325 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/Base.php',
|
326 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffComments.php',
|
327 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffMedia.php',
|
689 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotEventListener' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotEventListener.php',
|
690 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsController' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotSignalsController.php',
|
691 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\BotSignalsRecord' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/BotSignalsRecord.php',
|
692 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BaseBuildScores' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/BaseBuildScores.php',
|
693 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BuildScores' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/BuildScores.php',
|
694 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\BuildScoresFallback' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/BuildScoresFallback.php',
|
695 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\CalculateVisitorBotScores' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/CalculateVisitorBotScores.php',
|
696 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\Calculator\\ScoreLogic' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/Calculator/ScoreLogic.php',
|
697 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
|
698 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
|
699 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\TestNotBotLoading' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/TestNotBotLoading.php',
|
700 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
|
701 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
|
702 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/OffenseTracker.php',
|
795 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\NinjaForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Spam/Handlers/NinjaForms.php',
|
796 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\WPForms' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Spam/Handlers/WPForms.php',
|
797 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Lib\\Spam\\Handlers\\WpForo' => __DIR__ . '/../..' . '/src/Modules/Integrations/Lib/Spam/Handlers/WpForo.php',
|
|
|
798 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Integrations/ModCon.php',
|
799 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Options' => __DIR__ . '/../..' . '/src/Modules/Integrations/Options.php',
|
800 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Integrations\\Processor' => __DIR__ . '/../..' . '/src/Modules/Integrations/Processor.php',
|
956 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\AdminAdd' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/WpCli/AdminAdd.php',
|
957 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\AdminRemove' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/WpCli/AdminRemove.php',
|
958 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\WpCli\\Pin' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/WpCli/Pin.php',
|
|
|
959 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\Ops\\Terminate' => __DIR__ . '/../..' . '/src/Modules/Sessions/Lib/Ops/Terminate.php',
|
960 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\Lib\\SessionController' => __DIR__ . '/../..' . '/src/Modules/Sessions/Lib/SessionController.php',
|
961 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Sessions\\ModCon' => __DIR__ . '/../..' . '/src/Modules/Sessions/ModCon.php',
|
1098 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\FileLocker\\GetPublicKey' => __DIR__ . '/../..' . '/src/ShieldNetApi/FileLocker/GetPublicKey.php',
|
1099 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Handshake\\Verify' => __DIR__ . '/../..' . '/src/ShieldNetApi/Handshake/Verify.php',
|
1100 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\HandshakingNonce' => __DIR__ . '/../..' . '/src/ShieldNetApi/HandshakingNonce.php',
|
1101 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Reputation\\BotScoringLogic' => __DIR__ . '/../..' . '/src/ShieldNetApi/Reputation/BotScoringLogic.php',
|
1102 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiController' => __DIR__ . '/../..' . '/src/ShieldNetApi/ShieldNetApiController.php',
|
1103 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiDataVO' => __DIR__ . '/../..' . '/src/ShieldNetApi/ShieldNetApiDataVO.php',
|
1104 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\SureSend\\SendEmail' => __DIR__ . '/../..' . '/src/ShieldNetApi/SureSend/SendEmail.php',
|
1105 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Telemetry\\SendTelemetry' => __DIR__ . '/../..' . '/src/ShieldNetApi/Telemetry/SendTelemetry.php',
|
1106 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AdminNotes' => __DIR__ . '/../..' . '/src/Tables/Build/AdminNotes.php',
|
1107 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AuditTrail' => __DIR__ . '/../..' . '/src/Tables/Build/AuditTrail.php',
|
1108 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\BaseBuild' => __DIR__ . '/../..' . '/src/Tables/Build/BaseBuild.php',
|
1192 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
1193 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
|
1194 |
'FernleafSystems\\Wordpress\\Services\\Services' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Services.php',
|
1195 |
+
'FernleafSystems\\Wordpress\\Services\\Utilities\\Autoloading\\FindClassFromNamespaceRoots' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php',
|
1196 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
|
1197 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
|
1198 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\Consumers\\PluginConsumer' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Consumers/PluginConsumer.php',
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/BaseQuery.php
ADDED
@@ -0,0 +1,466 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
|
4 |
+
|
5 |
+
use Carbon\Carbon;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
abstract class BaseQuery {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var Handler
|
12 |
+
*/
|
13 |
+
protected $dbh;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var array
|
17 |
+
*/
|
18 |
+
protected $rawWheres;
|
19 |
+
|
20 |
+
protected $includeSoftDeleted;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var int
|
24 |
+
*/
|
25 |
+
protected $limit = 0;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var int
|
29 |
+
*/
|
30 |
+
protected $page = 1;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var array
|
34 |
+
*/
|
35 |
+
protected $orderBys;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var string
|
39 |
+
*/
|
40 |
+
protected $groupBy;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var mixed
|
44 |
+
*/
|
45 |
+
protected $lastQueryResult;
|
46 |
+
|
47 |
+
public function __construct() {
|
48 |
+
$this->customInit();
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* override to add custom init actions
|
53 |
+
*/
|
54 |
+
protected function customInit() {
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @param string $column
|
59 |
+
* @param string|array $value
|
60 |
+
* @param string $operator
|
61 |
+
* @return $this
|
62 |
+
*/
|
63 |
+
public function addWhere( $column, $value, $operator = '=' ) {
|
64 |
+
if ( !$this->isValidComparisonOperator( $operator ) ) {
|
65 |
+
return $this; // Exception?
|
66 |
+
}
|
67 |
+
|
68 |
+
if ( is_array( $value ) ) {
|
69 |
+
$value = array_map( 'esc_sql', $value );
|
70 |
+
$value = "('".implode( "','", $value )."')";
|
71 |
+
}
|
72 |
+
else {
|
73 |
+
if ( strtoupper( $operator ) === 'LIKE' ) {
|
74 |
+
$value = sprintf( '%%%s%%', $value );
|
75 |
+
}
|
76 |
+
if ( !is_int( $value ) ) {
|
77 |
+
$value = sprintf( "'%s'", esc_sql( $value ) );
|
78 |
+
}
|
79 |
+
}
|
80 |
+
|
81 |
+
$rawWheres = $this->getRawWheres();
|
82 |
+
$rawWheres[] = [
|
83 |
+
esc_sql( $column ),
|
84 |
+
$operator,
|
85 |
+
$value
|
86 |
+
];
|
87 |
+
|
88 |
+
return $this->setRawWheres( $rawWheres );
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @param string $column
|
93 |
+
* @param mixed $mValue
|
94 |
+
* @return $this
|
95 |
+
*/
|
96 |
+
public function addWhereEquals( string $column, $mValue ) {
|
97 |
+
return $this->addWhere( $column, $mValue, '=' );
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* @param string $column
|
102 |
+
* @param array $values
|
103 |
+
* @return $this
|
104 |
+
*/
|
105 |
+
public function addWhereIn( string $column, $values ) {
|
106 |
+
if ( !empty( $values ) && is_array( $values ) ) {
|
107 |
+
$this->addWhere( $column, $values, 'IN' );
|
108 |
+
}
|
109 |
+
return $this;
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* @param string $column
|
114 |
+
* @param string $like
|
115 |
+
* @param string $left
|
116 |
+
* @param string $right
|
117 |
+
* @return $this
|
118 |
+
*/
|
119 |
+
public function addWhereLike( string $column, $like, $left = '%', $right = '%' ) {
|
120 |
+
return $this->addWhere( $column, $left.$like.$right, 'LIKE' );
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @param int $nNewerThanTimeStamp
|
125 |
+
* @param string $column
|
126 |
+
* @return $this
|
127 |
+
*/
|
128 |
+
public function addWhereNewerThan( $nNewerThanTimeStamp, $column = 'created_at' ) {
|
129 |
+
return $this->addWhere( $column, $nNewerThanTimeStamp, '>' );
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* @param int $nOlderThanTimeStamp
|
134 |
+
* @param string $column
|
135 |
+
* @return $this
|
136 |
+
*/
|
137 |
+
public function addWhereOlderThan( $nOlderThanTimeStamp, $column = 'created_at' ) {
|
138 |
+
return $this->addWhere( $column, $nOlderThanTimeStamp, '<' );
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* @param string $sColumn
|
143 |
+
* @param mixed $mValue
|
144 |
+
* @return $this
|
145 |
+
*/
|
146 |
+
public function addWhereSearch( $sColumn, $mValue ) {
|
147 |
+
return $this->addWhere( $sColumn, $mValue, 'LIKE' );
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* @return string
|
152 |
+
*/
|
153 |
+
public function buildExtras() {
|
154 |
+
$aExtras = array_filter(
|
155 |
+
[
|
156 |
+
$this->getGroupBy(),
|
157 |
+
$this->buildOrderBy(),
|
158 |
+
$this->buildLimitPhrase(),
|
159 |
+
$this->buildOffsetPhrase(),
|
160 |
+
]
|
161 |
+
);
|
162 |
+
return implode( "\n", $aExtras );
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* @return string
|
167 |
+
*/
|
168 |
+
public function buildLimitPhrase() {
|
169 |
+
return $this->hasLimit() ? sprintf( 'LIMIT %s', $this->getLimit() ) : '';
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* @return string
|
174 |
+
*/
|
175 |
+
protected function buildOffsetPhrase() {
|
176 |
+
return $this->hasLimit() ? sprintf( 'OFFSET %s', $this->getOffset() ) : '';
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* @return $this
|
181 |
+
*/
|
182 |
+
public function clearWheres() {
|
183 |
+
return $this->setRawWheres( [] );
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* @return int
|
188 |
+
*/
|
189 |
+
protected function getOffset() {
|
190 |
+
return (int)$this->getLimit()*( $this->getPage() - 1 );
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* @return string
|
195 |
+
*/
|
196 |
+
public function buildWhere() {
|
197 |
+
$wheres = $this->getRawWheres();
|
198 |
+
if ( !$this->isIncludeSoftDeletedRows() ) {
|
199 |
+
$wheres[] = [ 'deleted_at', '=', 0 ];
|
200 |
+
}
|
201 |
+
$wheres = array_map( function ( array $where ) {
|
202 |
+
return $this->rawWhereToString( $where );
|
203 |
+
}, $wheres );
|
204 |
+
return implode( ' AND ', $wheres );
|
205 |
+
}
|
206 |
+
|
207 |
+
public function buildQuery() :string {
|
208 |
+
return sprintf( $this->getBaseQuery(),
|
209 |
+
$this->getDbH()->getTable(),
|
210 |
+
$this->buildWhere(),
|
211 |
+
$this->buildExtras()
|
212 |
+
);
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* @param int $ts
|
217 |
+
* @param string $comparisonOp
|
218 |
+
* @return $this
|
219 |
+
*/
|
220 |
+
public function filterByCreatedAt( $ts, $comparisonOp ) {
|
221 |
+
if ( !preg_match( '#[^=<>]#', $comparisonOp ) && is_numeric( $ts ) ) {
|
222 |
+
$this->addWhere( 'created_at', (int)$ts, $comparisonOp );
|
223 |
+
}
|
224 |
+
return $this;
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* @param int $startTS
|
229 |
+
* @param int $endTS
|
230 |
+
* @return $this
|
231 |
+
*/
|
232 |
+
public function filterByBoundary( $startTS, $endTS ) {
|
233 |
+
return $this->filterByCreatedAt( $endTS, '<=' )
|
234 |
+
->filterByCreatedAt( $startTS, '>=' );
|
235 |
+
}
|
236 |
+
|
237 |
+
/**
|
238 |
+
* @param int $ts
|
239 |
+
* @return $this
|
240 |
+
*/
|
241 |
+
public function filterByBoundary_Day( $ts ) {
|
242 |
+
$carbon = ( new Carbon() )->setTimestamp( $ts );
|
243 |
+
return $this->filterByBoundary( $carbon->startOfDay()->timestamp, $carbon->endOfDay()->timestamp );
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* @param int $ts
|
248 |
+
* @return $this
|
249 |
+
*/
|
250 |
+
public function filterByBoundary_Hour( $ts ) {
|
251 |
+
$carbon = ( new Carbon() )->setTimestamp( $ts );
|
252 |
+
return $this->filterByBoundary( $carbon->startOfHour()->timestamp, $carbon->endOfHour()->timestamp );
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* @param int $ts
|
257 |
+
* @return $this
|
258 |
+
*/
|
259 |
+
public function filterByBoundary_Month( $ts ) {
|
260 |
+
$carbon = ( new Carbon() )->setTimestamp( $ts );
|
261 |
+
return $this->filterByBoundary( $carbon->startOfMonth()->timestamp, $carbon->endOfMonth()->timestamp );
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* @param int $ts
|
266 |
+
* @return $this
|
267 |
+
*/
|
268 |
+
public function filterByBoundary_Week( $ts ) {
|
269 |
+
$carbon = ( new Carbon() )->setTimestamp( $ts );
|
270 |
+
return $this->filterByBoundary( $carbon->startOfWeek()->timestamp, $carbon->endOfWeek()->timestamp );
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* @param int $ts
|
275 |
+
* @return $this
|
276 |
+
*/
|
277 |
+
public function filterByBoundary_Year( $ts ) {
|
278 |
+
$carbon = ( new Carbon() )->setTimestamp( $ts );
|
279 |
+
return $this->filterByBoundary( $carbon->startOfYear()->timestamp, $carbon->endOfYear()->timestamp );
|
280 |
+
}
|
281 |
+
|
282 |
+
protected function getBaseQuery() :string {
|
283 |
+
return "SELECT * FROM `%s` WHERE %s %s";
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* @return Handler
|
288 |
+
*/
|
289 |
+
public function getDbH() {
|
290 |
+
return $this->dbh;
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* @param Handler $dbh
|
295 |
+
* @return $this
|
296 |
+
*/
|
297 |
+
public function setDbH( $dbh ) {
|
298 |
+
$this->dbh = $dbh;
|
299 |
+
return $this;
|
300 |
+
}
|
301 |
+
|
302 |
+
public function query() :bool {
|
303 |
+
$this->lastQueryResult = Services::WpDb()->doSql( $this->buildQuery() );
|
304 |
+
return ( $this->lastQueryResult === false ) ? false : $this->lastQueryResult > 0;
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* @return array[]|int|string[]|Record[]|mixed|null
|
309 |
+
*/
|
310 |
+
public function queryWithResult() {
|
311 |
+
return $this->query() ? $this->getLastQueryResult() : null;
|
312 |
+
}
|
313 |
+
|
314 |
+
/**
|
315 |
+
* @return array[]|int|string[]|Record[]|mixed
|
316 |
+
*/
|
317 |
+
public function getLastQueryResult() {
|
318 |
+
return $this->lastQueryResult;
|
319 |
+
}
|
320 |
+
|
321 |
+
public function getLimit() :int {
|
322 |
+
return (int)max( $this->limit, 0 );
|
323 |
+
}
|
324 |
+
|
325 |
+
public function getRawWheres() :array {
|
326 |
+
return is_array( $this->rawWheres ) ? $this->rawWheres : [];
|
327 |
+
}
|
328 |
+
|
329 |
+
public function getGroupBy() :string {
|
330 |
+
return empty( $this->groupBy ) ? '' : sprintf( 'GROUP BY `%s`', $this->groupBy );
|
331 |
+
}
|
332 |
+
|
333 |
+
protected function buildOrderBy() :string {
|
334 |
+
$order = '';
|
335 |
+
if ( !is_array( $this->orderBys ) ) {
|
336 |
+
// Defaults to created_at if aOrderBys is untouched. Set to empty array for no order
|
337 |
+
$this->orderBys = [ 'created_at' => 'DESC' ];
|
338 |
+
}
|
339 |
+
if ( !empty( $this->orderBys ) ) {
|
340 |
+
$orders = [];
|
341 |
+
foreach ( $this->orderBys as $col => $order ) {
|
342 |
+
$orders[] = sprintf( '`%s` %s', esc_sql( $col ), esc_sql( $order ) );
|
343 |
+
}
|
344 |
+
$order = sprintf( 'ORDER BY %s', implode( ', ', $orders ) );
|
345 |
+
}
|
346 |
+
return $order;
|
347 |
+
}
|
348 |
+
|
349 |
+
public function getPage() :int {
|
350 |
+
return (int)max( $this->page, 1 );
|
351 |
+
}
|
352 |
+
|
353 |
+
public function hasLimit() :bool {
|
354 |
+
return $this->getLimit() > 0;
|
355 |
+
}
|
356 |
+
|
357 |
+
public function isIncludeSoftDeletedRows() :bool {
|
358 |
+
return $this->includeSoftDeleted ?? false;
|
359 |
+
}
|
360 |
+
|
361 |
+
protected function rawWhereToString( array $rawWhere ) :string {
|
362 |
+
return vsprintf( '`%s` %s %s', $rawWhere );
|
363 |
+
}
|
364 |
+
|
365 |
+
/**
|
366 |
+
* @return $this
|
367 |
+
*/
|
368 |
+
public function reset() {
|
369 |
+
return $this->setLimit( 0 )
|
370 |
+
->setRawWheres( [] )
|
371 |
+
->setPage( 1 )
|
372 |
+
->setOrderBy( '' );
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* @param bool $includeSoftDeleted
|
377 |
+
* @return $this
|
378 |
+
*/
|
379 |
+
public function setIncludeSoftDeleted( bool $includeSoftDeleted ) {
|
380 |
+
$this->includeSoftDeleted = $includeSoftDeleted;
|
381 |
+
return $this;
|
382 |
+
}
|
383 |
+
|
384 |
+
/**
|
385 |
+
* @param int $limit
|
386 |
+
* @return $this
|
387 |
+
*/
|
388 |
+
public function setLimit( int $limit ) {
|
389 |
+
$this->limit = $limit;
|
390 |
+
return $this;
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* @param string $groupByColumn
|
395 |
+
* @return $this
|
396 |
+
*/
|
397 |
+
public function setGroupBy( $groupByColumn ) {
|
398 |
+
if ( empty( $groupByColumn ) ) {
|
399 |
+
$this->groupBy = '';
|
400 |
+
}
|
401 |
+
elseif ( $this->getDbH()->getTableSchema()->hasColumn( $groupByColumn ) ) {
|
402 |
+
$this->groupBy = $groupByColumn;
|
403 |
+
}
|
404 |
+
return $this;
|
405 |
+
}
|
406 |
+
|
407 |
+
/**
|
408 |
+
* @param string $orderByColumn
|
409 |
+
* @param string $order
|
410 |
+
* @param bool $replace
|
411 |
+
* @return $this
|
412 |
+
*/
|
413 |
+
public function setOrderBy( string $orderByColumn, $order = 'DESC', $replace = false ) {
|
414 |
+
if ( empty( $orderByColumn ) ) {
|
415 |
+
$this->orderBys = $orderByColumn;
|
416 |
+
}
|
417 |
+
else {
|
418 |
+
if ( !is_array( $this->orderBys ) || $replace ) {
|
419 |
+
$this->orderBys = [];
|
420 |
+
}
|
421 |
+
$this->orderBys[ $orderByColumn ] = $order;
|
422 |
+
}
|
423 |
+
return $this;
|
424 |
+
}
|
425 |
+
|
426 |
+
/**
|
427 |
+
* @param int $nPage
|
428 |
+
* @return $this
|
429 |
+
*/
|
430 |
+
public function setPage( $nPage ) {
|
431 |
+
$this->page = $nPage;
|
432 |
+
return $this;
|
433 |
+
}
|
434 |
+
|
435 |
+
/**
|
436 |
+
* @param array[] $wheres
|
437 |
+
* @return $this
|
438 |
+
*/
|
439 |
+
public function setRawWheres( array $wheres ) {
|
440 |
+
$this->rawWheres = $wheres;
|
441 |
+
return $this;
|
442 |
+
}
|
443 |
+
|
444 |
+
/**
|
445 |
+
* @param Record $VO
|
446 |
+
* @return $this
|
447 |
+
*/
|
448 |
+
public function setWheresFromVo( $VO ) {
|
449 |
+
foreach ( $VO->getRawData() as $col => $mVal ) {
|
450 |
+
$this->addWhereEquals( $col, $mVal );
|
451 |
+
}
|
452 |
+
return $this;
|
453 |
+
}
|
454 |
+
|
455 |
+
/**
|
456 |
+
* Very basic
|
457 |
+
* @param string $op
|
458 |
+
* @return bool
|
459 |
+
*/
|
460 |
+
protected function isValidComparisonOperator( $op ) {
|
461 |
+
return in_array(
|
462 |
+
strtoupper( $op ),
|
463 |
+
[ '=', '<', '>', '!=', '<>', '<=', '>=', '<=>', 'IN', 'LIKE', 'NOT LIKE' ]
|
464 |
+
);
|
465 |
+
}
|
466 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Delete.php
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
+
class Delete extends BaseQuery {
|
8 |
+
|
9 |
+
private $isSoftDelete = false;
|
10 |
+
|
11 |
+
public function query() :bool {
|
12 |
+
if ( $this->isSoftDelete && $this->getDbH()->getTableSchema()->hasColumn( 'deleted_at' ) ) {
|
13 |
+
|
14 |
+
$updateWheres = [];
|
15 |
+
foreach ( $this->getRawWheres() as $where ) {
|
16 |
+
$updateWheres[ $where[ 0 ] ] = $where[ 2 ];
|
17 |
+
}
|
18 |
+
|
19 |
+
$updater = $this->getDbH()
|
20 |
+
->getQueryUpdater()
|
21 |
+
->setUpdateWheres( $updateWheres )
|
22 |
+
->setUpdateData( [ 'deleted_at' => Services::Request()->ts(), ] );
|
23 |
+
$success = $updater->query();
|
24 |
+
$this->lastQueryResult = $updater->getLastQueryResult();
|
25 |
+
}
|
26 |
+
else {
|
27 |
+
$success = parent::query();
|
28 |
+
}
|
29 |
+
return $success;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @return bool
|
34 |
+
*/
|
35 |
+
public function all() {
|
36 |
+
return $this->query();
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @param int $id
|
41 |
+
* @return bool
|
42 |
+
*/
|
43 |
+
public function deleteById( $id ) {
|
44 |
+
return $this->reset()
|
45 |
+
->addWhereEquals( 'id', (int)$id )
|
46 |
+
->query();
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @param Record $record
|
51 |
+
* @return bool
|
52 |
+
* @deprecated
|
53 |
+
*/
|
54 |
+
public function deleteEntry( $record ) {
|
55 |
+
return $this->deleteRecord( $record );
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @param Record $record
|
60 |
+
* @return bool
|
61 |
+
*/
|
62 |
+
public function deleteRecord( $record ) {
|
63 |
+
return $this->deleteById( $record->id );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* NOTE: Does not reset() before query, so may be customized with where.
|
68 |
+
* @param int $maxEntries
|
69 |
+
* @param string $orderByColumn
|
70 |
+
* @param bool $bOldestFirst
|
71 |
+
* @return int
|
72 |
+
* @throws \Exception
|
73 |
+
*/
|
74 |
+
public function deleteExcess( $maxEntries, $orderByColumn = 'created_at', $bOldestFirst = true ) {
|
75 |
+
if ( is_null( $maxEntries ) ) {
|
76 |
+
throw new \Exception( 'Max Entries not specified for table excess delete.' );
|
77 |
+
}
|
78 |
+
|
79 |
+
$nEntriesDeleted = 0;
|
80 |
+
|
81 |
+
// The same WHEREs should apply
|
82 |
+
$nTotal = $this->getDbH()
|
83 |
+
->getQuerySelector()
|
84 |
+
->setRawWheres( $this->getRawWheres() )
|
85 |
+
->count();
|
86 |
+
$toDelete = $nTotal - $maxEntries;
|
87 |
+
|
88 |
+
if ( $toDelete > 0 ) {
|
89 |
+
$nEntriesDeleted = $this->setOrderBy( $orderByColumn, $bOldestFirst ? 'ASC' : 'DESC' )
|
90 |
+
->setLimit( $toDelete )
|
91 |
+
->query();
|
92 |
+
}
|
93 |
+
|
94 |
+
return $nEntriesDeleted;
|
95 |
+
}
|
96 |
+
|
97 |
+
protected function getBaseQuery() :string {
|
98 |
+
return "DELETE FROM `%s` WHERE %s %s";
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Offset never applies to DELETE
|
103 |
+
* @return string
|
104 |
+
*/
|
105 |
+
protected function buildOffsetPhrase() {
|
106 |
+
return '';
|
107 |
+
}
|
108 |
+
|
109 |
+
public function setIsHardDelete() {
|
110 |
+
$this->isSoftDelete = false;
|
111 |
+
return $this;
|
112 |
+
}
|
113 |
+
|
114 |
+
public function setIsSoftDelete() {
|
115 |
+
$this->isSoftDelete = true;
|
116 |
+
return $this;
|
117 |
+
}
|
118 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Handler.php
ADDED
@@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Logic\ExecOnce;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Core\Databases\Common\{
|
7 |
+
AlignTableWithSchema,
|
8 |
+
Iterator,
|
9 |
+
SubQueryLoader,
|
10 |
+
TableSchema
|
11 |
+
};
|
12 |
+
use FernleafSystems\Wordpress\Plugin\Core\Databases\Exceptions\{
|
13 |
+
NoSlugProvidedException
|
14 |
+
};
|
15 |
+
use FernleafSystems\Wordpress\Services\Services;
|
16 |
+
|
17 |
+
abstract class Handler {
|
18 |
+
|
19 |
+
use ExecOnce;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var bool
|
23 |
+
*/
|
24 |
+
private $isReady;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var array
|
28 |
+
*/
|
29 |
+
protected $tableDefinition;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var TableSchema
|
33 |
+
*/
|
34 |
+
protected $schema;
|
35 |
+
|
36 |
+
public function __construct( array $tableDefinition ) {
|
37 |
+
if ( empty( $tableDefinition[ 'slug' ] ) ) {
|
38 |
+
throw new NoSlugProvidedException( 'Slug not provided in Table Definition' );
|
39 |
+
}
|
40 |
+
$this->tableDefinition = $tableDefinition;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @throws \Exception
|
45 |
+
*/
|
46 |
+
protected function run() {
|
47 |
+
$this->tableInit();
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @return $this
|
52 |
+
* @throws \Exception
|
53 |
+
*/
|
54 |
+
public function tableInit() {
|
55 |
+
|
56 |
+
$this->setupTableSchema();
|
57 |
+
|
58 |
+
if ( !$this->isReady() ) {
|
59 |
+
|
60 |
+
$this->tableCreate();
|
61 |
+
|
62 |
+
if ( !$this->isReady( true ) ) {
|
63 |
+
$this->tableDelete();
|
64 |
+
$this->tableCreate();
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
return $this;
|
69 |
+
}
|
70 |
+
|
71 |
+
private function setupTableSchema() :TableSchema {
|
72 |
+
$this->schema = new TableSchema();
|
73 |
+
|
74 |
+
$this->schema->applyFromArray( array_merge(
|
75 |
+
[
|
76 |
+
'slug' => '',
|
77 |
+
'table_prefix' => '',
|
78 |
+
'primary_key' => 'id',
|
79 |
+
'cols_custom' => [],
|
80 |
+
'cols_timestamps' => [],
|
81 |
+
'has_updated_at' => false,
|
82 |
+
'col_older_than' => 'created_at',
|
83 |
+
'autoexpire' => 0,
|
84 |
+
'has_ip_col' => false,
|
85 |
+
],
|
86 |
+
$this->tableDefinition
|
87 |
+
) );
|
88 |
+
|
89 |
+
$this->schema->table = $this->getTable();
|
90 |
+
|
91 |
+
return $this->schema;
|
92 |
+
}
|
93 |
+
|
94 |
+
public function autoCleanDb() {
|
95 |
+
}
|
96 |
+
|
97 |
+
public function tableCleanExpired( int $autoExpireDays ) {
|
98 |
+
if ( $autoExpireDays > 0 ) {
|
99 |
+
$this->deleteRowsOlderThan( Services::Request()->ts() - $autoExpireDays*DAY_IN_SECONDS );
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* @param int $timestamp
|
105 |
+
* @return bool
|
106 |
+
*/
|
107 |
+
public function deleteRowsOlderThan( int $timestamp ) :bool {
|
108 |
+
return $this->isReady() &&
|
109 |
+
$this->getQueryDeleter()
|
110 |
+
->addWhereOlderThan( $timestamp, $this->getTableSchema()->col_older_than )
|
111 |
+
->query();
|
112 |
+
}
|
113 |
+
|
114 |
+
public function getTable() :string {
|
115 |
+
return $this->getTableSchema()->table;
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* @return Iterator
|
120 |
+
*/
|
121 |
+
public function getIterator() {
|
122 |
+
$o = new Iterator();
|
123 |
+
return $o->setDbHandler( $this );
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* @return Delete|mixed
|
128 |
+
*/
|
129 |
+
public function getQueryDeleter() {
|
130 |
+
return ( new SubQueryLoader() )
|
131 |
+
->setDbHandler( $this )
|
132 |
+
->delete();
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* @return Insert|mixed
|
137 |
+
*/
|
138 |
+
public function getQueryInserter() {
|
139 |
+
return ( new SubQueryLoader() )
|
140 |
+
->setDbHandler( $this )
|
141 |
+
->insert();
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @return Select|mixed
|
146 |
+
*/
|
147 |
+
public function getQuerySelector() {
|
148 |
+
return ( new SubQueryLoader() )
|
149 |
+
->setDbHandler( $this )
|
150 |
+
->select()
|
151 |
+
->setResultsAsVo( true );
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* @return Update|mixed
|
156 |
+
*/
|
157 |
+
public function getQueryUpdater() {
|
158 |
+
return ( new SubQueryLoader() )
|
159 |
+
->setDbHandler( $this )
|
160 |
+
->update();
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* @return Record|mixed
|
165 |
+
*/
|
166 |
+
public function getRecord() {
|
167 |
+
return ( new SubQueryLoader() )
|
168 |
+
->setDbHandler( $this )
|
169 |
+
->record();
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* @return Record|mixed
|
174 |
+
* @deprecated
|
175 |
+
*/
|
176 |
+
public function getVo() {
|
177 |
+
return $this->getRecord();
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* @return $this
|
182 |
+
* @throws \Exception
|
183 |
+
*/
|
184 |
+
protected function tableCreate() {
|
185 |
+
$DB = Services::WpDb();
|
186 |
+
$sch = $this->getTableSchema();
|
187 |
+
if ( !$DB->getIfTableExists( $sch->table ) ) {
|
188 |
+
$DB->doSql( $sch->buildCreate() );
|
189 |
+
}
|
190 |
+
return $this;
|
191 |
+
}
|
192 |
+
|
193 |
+
public function tableDelete( bool $truncate = false ) :bool {
|
194 |
+
$table = $this->getTable();
|
195 |
+
$DB = Services::WpDb();
|
196 |
+
$mResult = !$this->tableExists() ||
|
197 |
+
( $truncate ? $DB->doTruncateTable( $table ) : $DB->doDropTable( $table ) );
|
198 |
+
$this->reset();
|
199 |
+
return $mResult !== false;
|
200 |
+
}
|
201 |
+
|
202 |
+
public function tableExists() :bool {
|
203 |
+
return Services::WpDb()->getIfTableExists( $this->getTable() );
|
204 |
+
}
|
205 |
+
|
206 |
+
public function tableTrimExcess( int $rowsLimit ) :self {
|
207 |
+
try {
|
208 |
+
$this->getQueryDeleter()->deleteExcess( $rowsLimit );
|
209 |
+
}
|
210 |
+
catch ( \Exception $e ) {
|
211 |
+
}
|
212 |
+
return $this;
|
213 |
+
}
|
214 |
+
|
215 |
+
public function isReady( bool $reTest = false ) :bool {
|
216 |
+
if ( $reTest ) {
|
217 |
+
$this->reset();
|
218 |
+
}
|
219 |
+
|
220 |
+
if ( !isset( $this->isReady ) ) {
|
221 |
+
try {
|
222 |
+
$align = new AlignTableWithSchema( $this->getTableSchema() );
|
223 |
+
$align->align();
|
224 |
+
$this->isReady = $this->tableExists() && $align->isAligned();
|
225 |
+
}
|
226 |
+
catch ( \Exception $e ) {
|
227 |
+
$this->isReady = false;
|
228 |
+
}
|
229 |
+
}
|
230 |
+
|
231 |
+
return $this->isReady;
|
232 |
+
}
|
233 |
+
|
234 |
+
public function getTableSchema() :TableSchema {
|
235 |
+
return $this->schema;
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* @return $this
|
240 |
+
*/
|
241 |
+
private function reset() {
|
242 |
+
unset( $this->isReady );
|
243 |
+
return $this;
|
244 |
+
}
|
245 |
+
|
246 |
+
public function getBaseNamespaces() :array {
|
247 |
+
return [ __NAMESPACE__ ];
|
248 |
+
}
|
249 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Insert.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
+
class Insert extends BaseQuery {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var array
|
11 |
+
*/
|
12 |
+
protected $insertData;
|
13 |
+
|
14 |
+
public function getInsertData() :array {
|
15 |
+
return array_intersect_key(
|
16 |
+
is_array( $this->insertData ) ? $this->insertData : [],
|
17 |
+
array_flip( $this->getDbH()->getTableSchema()->getColumnNames() )
|
18 |
+
);
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @param Record $record
|
23 |
+
* @return bool
|
24 |
+
*/
|
25 |
+
public function insert( $record ) :bool {
|
26 |
+
return $this->setInsertData( $record->getRawData() )->query() === 1;
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Verifies insert data keys against actual table columns
|
31 |
+
* @param array $data
|
32 |
+
* @return $this
|
33 |
+
*/
|
34 |
+
protected function setInsertData( $data ) {
|
35 |
+
$this->insertData = array_intersect_key(
|
36 |
+
is_array( $data ) ? $data : [],
|
37 |
+
array_flip( $this->getDbH()->getTableSchema()->getColumnNames() )
|
38 |
+
);
|
39 |
+
return $this;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return $this
|
44 |
+
* @throws \Exception
|
45 |
+
*/
|
46 |
+
protected function verifyInsertData() {
|
47 |
+
$baseData = [ 'created_at' => Services::Request()->ts() ];
|
48 |
+
if ( $this->getDbH()->getTableSchema()->hasColumn( 'updated_at' ) ) {
|
49 |
+
$baseData[ 'updated_at' ] = Services::Request()->ts();
|
50 |
+
}
|
51 |
+
return $this->setInsertData( array_merge( $baseData, $this->getInsertData() ) );
|
52 |
+
}
|
53 |
+
|
54 |
+
public function query() :bool {
|
55 |
+
try {
|
56 |
+
$this->verifyInsertData();
|
57 |
+
$this->lastQueryResult = Services::WpDb()
|
58 |
+
->insertDataIntoTable(
|
59 |
+
$this->getDbH()->getTable(),
|
60 |
+
$this->getInsertData()
|
61 |
+
);
|
62 |
+
$success = (bool)$this->lastQueryResult;
|
63 |
+
}
|
64 |
+
catch ( \Exception $e ) {
|
65 |
+
$success = false;
|
66 |
+
}
|
67 |
+
return $success;
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Offset never applies
|
72 |
+
*
|
73 |
+
* @return string
|
74 |
+
*/
|
75 |
+
protected function buildOffsetPhrase() {
|
76 |
+
return '';
|
77 |
+
}
|
78 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @property int $id
|
9 |
+
* @property array $meta
|
10 |
+
* @property int $created_at
|
11 |
+
* @property int $deleted_at
|
12 |
+
*/
|
13 |
+
class Record extends DynPropertiesClass {
|
14 |
+
|
15 |
+
public function __construct( array $row = [] ) {
|
16 |
+
$this->applyFromArray( $row );
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param string $key
|
21 |
+
* @return mixed
|
22 |
+
*/
|
23 |
+
public function __get( string $key ) {
|
24 |
+
|
25 |
+
$value = parent::__get( $key );
|
26 |
+
|
27 |
+
switch ( $key ) {
|
28 |
+
|
29 |
+
case 'meta':
|
30 |
+
if ( is_string( $value ) && !empty( $value ) ) {
|
31 |
+
$value = base64_decode( $value );
|
32 |
+
if ( !empty( $value ) ) {
|
33 |
+
$value = @json_decode( $value, true );
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
if ( !is_array( $value ) ) {
|
38 |
+
$value = [];
|
39 |
+
}
|
40 |
+
break;
|
41 |
+
|
42 |
+
default:
|
43 |
+
break;
|
44 |
+
}
|
45 |
+
|
46 |
+
if ( $key === 'id' || preg_match( '#^.*_at$#i', $key ) ) {
|
47 |
+
$value = (int)$value;
|
48 |
+
}
|
49 |
+
|
50 |
+
return $value;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @param string $key
|
55 |
+
* @param mixed $value
|
56 |
+
*/
|
57 |
+
public function __set( string $key, $value ) {
|
58 |
+
|
59 |
+
switch ( $key ) {
|
60 |
+
|
61 |
+
case 'meta':
|
62 |
+
if ( !is_array( $value ) ) {
|
63 |
+
$value = [];
|
64 |
+
}
|
65 |
+
$value = base64_encode( json_encode( $value ) );
|
66 |
+
break;
|
67 |
+
|
68 |
+
default:
|
69 |
+
break;
|
70 |
+
}
|
71 |
+
|
72 |
+
parent::__set( $key, $value );
|
73 |
+
}
|
74 |
+
|
75 |
+
public function getCreatedAt() :int {
|
76 |
+
return (int)$this->created_at;
|
77 |
+
}
|
78 |
+
|
79 |
+
public function getHash() :string {
|
80 |
+
$data = $this->getRawData();
|
81 |
+
asort( $data );
|
82 |
+
return md5( serialize( $data ) );
|
83 |
+
}
|
84 |
+
|
85 |
+
public function isDeleted() :bool {
|
86 |
+
return $this->deleted_at > 0;
|
87 |
+
}
|
88 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php
ADDED
@@ -0,0 +1,304 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
+
class Select extends BaseQuery {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var array
|
11 |
+
*/
|
12 |
+
protected $columnsToSelect;
|
13 |
+
|
14 |
+
protected $isCount = false;
|
15 |
+
|
16 |
+
protected $isSum = false;
|
17 |
+
|
18 |
+
protected $isDistinct = false;
|
19 |
+
|
20 |
+
protected $resultsAsVO;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
protected $customSelect;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
protected $resultFormat;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @param string $col
|
34 |
+
* @return $this
|
35 |
+
*/
|
36 |
+
public function addColumnToSelect( $col ) {
|
37 |
+
$aCols = $this->getColumnsToSelect();
|
38 |
+
$aCols[] = $col;
|
39 |
+
return $this->setColumnsToSelect( $aCols );
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return array[]|int|string[]|Record[]|mixed
|
44 |
+
*/
|
45 |
+
public function all() {
|
46 |
+
return $this->reset()->queryWithResult();
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @param int $ID
|
51 |
+
* @return \stdClass
|
52 |
+
*/
|
53 |
+
public function byId( $ID ) {
|
54 |
+
$items = $this->reset()
|
55 |
+
->addWhereEquals( 'id', $ID )
|
56 |
+
->queryWithResult();
|
57 |
+
return array_shift( $items );
|
58 |
+
}
|
59 |
+
|
60 |
+
public function buildQuery() :string {
|
61 |
+
return sprintf( $this->getBaseQuery(),
|
62 |
+
$this->buildSelect(),
|
63 |
+
$this->getDbH()->getTable(),
|
64 |
+
$this->buildWhere(),
|
65 |
+
$this->buildExtras()
|
66 |
+
);
|
67 |
+
}
|
68 |
+
|
69 |
+
protected function buildSelect() :string {
|
70 |
+
$cols = $this->getColumnsToSelect();
|
71 |
+
|
72 |
+
if ( $this->isCount() ) {
|
73 |
+
$substitute = 'COUNT(*)';
|
74 |
+
}
|
75 |
+
elseif ( $this->isSum() ) {
|
76 |
+
$substitute = sprintf( 'SUM(%s)', array_shift( $cols ) );
|
77 |
+
}
|
78 |
+
elseif ( $this->isDistinct() && $this->hasColumnsToSelect() ) {
|
79 |
+
$substitute = sprintf( 'DISTINCT %s', implode( ',', $cols ) );
|
80 |
+
}
|
81 |
+
elseif ( $this->hasColumnsToSelect() ) {
|
82 |
+
$substitute = implode( ',', $cols );
|
83 |
+
}
|
84 |
+
elseif ( $this->isCustomSelect() ) {
|
85 |
+
$substitute = $this->customSelect;
|
86 |
+
}
|
87 |
+
else {
|
88 |
+
$substitute = '*';
|
89 |
+
}
|
90 |
+
return $substitute;
|
91 |
+
}
|
92 |
+
|
93 |
+
public function sumColumn() :int {
|
94 |
+
return (int)$this->setIsCount( true )->queryWithResult();
|
95 |
+
}
|
96 |
+
|
97 |
+
public function count() :int {
|
98 |
+
return (int)$this->setIsCount( true )->queryWithResult();
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @return int
|
103 |
+
*/
|
104 |
+
public function sum() {
|
105 |
+
return $this->setIsSum( true )->queryWithResult();
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @return Record|\stdClass|mixed|null
|
110 |
+
*/
|
111 |
+
public function first() {
|
112 |
+
$r = $this->setLimit( 1 )->queryWithResult();
|
113 |
+
return empty( $r ) ? null : array_shift( $r );
|
114 |
+
}
|
115 |
+
|
116 |
+
protected function getBaseQuery() :string {
|
117 |
+
return "SELECT %s FROM `%s` WHERE %s %s";
|
118 |
+
}
|
119 |
+
|
120 |
+
public function getColumnsToSelect() :array {
|
121 |
+
return is_array( $this->columnsToSelect ) ? $this->columnsToSelect : [];
|
122 |
+
}
|
123 |
+
|
124 |
+
public function getDistinctForColumn( string $col ) :array {
|
125 |
+
return $this->reset()
|
126 |
+
->addColumnToSelect( $col )
|
127 |
+
->setIsDistinct( true )
|
128 |
+
->queryWithResult();
|
129 |
+
}
|
130 |
+
|
131 |
+
protected function getDistinct_FilterAndSort( string $col ) :array {
|
132 |
+
$a = array_filter( $this->getDistinctForColumn( $col ) );
|
133 |
+
natcasesort( $a );
|
134 |
+
return $a;
|
135 |
+
}
|
136 |
+
|
137 |
+
protected function getSelectDataFormat() :string {
|
138 |
+
if ( $this->isResultsAsVO() ) {
|
139 |
+
$format = ARRAY_A;
|
140 |
+
}
|
141 |
+
else {
|
142 |
+
$format = in_array( $this->resultFormat, [ OBJECT_K, ARRAY_A ] ) ? $this->resultFormat : OBJECT_K;
|
143 |
+
}
|
144 |
+
return $format;
|
145 |
+
}
|
146 |
+
|
147 |
+
protected function hasColumnsToSelect() :bool {
|
148 |
+
return count( $this->getColumnsToSelect() ) > 0;
|
149 |
+
}
|
150 |
+
|
151 |
+
public function isCount() :bool {
|
152 |
+
return (bool)$this->isCount;
|
153 |
+
}
|
154 |
+
|
155 |
+
public function isSum() :bool {
|
156 |
+
return (bool)$this->isSum;
|
157 |
+
}
|
158 |
+
|
159 |
+
public function isCustomSelect() :bool {
|
160 |
+
return !empty( $this->customSelect );
|
161 |
+
}
|
162 |
+
|
163 |
+
public function isDistinct() :bool {
|
164 |
+
return $this->isDistinct;
|
165 |
+
}
|
166 |
+
|
167 |
+
public function isResultsAsVO() :bool {
|
168 |
+
return ( $this->resultsAsVO ?? true ) && !$this->isSum();
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* COUNT, DISTINCT, & normal SELECT
|
173 |
+
*/
|
174 |
+
public function query() :bool {
|
175 |
+
$mData = [];
|
176 |
+
|
177 |
+
if ( $this->isCount() || $this->isSum() ) {
|
178 |
+
$this->lastQueryResult = $this->queryVar();
|
179 |
+
}
|
180 |
+
elseif ( $this->isDistinct() ) {
|
181 |
+
|
182 |
+
$this->lastQueryResult = $this->queryDistinct();
|
183 |
+
if ( is_array( $this->lastQueryResult ) ) {
|
184 |
+
$this->lastQueryResult = array_map( function ( $record ) {
|
185 |
+
return array_shift( $record );
|
186 |
+
}, $this->lastQueryResult );
|
187 |
+
}
|
188 |
+
else {
|
189 |
+
$this->lastQueryResult = [];
|
190 |
+
}
|
191 |
+
}
|
192 |
+
else {
|
193 |
+
|
194 |
+
$this->lastQueryResult = $this->querySelect();
|
195 |
+
if ( $this->isResultsAsVO() && !empty( $this->lastQueryResult ) ) {
|
196 |
+
$this->lastQueryResult = array_map( function ( $record ) {
|
197 |
+
return $this->getDbH()->getRecord()->applyFromArray( $record );
|
198 |
+
}, $this->lastQueryResult );
|
199 |
+
}
|
200 |
+
else {
|
201 |
+
$this->lastQueryResult = $mData;
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
$this->reset();
|
206 |
+
return !is_null( $this->lastQueryResult );
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* @return array[]
|
211 |
+
*/
|
212 |
+
protected function querySelect() {
|
213 |
+
return Services::WpDb()->selectCustom( $this->buildQuery(), $this->getSelectDataFormat() );
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* @return int
|
218 |
+
*/
|
219 |
+
protected function queryVar() {
|
220 |
+
return Services::WpDb()->getVar( $this->buildQuery() );
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* @return array[]
|
225 |
+
*/
|
226 |
+
protected function queryDistinct() {
|
227 |
+
return Services::WpDb()->selectCustom( $this->buildQuery() );
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* @return $this
|
232 |
+
*/
|
233 |
+
public function reset() {
|
234 |
+
parent::reset();
|
235 |
+
return $this->setIsCount( false )
|
236 |
+
->setIsDistinct( false )
|
237 |
+
->setGroupBy( '' )
|
238 |
+
->setSelectResultsFormat( '' )
|
239 |
+
->setCustomSelect( '' )
|
240 |
+
->setColumnsToSelect( [] )
|
241 |
+
->clearWheres();
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* @return Record|mixed|\stdClass|null
|
246 |
+
*/
|
247 |
+
public function selectLatestById() {
|
248 |
+
return $this->setOrderBy( 'id' )
|
249 |
+
->setLimit( 1 )
|
250 |
+
->first();
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* @return Record|mixed|\stdClass|null
|
255 |
+
*/
|
256 |
+
public function selectFirstById() {
|
257 |
+
return $this->setOrderBy( 'id', 'ASC' )
|
258 |
+
->setLimit( 1 )
|
259 |
+
->first();
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Verifies the given columns are valid and unique
|
264 |
+
* @param string[] $columns
|
265 |
+
* @return $this
|
266 |
+
*/
|
267 |
+
public function setColumnsToSelect( array $columns ) {
|
268 |
+
$this->columnsToSelect = array_intersect(
|
269 |
+
$this->getDbH()->getTableSchema()->getColumnNames(),
|
270 |
+
array_map( 'strtolower', $columns )
|
271 |
+
);
|
272 |
+
return $this;
|
273 |
+
}
|
274 |
+
|
275 |
+
public function setCustomSelect( string $select ) :self {
|
276 |
+
$this->customSelect = $select;
|
277 |
+
return $this;
|
278 |
+
}
|
279 |
+
|
280 |
+
public function setIsCount( bool $isCount ) :self {
|
281 |
+
$this->isCount = $isCount;
|
282 |
+
return $this;
|
283 |
+
}
|
284 |
+
|
285 |
+
public function setIsSum( bool $sum ) :self {
|
286 |
+
$this->isSum = $sum;
|
287 |
+
return $this;
|
288 |
+
}
|
289 |
+
|
290 |
+
public function setIsDistinct( bool $distinct ) :self {
|
291 |
+
$this->isDistinct = $distinct;
|
292 |
+
return $this;
|
293 |
+
}
|
294 |
+
|
295 |
+
public function setResultsAsVo( bool $asVO ) :self {
|
296 |
+
$this->resultsAsVO = $asVO;
|
297 |
+
return $this;
|
298 |
+
}
|
299 |
+
|
300 |
+
public function setSelectResultsFormat( string $format ) :self {
|
301 |
+
$this->resultFormat = $format;
|
302 |
+
return $this;
|
303 |
+
}
|
304 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Traits/Select_IPTable.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base\Traits;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Core\Utilities\Tool\IpListSort;
|
6 |
+
|
7 |
+
trait Select_IPTable {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return string[]
|
11 |
+
*/
|
12 |
+
public function getDistinctIps() :array {
|
13 |
+
$ips = $this->getDistinctForColumn( 'ip' );
|
14 |
+
if ( $this->getDbH()->getTableSchema()->is_ip_binary ) {
|
15 |
+
$ips = array_map(
|
16 |
+
function ( $binaryIP ) {
|
17 |
+
return inet_ntop( $binaryIP );
|
18 |
+
},
|
19 |
+
$ips
|
20 |
+
);
|
21 |
+
}
|
22 |
+
return IpListSort::Sort( $ips );
|
23 |
+
}
|
24 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php
ADDED
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
+
class Update extends Insert {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var array
|
11 |
+
*/
|
12 |
+
protected $updateWheres = [];
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return array
|
16 |
+
*/
|
17 |
+
public function getUpdateData() {
|
18 |
+
return $this->getInsertData();
|
19 |
+
}
|
20 |
+
|
21 |
+
public function getUpdateWheres() :array {
|
22 |
+
return is_array( $this->updateWheres ) ? $this->updateWheres : [];
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @param array $data
|
27 |
+
* @return $this
|
28 |
+
*/
|
29 |
+
public function setUpdateData( $data ) {
|
30 |
+
return $this->setInsertData( $data );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @param array $updateWheres
|
35 |
+
* @return $this
|
36 |
+
*/
|
37 |
+
public function setUpdateWheres( $updateWheres ) {
|
38 |
+
$this->updateWheres = $updateWheres;
|
39 |
+
return $this;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @param int $ID
|
44 |
+
* @return $this
|
45 |
+
*/
|
46 |
+
public function setUpdateId( $ID ) {
|
47 |
+
$this->updateWheres = [ 'id' => $ID ];
|
48 |
+
return $this;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @param Record $record
|
53 |
+
* @param array $updateData
|
54 |
+
* @return bool
|
55 |
+
*/
|
56 |
+
public function updateEntry( $record, $updateData = [] ) :bool {
|
57 |
+
return $this->updateRecord( $record, $updateData );
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @param Record $record
|
62 |
+
* @param array $updateData
|
63 |
+
* @return bool
|
64 |
+
*/
|
65 |
+
public function updateRecord( $record, $updateData = [] ) :bool {
|
66 |
+
$success = false;
|
67 |
+
|
68 |
+
if ( $record instanceof Record ) {
|
69 |
+
|
70 |
+
foreach ( $record->getRawData() as $key => $value ) {
|
71 |
+
if ( isset( $updateData[ $key ] ) && $updateData[ $key ] === $value ) {
|
72 |
+
unset( $updateData[ $key ] );
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
if ( empty( $updateData ) ) {
|
77 |
+
$success = true;
|
78 |
+
}
|
79 |
+
else {
|
80 |
+
if ( $this->getDbH()->getTableSchema()->hasColumn( 'updated_at' )
|
81 |
+
&& !isset( $updateData[ 'updated_at' ] ) ) {
|
82 |
+
$updateData[ 'updated_at' ] = Services::Request()->ts();
|
83 |
+
}
|
84 |
+
if ( $this->updateById( $record->id, $updateData ) ) {
|
85 |
+
$record->applyFromArray( array_merge( $record->getRawData(), $updateData ) );
|
86 |
+
$success = true;
|
87 |
+
}
|
88 |
+
}
|
89 |
+
}
|
90 |
+
|
91 |
+
return $success;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @param int $id
|
96 |
+
* @param array $updateData
|
97 |
+
* @return bool true is success or no update necessary
|
98 |
+
*/
|
99 |
+
public function updateById( $id, $updateData = [] ) {
|
100 |
+
$success = true;
|
101 |
+
|
102 |
+
if ( !empty( $updateData ) ) {
|
103 |
+
$success = $this->setUpdateId( $id )
|
104 |
+
->setUpdateData( $updateData )
|
105 |
+
->query();
|
106 |
+
}
|
107 |
+
return $success;
|
108 |
+
}
|
109 |
+
|
110 |
+
public function query() :bool {
|
111 |
+
$this->lastQueryResult = Services::WpDb()
|
112 |
+
->updateRowsFromTableWhere(
|
113 |
+
$this->getDbH()->getTable(),
|
114 |
+
$this->getUpdateData(),
|
115 |
+
$this->getUpdateWheres()
|
116 |
+
);
|
117 |
+
return (bool)$this->lastQueryResult;
|
118 |
+
}
|
119 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php
ADDED
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Common;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
+
class AlignTableWithSchema {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var TableSchema
|
11 |
+
*/
|
12 |
+
private $schema;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var string[]
|
16 |
+
*/
|
17 |
+
private $cols = null;
|
18 |
+
|
19 |
+
public function __construct( TableSchema $schema ) {
|
20 |
+
$this->schema = $schema;
|
21 |
+
}
|
22 |
+
|
23 |
+
public function isAligned() :bool {
|
24 |
+
$colsActual = $this->getColumnsActual();
|
25 |
+
$colsSchema = $this->schema->getColumnNames();
|
26 |
+
asort( $colsActual );
|
27 |
+
asort( $colsSchema );
|
28 |
+
return $colsActual === $colsSchema;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function align() {
|
32 |
+
$DB = Services::WpDb();
|
33 |
+
if ( !$DB->getIfTableExists( $this->schema->table ) ) {
|
34 |
+
$DB->doSql( $this->schema->buildCreate() );
|
35 |
+
}
|
36 |
+
else {
|
37 |
+
$this->alignColumns();
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
private function alignColumns() {
|
42 |
+
$DB = Services::WpDb();
|
43 |
+
$colsUpdated = false;
|
44 |
+
|
45 |
+
$colsActual = $this->getColumnsActual();
|
46 |
+
$colsSchema = $this->schema->getColumnNames();
|
47 |
+
|
48 |
+
// Are columns missing?
|
49 |
+
foreach ( array_diff( $colsSchema, $colsActual ) as $col ) {
|
50 |
+
$this->addColumn( $col );
|
51 |
+
$colsUpdated = true;
|
52 |
+
}
|
53 |
+
|
54 |
+
// Extra columns?
|
55 |
+
foreach ( array_diff( $colsActual, $colsSchema ) as $col ) {
|
56 |
+
$DB->doSql( sprintf( 'ALTER TABLE `%s` DROP `%s`;', $this->schema->table, $col ) );
|
57 |
+
$colsUpdated = true;
|
58 |
+
}
|
59 |
+
|
60 |
+
if ( $colsUpdated ) {
|
61 |
+
$this->cols = null;
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
private function addColumn( string $col ) {
|
66 |
+
$colsSchema = $this->schema->enumerateColumns();
|
67 |
+
if ( array_key_exists( $col, $colsSchema ) ) {
|
68 |
+
|
69 |
+
if ( key( $colsSchema ) === $col ) {
|
70 |
+
$position = 'FIRST';
|
71 |
+
}
|
72 |
+
else {
|
73 |
+
// find the correct position to insert the col
|
74 |
+
while ( key( $colsSchema ) !== $col ) {
|
75 |
+
next( $colsSchema );
|
76 |
+
}
|
77 |
+
prev( $colsSchema );
|
78 |
+
$position = 'AFTER '.key( $colsSchema );
|
79 |
+
}
|
80 |
+
|
81 |
+
Services::WpDb()->doSql( sprintf( 'ALTER TABLE `%s` ADD COLUMN %s %s %s;',
|
82 |
+
$this->schema->table,
|
83 |
+
$col,
|
84 |
+
$colsSchema[ $col ],
|
85 |
+
$position
|
86 |
+
) );
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* @return string[]
|
92 |
+
*/
|
93 |
+
private function getColumnsActual() :array {
|
94 |
+
if ( is_null( $this->cols ) ) {
|
95 |
+
$this->cols = Services::WpDb()->getColumnsForTable( $this->schema->table );
|
96 |
+
}
|
97 |
+
return is_array( $this->cols ) ? array_map( 'strtolower', $this->cols ) : [];
|
98 |
+
}
|
99 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Common;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Services\Services;
|
6 |
+
|
7 |
+
class BuildColumnFromDef {
|
8 |
+
|
9 |
+
const MACROTYPE_PRIMARYID = 'primary_id';
|
10 |
+
const MACROTYPE_TIMESTAMP = 'timestamp';
|
11 |
+
const MACROTYPE_UNSIGNEDINT = 'unsigned_int';
|
12 |
+
const MACROTYPE_HASH = 'hash';
|
13 |
+
const MACROTYPE_IP = 'ip';
|
14 |
+
const MACROTYPE_META = 'meta';
|
15 |
+
const MACROTYPE_TEXT = 'text';
|
16 |
+
const MACROTYPE_URL = 'url';
|
17 |
+
const MACROTYPE_BOOL = 'bool';
|
18 |
+
const MACROTYPE_VARCHAR = 'varchar';
|
19 |
+
|
20 |
+
private $def;
|
21 |
+
|
22 |
+
public function __construct( array $def ) {
|
23 |
+
$this->setDef( $def );
|
24 |
+
}
|
25 |
+
|
26 |
+
public function setDef( array $def ) {
|
27 |
+
$this->def = $def;
|
28 |
+
return $this;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function build() :string {
|
32 |
+
$def = $this->buildStructure();
|
33 |
+
return sprintf( '%s%s %s %s %s',
|
34 |
+
$def[ 'type' ],
|
35 |
+
isset( $def[ 'length' ] ) ? sprintf( '(%s)', $def[ 'length' ] ) : '',
|
36 |
+
implode( ' ', $def[ 'attr' ] ?? [] ),
|
37 |
+
isset( $def[ 'default' ] ) ? sprintf( "DEFAULT %s", $def[ 'default' ] ) : '',
|
38 |
+
isset( $def[ 'comment' ] ) ? sprintf( "COMMENT '%s'", str_replace( "'", '', $def[ 'comment' ] ) ) : ''
|
39 |
+
);
|
40 |
+
}
|
41 |
+
|
42 |
+
protected function buildStructure() :array {
|
43 |
+
return Services::DataManipulation()->mergeArraysRecursive(
|
44 |
+
$this->getMacroTypeDef( $this->def[ 'macro_type' ] ?? '' ),
|
45 |
+
$this->def
|
46 |
+
);
|
47 |
+
}
|
48 |
+
|
49 |
+
protected function getMacroTypeDef( string $macroType ) :array {
|
50 |
+
switch ( $macroType ) {
|
51 |
+
|
52 |
+
case self::MACROTYPE_HASH:
|
53 |
+
$def = array_merge(
|
54 |
+
$this->getMacroTypeDef( self::MACROTYPE_VARCHAR ),
|
55 |
+
[
|
56 |
+
'length' => 40,
|
57 |
+
'comment' => 'SHA1 Hash',
|
58 |
+
]
|
59 |
+
);
|
60 |
+
break;
|
61 |
+
|
62 |
+
case self::MACROTYPE_IP:
|
63 |
+
$def = [
|
64 |
+
'type' => 'varbinary',
|
65 |
+
'length' => 16,
|
66 |
+
'attr' => [],
|
67 |
+
'default' => 'NULL',
|
68 |
+
'comment' => 'IP Address',
|
69 |
+
];
|
70 |
+
break;
|
71 |
+
|
72 |
+
case self::MACROTYPE_META:
|
73 |
+
$def = array_merge(
|
74 |
+
$this->getMacroTypeDef( self::MACROTYPE_TEXT ),
|
75 |
+
[
|
76 |
+
'comment' => 'Meta Data',
|
77 |
+
]
|
78 |
+
);
|
79 |
+
break;
|
80 |
+
|
81 |
+
case self::MACROTYPE_TEXT:
|
82 |
+
$def = [
|
83 |
+
'type' => 'text',
|
84 |
+
];
|
85 |
+
break;
|
86 |
+
|
87 |
+
case self::MACROTYPE_URL:
|
88 |
+
$def = array_merge(
|
89 |
+
$this->getMacroTypeDef( self::MACROTYPE_VARCHAR ),
|
90 |
+
[
|
91 |
+
'comment' => 'Site URL',
|
92 |
+
]
|
93 |
+
);
|
94 |
+
break;
|
95 |
+
|
96 |
+
case self::MACROTYPE_VARCHAR:
|
97 |
+
$def = [
|
98 |
+
'type' => 'varchar',
|
99 |
+
'length' => 60,
|
100 |
+
'attr' => [
|
101 |
+
'NOT NULL',
|
102 |
+
],
|
103 |
+
'default' => "''",
|
104 |
+
];
|
105 |
+
break;
|
106 |
+
|
107 |
+
case self::MACROTYPE_BOOL:
|
108 |
+
$def = array_merge(
|
109 |
+
$this->getMacroTypeDef( self::MACROTYPE_UNSIGNEDINT ),
|
110 |
+
[
|
111 |
+
'type' => 'tinyint',
|
112 |
+
'length' => 1,
|
113 |
+
'comment' => 'Boolean',
|
114 |
+
]
|
115 |
+
);
|
116 |
+
break;
|
117 |
+
|
118 |
+
case self::MACROTYPE_TIMESTAMP:
|
119 |
+
$def = array_merge(
|
120 |
+
$this->getMacroTypeDef( self::MACROTYPE_UNSIGNEDINT ),
|
121 |
+
[
|
122 |
+
'length' => 15,
|
123 |
+
'comment' => 'Epoch Timestamp',
|
124 |
+
]
|
125 |
+
);
|
126 |
+
break;
|
127 |
+
|
128 |
+
case self::MACROTYPE_UNSIGNEDINT:
|
129 |
+
$def = [
|
130 |
+
'type' => 'int',
|
131 |
+
'length' => 11,
|
132 |
+
'attr' => [
|
133 |
+
'UNSIGNED',
|
134 |
+
'NOT NULL',
|
135 |
+
],
|
136 |
+
'default' => 0,
|
137 |
+
];
|
138 |
+
break;
|
139 |
+
|
140 |
+
case self::MACROTYPE_PRIMARYID:
|
141 |
+
$def = array_merge(
|
142 |
+
$this->getMacroTypeDef( self::MACROTYPE_UNSIGNEDINT ),
|
143 |
+
[
|
144 |
+
'comment' => 'Primary ID',
|
145 |
+
]
|
146 |
+
);
|
147 |
+
$def[ 'attr' ][] = 'AUTO_INCREMENT';
|
148 |
+
break;
|
149 |
+
|
150 |
+
default:
|
151 |
+
$def = [];
|
152 |
+
break;
|
153 |
+
}
|
154 |
+
|
155 |
+
return $def;
|
156 |
+
}
|
157 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/HandlerConsumer.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Common;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Core\Databases\Base\Handler;
|
6 |
+
|
7 |
+
trait HandlerConsumer {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var Handler
|
11 |
+
*/
|
12 |
+
private $dbh;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return Handler|mixed
|
16 |
+
*/
|
17 |
+
public function getDbHandler() {
|
18 |
+
return $this->dbh;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @param Handler $dbh
|
23 |
+
* @return $this
|
24 |
+
*/
|
25 |
+
public function setDbHandler( $dbh ) {
|
26 |
+
$this->dbh = $dbh;
|
27 |
+
return $this;
|
28 |
+
}
|
29 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/Iterator.php
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Common;
|
4 |
+
|
5 |
+
use Elliotchance\Iterator\AbstractPagedIterator;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Core\Databases\Base\Record;
|
7 |
+
use FernleafSystems\Wordpress\Plugin\Core\Databases\Base\Select;
|
8 |
+
|
9 |
+
class Iterator extends AbstractPagedIterator {
|
10 |
+
|
11 |
+
const PAGE_LIMIT = 50;
|
12 |
+
use HandlerConsumer;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var Select|mixed
|
16 |
+
*/
|
17 |
+
private $selector;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var int
|
21 |
+
*/
|
22 |
+
private $totalSize;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var array
|
26 |
+
*/
|
27 |
+
private $customFilters = [];
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @return Record|mixed|null
|
31 |
+
*/
|
32 |
+
public function current() {
|
33 |
+
return parent::current();
|
34 |
+
}
|
35 |
+
|
36 |
+
public function getCustomQueryFilters() :array {
|
37 |
+
return is_array( $this->customFilters ) ? $this->customFilters : [];
|
38 |
+
}
|
39 |
+
|
40 |
+
protected function getDefaultQueryFilters() :array {
|
41 |
+
return [
|
42 |
+
'orderby' => 'id',
|
43 |
+
'order' => 'ASC',
|
44 |
+
];
|
45 |
+
}
|
46 |
+
|
47 |
+
protected function getFinalQueryFilters() :array {
|
48 |
+
return array_merge( $this->getDefaultQueryFilters(), $this->getCustomQueryFilters() );
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @param int $nPage - always starts at 0
|
53 |
+
* @return array
|
54 |
+
*/
|
55 |
+
public function getPage( $nPage ) {
|
56 |
+
$aParams = $this->getFinalQueryFilters();
|
57 |
+
|
58 |
+
$this->getSelector()
|
59 |
+
->setResultsAsVo( true )
|
60 |
+
->setPage( $nPage + 1 ) // Pages start at 1, not zero.
|
61 |
+
->setLimit( $this->getPageSize() )
|
62 |
+
->setOrderBy( $aParams[ 'orderby' ], $aParams[ 'order' ] );
|
63 |
+
|
64 |
+
return $this->runQuery();
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @return int
|
69 |
+
*/
|
70 |
+
public function getPageSize() {
|
71 |
+
return static::PAGE_LIMIT;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @return Select|mixed
|
76 |
+
*/
|
77 |
+
public function getSelector() {
|
78 |
+
if ( empty( $this->selector ) ) {
|
79 |
+
$this->selector = $this->getDbHandler()->getQuerySelector();
|
80 |
+
}
|
81 |
+
return $this->selector;
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* @return int
|
86 |
+
*/
|
87 |
+
public function getTotalSize() {
|
88 |
+
if ( !isset( $this->totalSize ) ) {
|
89 |
+
$this->totalSize = $this->runQueryCount();
|
90 |
+
}
|
91 |
+
return $this->totalSize;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @return Record[]|mixed[]
|
96 |
+
*/
|
97 |
+
protected function runQuery() {
|
98 |
+
return ( clone $this->getSelector() )->query();
|
99 |
+
}
|
100 |
+
|
101 |
+
protected function runQueryCount() :int {
|
102 |
+
return (int)( clone $this->getSelector() )->count();
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* @param Select|mixed $selector
|
107 |
+
* @return $this
|
108 |
+
*/
|
109 |
+
public function setSelector( $selector ) {
|
110 |
+
$this->selector = $selector;
|
111 |
+
return $this;
|
112 |
+
}
|
113 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/RecordConsumer.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Common;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Core\Databases\Base\Record;
|
6 |
+
|
7 |
+
trait RecordConsumer {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var Record
|
11 |
+
*/
|
12 |
+
private $dbRecord;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return Record|mixed
|
16 |
+
*/
|
17 |
+
public function getRecord() {
|
18 |
+
return $this->dbRecord;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @param Record $record
|
23 |
+
* @return $this
|
24 |
+
*/
|
25 |
+
public function setRecord( $record ) {
|
26 |
+
$this->dbRecord = $record;
|
27 |
+
return $this;
|
28 |
+
}
|
29 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/SubQueryLoader.php
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Common;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Core\Databases\Base\{
|
6 |
+
BaseQuery,
|
7 |
+
Delete,
|
8 |
+
Insert,
|
9 |
+
Record,
|
10 |
+
Select,
|
11 |
+
Update
|
12 |
+
};
|
13 |
+
use FernleafSystems\Wordpress\Services\Utilities\Autoloading\FindClassFromNamespaceRoots;
|
14 |
+
|
15 |
+
class SubQueryLoader {
|
16 |
+
|
17 |
+
use HandlerConsumer;
|
18 |
+
|
19 |
+
public function loadClass( string $class ) {
|
20 |
+
/** @var BaseQuery $o */
|
21 |
+
$o = new $class;
|
22 |
+
return method_exists( $o, 'setDbH' ) ? $o->setDbH( $this->getDbHandler() ) : $o;
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @return Delete|mixed
|
27 |
+
*/
|
28 |
+
public function delete() {
|
29 |
+
return $this->loadClass(
|
30 |
+
FindClassFromNamespaceRoots::Find( 'Delete', $this->getNamespaceRoots() )
|
31 |
+
);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @return Insert|mixed
|
36 |
+
*/
|
37 |
+
public function insert() {
|
38 |
+
return $this->loadClass(
|
39 |
+
FindClassFromNamespaceRoots::Find( 'Insert', $this->getNamespaceRoots() )
|
40 |
+
);
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @return Record|mixed
|
45 |
+
*/
|
46 |
+
public function record() {
|
47 |
+
return $this->loadClass(
|
48 |
+
FindClassFromNamespaceRoots::Find( 'Record', $this->getNamespaceRoots() )
|
49 |
+
);
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @return Select|mixed
|
54 |
+
*/
|
55 |
+
public function select() {
|
56 |
+
return $this->loadClass(
|
57 |
+
FindClassFromNamespaceRoots::Find( 'Select', $this->getNamespaceRoots() )
|
58 |
+
);
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @return Update|mixed
|
63 |
+
*/
|
64 |
+
public function update() {
|
65 |
+
return $this->loadClass(
|
66 |
+
FindClassFromNamespaceRoots::Find( 'Update', $this->getNamespaceRoots() )
|
67 |
+
);
|
68 |
+
}
|
69 |
+
|
70 |
+
protected function getNamespaceRoots() :array {
|
71 |
+
$dbh = $this->getDbHandler();
|
72 |
+
$roots = $dbh->getBaseNamespaces();
|
73 |
+
array_unshift( $roots, $this->getPrimaryNamespace() );
|
74 |
+
return $roots;
|
75 |
+
}
|
76 |
+
|
77 |
+
private function getPrimaryNamespace() :string {
|
78 |
+
try {
|
79 |
+
$namespace = ( new \ReflectionClass( $this->getDbHandler() ) )->getNamespaceName();
|
80 |
+
}
|
81 |
+
catch ( \Exception $e ) {
|
82 |
+
$namespace = __NAMESPACE__;
|
83 |
+
}
|
84 |
+
return rtrim( $namespace, '\\' );
|
85 |
+
}
|
86 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableSchema.php
ADDED
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Common;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class TableSchema
|
10 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Databases\Common
|
11 |
+
* @property string $slug
|
12 |
+
* @property string $table - full and complete table name including any prefixes
|
13 |
+
* @property string $table_prefix
|
14 |
+
* @property string $primary_key
|
15 |
+
* @property string[] $cols_ids
|
16 |
+
* @property string[] $cols_custom
|
17 |
+
* @property string[] $cols_timestamps
|
18 |
+
* @property string $col_older_than
|
19 |
+
* @property bool $has_updated_at
|
20 |
+
* @property int $autoexpire
|
21 |
+
* @property bool $has_ip_col
|
22 |
+
* @property bool $is_ip_binary
|
23 |
+
*/
|
24 |
+
class TableSchema extends DynPropertiesClass {
|
25 |
+
|
26 |
+
const PRIMARY_KEY = 'id';
|
27 |
+
|
28 |
+
public function __get( string $key ) {
|
29 |
+
$val = parent::__get( $key );
|
30 |
+
switch ( $key ) {
|
31 |
+
case 'has_ip_col':
|
32 |
+
$val = array_key_exists( 'ip', $this->enumerateColumns() );
|
33 |
+
break;
|
34 |
+
case 'is_ip_binary':
|
35 |
+
$val = $this->has_ip_col && ( stripos( $this->cols_custom[ 'ip' ], 'varbinary' ) !== false );
|
36 |
+
break;
|
37 |
+
case 'table':
|
38 |
+
$val = $this->buildTableName();
|
39 |
+
break;
|
40 |
+
case 'col_older_than':
|
41 |
+
if ( empty( $val ) || !$this->hasColumn( $val ) ) {
|
42 |
+
$val = 'created_at';
|
43 |
+
}
|
44 |
+
break;
|
45 |
+
case 'has_updated_at':
|
46 |
+
$val = is_null( $val ) ? true : $val;
|
47 |
+
break;
|
48 |
+
default:
|
49 |
+
break;
|
50 |
+
}
|
51 |
+
return $val;
|
52 |
+
}
|
53 |
+
|
54 |
+
protected function buildTableName() :string {
|
55 |
+
return sprintf( '%s%s%s',
|
56 |
+
Services::WpDb()->getPrefix(),
|
57 |
+
empty( $this->table_prefix ) ? '' : $this->table_prefix.'_',
|
58 |
+
$this->slug
|
59 |
+
);
|
60 |
+
}
|
61 |
+
|
62 |
+
public function buildCreate() :string {
|
63 |
+
$cols = [];
|
64 |
+
foreach ( $this->enumerateColumns() as $col => $def ) {
|
65 |
+
$cols[] = sprintf( '%s %s', $col, $def );
|
66 |
+
}
|
67 |
+
$cols[] = $this->getPrimaryKeyDef();
|
68 |
+
|
69 |
+
return sprintf(
|
70 |
+
'CREATE TABLE %s (
|
71 |
+
%s
|
72 |
+
) %s;',
|
73 |
+
$this->table,
|
74 |
+
implode( ", ", $cols ),
|
75 |
+
Services::WpDb()->getCharCollate()
|
76 |
+
);
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* @return string[]
|
81 |
+
*/
|
82 |
+
public function getColumnNames() :array {
|
83 |
+
return array_keys( $this->enumerateColumns() );
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @return string[]
|
88 |
+
*/
|
89 |
+
public function enumerateColumns() :array {
|
90 |
+
return array_map(
|
91 |
+
function ( array $colDef ) {
|
92 |
+
// convert from array column def to string.
|
93 |
+
return ( new BuildColumnFromDef( $colDef ) )->build();
|
94 |
+
},
|
95 |
+
array_merge(
|
96 |
+
$this->getColumn_ID(),
|
97 |
+
$this->cols_custom ?? [],
|
98 |
+
$this->getColumns_Timestamps()
|
99 |
+
)
|
100 |
+
);
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* @return string[]
|
105 |
+
*/
|
106 |
+
protected function getColumn_ID() :array {
|
107 |
+
return [
|
108 |
+
$this->getPrimaryKeyColumnName() => [ 'macro_type' => BuildColumnFromDef::MACROTYPE_PRIMARYID ],
|
109 |
+
];
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* @return string[]
|
114 |
+
*/
|
115 |
+
protected function getColumns_Timestamps() :array {
|
116 |
+
|
117 |
+
$standardTsCols = [
|
118 |
+
'created_at' => [
|
119 |
+
'comment' => 'Created'
|
120 |
+
],
|
121 |
+
'deleted_at' => [
|
122 |
+
'comment' => 'Soft Deleted'
|
123 |
+
],
|
124 |
+
];
|
125 |
+
|
126 |
+
if ( $this->has_updated_at && !array_key_exists( 'updated_at', $this->cols_timestamps ) ) {
|
127 |
+
$standardTsCols[ 'updated_at' ] = [
|
128 |
+
'comment' => 'Last Updated'
|
129 |
+
];
|
130 |
+
}
|
131 |
+
|
132 |
+
return array_map(
|
133 |
+
function ( array $colDef ) {
|
134 |
+
$colDef[ 'macro_type' ] = BuildColumnFromDef::MACROTYPE_TIMESTAMP;
|
135 |
+
return $colDef;
|
136 |
+
},
|
137 |
+
array_merge(
|
138 |
+
$this->cols_timestamps ?? [],
|
139 |
+
$standardTsCols
|
140 |
+
)
|
141 |
+
);
|
142 |
+
}
|
143 |
+
|
144 |
+
protected function getPrimaryKeyDef() :string {
|
145 |
+
return sprintf( 'PRIMARY KEY (%s)', $this->getPrimaryKeyColumnName() );
|
146 |
+
}
|
147 |
+
|
148 |
+
protected function getPrimaryKeyColumnName() :string {
|
149 |
+
return $this->primary_key ?? static::PRIMARY_KEY;
|
150 |
+
}
|
151 |
+
|
152 |
+
public function hasColumn( string $col ) :bool {
|
153 |
+
return in_array( strtolower( $col ), $this->getColumnNames() );
|
154 |
+
}
|
155 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/NoSlugProvidedException.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Exceptions;
|
4 |
+
|
5 |
+
class NoSlugProvidedException extends \InvalidArgumentException {
|
6 |
+
|
7 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Autoloading/FindClassFromNamespaceRoots.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php declare( strict_types=1 );
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Services\Utilities\Autoloading;
|
4 |
+
|
5 |
+
class FindClassFromNamespaceRoots {
|
6 |
+
|
7 |
+
public static function Find( string $class, array $roots, bool $beInstantiable = true, bool $throwEx = true ) :string {
|
8 |
+
$theClass = '';
|
9 |
+
|
10 |
+
$roots = array_map( function ( $root ) {
|
11 |
+
return rtrim( $root, '\\' ).'\\';
|
12 |
+
}, $roots );
|
13 |
+
|
14 |
+
foreach ( $roots as $NS ) {
|
15 |
+
$maybe = $NS.$class;
|
16 |
+
if ( @class_exists( $maybe ) ) {
|
17 |
+
try {
|
18 |
+
if ( !$beInstantiable || ( new \ReflectionClass( $maybe ) )->isInstantiable() ) {
|
19 |
+
$theClass = $maybe;
|
20 |
+
break;
|
21 |
+
}
|
22 |
+
}
|
23 |
+
catch ( \ReflectionException $e ) {
|
24 |
+
continue;
|
25 |
+
}
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
if ( $throwEx && empty( $theClass ) ) {
|
30 |
+
throw new \Exception( sprintf( 'Could not find class for element "%s".', $class ) );
|
31 |
+
}
|
32 |
+
|
33 |
+
return $theClass;
|
34 |
+
}
|
35 |
+
}
|
templates/twig/wpadmin_pages/insights/ips/ip_analyse/ip_general.twig
CHANGED
@@ -45,11 +45,11 @@
|
|
45 |
</p>
|
46 |
</dd>
|
47 |
|
48 |
-
<dt class="mb-1">{{ strings.status.
|
49 |
<dd>
|
50 |
<p>
|
51 |
<span class="bigger-badge badge badge-{{ vars.status.is_bot ? 'warning' : 'success' }}">
|
52 |
-
{{ vars.status.
|
53 |
</span>
|
54 |
<a href="#" class="ml-2 text-primary ip_analyse_action"
|
55 |
data-ip_action="delete_notbot" data-ip="{{ vars.ip }}">{{ strings.delete_notbot }}</a>
|
45 |
</p>
|
46 |
</dd>
|
47 |
|
48 |
+
<dt class="mb-1">{{ strings.status.ip_reputation }}</dt>
|
49 |
<dd>
|
50 |
<p>
|
51 |
<span class="bigger-badge badge badge-{{ vars.status.is_bot ? 'warning' : 'success' }}">
|
52 |
+
{{ vars.status.ip_reputation_score }}
|
53 |
</span>
|
54 |
<a href="#" class="ml-2 text-primary ip_analyse_action"
|
55 |
data-ip_action="delete_notbot" data-ip="{{ vars.ip }}">{{ strings.delete_notbot }}</a>
|