Version Description
Current Release = Released: 6th December, 2019 - Release Notes
(v.4) IMPROVED: Discovered serious conflict with SiteGround Optimizer plugin. Provided admin notice and automatic fixing.
(v.4) FIXED: Protected against spurious error log notices when comparing hashes with "nothing".
Download this release
Release Info
Developer | paultgoodchild |
Plugin | Shield Security for WordPress |
Version | 8.4.4 |
Comparing to | |
See all releases |
Code changes from version 8.3.0 to 8.4.4
- changelog.html +728 -706
- filesnotfound.php +1 -6
- icwp-plugin-controller.php +0 -25
- icwp-wpsf.php +5 -5
- plugin-spec.php +11 -11
- readme.txt +38 -115
- resources/css/chartist.min.css +1 -1
- resources/css/plugin.css +1 -2
- resources/js/chartist.min.js +3 -3
- resources/js/charts.js +17 -1
- resources/js/global-plugin.js +1 -1
- resources/js/shield-comments.js +137 -0
- src/common/icwp-data.php +5 -5
- src/common/icwp-edd.php +0 -172
- src/common/icwp-foundation.php +4 -239
- src/common/icwp-optionsvo.php +0 -991
- src/common/icwp-render.php +0 -316
- src/common/icwp-request.php +0 -310
- src/common/icwp-serviceproviders.php +11 -16
- src/common/icwp-wpdb.php +0 -237
- src/common/icwp-wpfilesystem.php +0 -492
- src/common/icwp-wpfunctions-plugins.php +0 -547
- src/common/icwp-wpfunctions-themes.php +0 -365
- src/common/icwp-wpfunctions.php +0 -936
- src/common/icwp-wpincludes.php +0 -79
- src/common/icwp-wpupgrades.php +0 -358
- src/common/wp-admin-notices.php +4 -186
- src/common/wp-comments.php +0 -105
- src/common/wp-users.php +0 -290
- src/common/wp-widget.php +1 -0
- src/config/changelog.json +4 -4
- src/config/feature-admin_access_restriction.php +23 -22
- src/config/feature-audit_trail.php +18 -18
- src/config/feature-autoupdates.php +5 -5
- src/config/feature-comments_filter.php +19 -19
- src/config/feature-firewall.php +3 -3
- src/config/feature-hack_protect.php +26 -26
- src/config/feature-headers.php +11 -11
- src/config/feature-ips.php +25 -24
- src/config/feature-license.php +1 -1
- src/config/feature-lockdown.php +7 -7
- src/config/feature-login_protect.php +28 -28
- src/config/feature-plugin.php +19 -10
- src/config/feature-traffic.php +4 -4
- src/config/feature-user_management.php +12 -12
- src/features/admin_access_restriction.php +0 -79
- src/features/audit_trail.php +1 -115
- src/features/autoupdates.php +158 -137
- src/features/base.php +17 -66
- src/features/base_wpsf.php +8 -6
- src/features/events.php +1 -1
- src/features/hack_protect.php +5 -38
- src/features/headers.php +2 -1
- src/features/insights.php +75 -45
- src/features/ips.php +1 -119
- src/features/license.php +2 -2
- src/features/login_protect.php +3 -3
- src/features/plugin.php +11 -12
- src/features/sessions.php +1 -1
- src/features/statistics.php +1 -1
- src/features/traffic.php +1 -9
- src/features/user_management.php +0 -9
- src/lib/src/AuditTrail/Auditor.php +0 -14
- src/lib/src/Controller/Controller.php +14 -0
- src/lib/src/Databases/AuditTrail/Handler.php +1 -3
- src/lib/src/Databases/AuditTrail/Select.php +0 -12
- src/lib/src/Databases/Base/BaseQuery.php +45 -4
- src/lib/src/Databases/Events/Common.php +26 -0
- src/lib/src/Databases/Events/Delete.php +1 -0
- src/lib/src/Databases/Events/Select.php +23 -17
- src/lib/src/Databases/IPs/CommonFilters.php +8 -0
- src/lib/src/Deprecated/Foundation.php +1 -166
- src/lib/src/Modules/Autoupdates/AjaxHandler.php +4 -4
- src/lib/src/Modules/Autoupdates/Options.php +133 -0
- src/lib/src/Modules/Base/AdminNotices.php +9 -9
- src/lib/src/Modules/Base/BaseModCon.php +10 -45
- src/lib/src/Modules/Base/BaseProcessor.php +0 -28
- src/lib/src/Modules/Base/Options.php +1 -1
- src/lib/src/Modules/Base/Strings.php +1 -1
- src/lib/src/Modules/CommentsFilter/AjaxHandler.php +42 -0
- src/lib/src/Modules/CommentsFilter/Scan/Human.php +1 -1
- src/lib/src/Modules/CommentsFilter/Token/Create.php +45 -0
- src/lib/src/Modules/Events/AjaxHandler.php +34 -27
- src/lib/src/Modules/Events/Charts/BuildData.php +130 -0
- src/lib/src/Modules/Events/Charts/ChartRequestVO.php +20 -0
- src/lib/src/Modules/Events/Consolidate/ConsolidateAllEvents.php +291 -0
- src/lib/src/Modules/HackGuard/Options.php +2 -2
- src/lib/src/Modules/HackGuard/Strings.php +1 -1
- src/lib/src/Modules/IPs/AjaxHandler.php +3 -1
- src/lib/src/Modules/IPs/Components/LookupIpOnList.php +105 -0
- src/lib/src/Modules/IPs/Options.php +1 -2
- src/lib/src/Modules/Plugin/AdminNotices.php +35 -1
- src/lib/src/Modules/Plugin/AjaxHandler.php +20 -3
- src/lib/src/Modules/Plugin/Components/BadgeWidget.php +15 -1
- src/lib/src/Modules/Plugin/Components/PluginBadge.php +1 -1
- src/lib/src/Modules/Plugin/Components/SiteGroundPluginCompatibility.php +69 -0
- src/lib/src/Modules/Plugin/Strings.php +1 -1
- src/lib/src/Modules/PluginControllerConsumer.php +8 -2
- src/lib/src/Modules/SecurityAdmin/Options.php +1 -1
- src/lib/src/Scans/Mal/FileScanner.php +30 -57
- src/lib/src/Scans/Mal/Scan.php +0 -12
- src/lib/src/Scans/Mal/ScanActionVO.php +0 -2
- src/lib/src/Scans/Mal/Utilities/FalsePositiveQuery.php +81 -0
- src/lib/src/Scans/Mal/Utilities/Signatures.php +1 -0
- src/lib/src/Scans/Mal/Utilities/Whitelist.php +1 -0
- src/lib/src/Scans/Ptg/Scan.php +0 -1
- src/lib/src/Tables/Build/ScanMal.php +1 -1
- src/lib/src/Tables/Build/Traffic.php +1 -1
- src/lib/src/Tables/Render/Base.php +3 -2
- src/lib/src/Utilities/VisitorIpDetection.php +0 -187
- src/lib/vendor/composer/autoload_classmap.php +10 -27
- src/lib/vendor/composer/autoload_static.php +10 -27
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Plugins.php +27 -58
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Themes.php +29 -59
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkin.php +12 -18
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkinLegacy.php +38 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php +7 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php +7 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/DataManipulation.php +8 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/Compare/CompareHash.php +32 -12
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/ExtractLinesFromFile.php +1 -3
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php +42 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ClassicPress.php +1 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/PluginThemeBase.php +1 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/WordPress.php +1 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Base.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/RequestVO.php +1 -0
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Retrieve.php +19 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php +29 -12
- src/lib/vendor/symfony/polyfill-mbstring/Mbstring.php +13 -2
- src/processors/adminaccess_whitelabel.php +1 -1
- src/processors/audit_trail.php +1 -1
- src/processors/autoupdates.php +55 -52
- src/processors/base.php +0 -265
- src/processors/base_plugin.php +0 -10
- src/processors/base_wpsf.php +0 -198
- src/processors/basedb.php +0 -103
- src/processors/comments_filter.php +1 -1
- src/processors/commentsfilter_botspam.php +81 -44
- src/processors/events.php +6 -0
- src/processors/firewall.php +1 -1
- src/processors/hackprotect_scan_base.php +0 -7
- src/processors/hackprotect_scan_mal.php +2 -2
- src/processors/hackprotect_scan_ufc.php +1 -1
- src/processors/hackprotect_scan_wcf.php +2 -2
- src/processors/hackprotect_scanner.php +0 -7
- src/processors/ips.php +8 -1
- src/processors/lockdown.php +1 -1
- src/processors/loginprotect_intentprovider_email.php +2 -2
- src/processors/loginprotect_intentprovider_ga.php +1 -1
- src/processors/loginprotect_intentprovider_yubikey.php +1 -1
- src/processors/loginprotect_wplogin.php +7 -3
- src/processors/plugin_tracking.php +3 -3
- src/processors/sessions.php +0 -17
- src/processors/traffic_logger.php +3 -3
- src/processors/usermanagement_passwords.php +14 -27
- src/query/base/statistics_base.php +0 -252
- src/query/statistics/reporting.php +0 -11
- src/wizards/base.php +3 -3
- src/wizards/base_wpsf.php +4 -2
- src/wizards/login_protect.php +2 -2
- src/wizards/plugin.php +4 -4
- templates/php/snippets/module-help-admin_access_restriction.php +2 -2
- templates/php/snippets/module-help-firewall.php +1 -1
- templates/php/snippets/module-help-headers.php +1 -1
- templates/php/snippets/module-help-login_protect.php +1 -1
- templates/php/snippets/module-help-plugin.php +1 -1
- templates/php/snippets/pro.php +0 -310
- templates/twig/features/feature-base.twig +1 -1
- templates/twig/notices/compat-sgoptimize.twig +25 -0
- templates/twig/notices/rate-plugin.twig +1 -1
- templates/twig/snippets/comment_form_botbox.twig +1 -82
- templates/twig/wizard/slides/welcome/optin.twig +1 -1
- templates/twig/wpadmin_pages/base.twig +3 -0
- templates/twig/wpadmin_pages/insights/base.twig +3 -0
- templates/twig/wpadmin_pages/insights/insights/stats.twig +0 -14
- templates/twig/wpadmin_pages/insights/license/license.twig +6 -9
- templates/twig/wpadmin_pages/insights/original/audit_trail.twig +0 -34
- templates/twig/wpadmin_pages/insights/original/index.twig +0 -202
- templates/twig/wpadmin_pages/insights/original/mod_summary.twig +0 -21
- templates/twig/wpadmin_pages/insights/original/notices.twig +0 -58
- templates/twig/wpadmin_pages/insights/original/recent_events.twig +0 -18
- templates/twig/wpadmin_pages/insights/original/stats.twig +0 -20
- templates/twig/wpadmin_pages/insights/original/title.twig +0 -23
- templates/twig/wpadmin_pages/insights/{insights → overview}/index.twig +52 -7
- templates/twig/wpadmin_pages/insights/{insights → overview}/notices.twig +0 -0
- templates/twig/wpadmin_pages/insights/{insights → overview}/recent_events.twig +0 -0
- templates/twig/wpadmin_pages/insights/overview/stats.twig +19 -0
- templates/twig/wpadmin_pages/insights/reports/index.twig +2 -4
- unsupported.php +1 -1
changelog.html
CHANGED
@@ -1,675 +1,699 @@
|
|
1 |
-
|
2 |
-
<
|
3 |
-
<
|
4 |
-
<
|
5 |
-
<li><strong>(v.
|
6 |
-
<li><strong>(v.
|
7 |
-
<li><strong>(v.
|
8 |
-
<li><strong>(v.0)</strong>
|
9 |
-
<li><strong>(v.0)</strong>
|
10 |
-
|
11 |
-
<
|
12 |
-
<
|
13 |
-
<
|
14 |
-
<li><strong>(v.
|
15 |
-
</
|
16 |
-
<
|
17 |
-
<
|
18 |
-
<
|
19 |
-
<li><strong>(v.
|
20 |
-
<li><strong>(v.
|
21 |
-
<li><strong>(v.
|
22 |
-
<li><strong>(v.
|
23 |
-
<li><strong>(v.
|
24 |
-
<li><strong>(v.
|
25 |
-
<li><strong>(v.
|
26 |
-
<li><strong>(v.
|
27 |
-
<li><strong>(v.
|
28 |
-
<li><strong>(v.
|
29 |
-
<li><strong>(v.
|
30 |
-
<li><strong>(v.
|
31 |
-
<li><strong>(v.
|
32 |
-
<li><strong>(v.
|
33 |
-
<li><strong>(v.
|
34 |
-
<li><strong>(v.
|
35 |
-
<li><strong>(v.0)</strong>
|
36 |
-
<li><strong>(v.0)</strong>
|
37 |
-
<li><strong>(v.0)</strong>
|
38 |
-
<li><strong>(v.0)</strong>
|
39 |
-
<li><strong>(v.0)</strong>
|
40 |
-
</
|
41 |
-
<
|
42 |
-
<
|
43 |
-
|
44 |
-
<
|
45 |
-
<
|
46 |
-
<
|
47 |
-
<li><strong>(v.
|
48 |
-
<li><strong>(v.
|
49 |
-
<li><strong>(v.
|
50 |
-
<li><strong>(v.
|
51 |
-
<li><strong>(v.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
<li><strong>(v.5)</strong> Release skipped.</li>
|
53 |
-
<li><strong>(v.4)</strong> FIXED:
|
54 |
-
<li><strong>(v.3)</strong> ADDED:
|
55 |
-
<li><strong>(v.3)</strong> ADDED:
|
56 |
-
<li><strong>(v.3)</strong> FIXED:
|
57 |
-
<li><strong>(v.3)</strong> IMPROVED:
|
58 |
-
<li><strong>(v.3)</strong> IMPROVED:
|
59 |
-
<li><strong>(v.3)</strong> ADDED:
|
60 |
-
<li><strong>(v.2)</strong> IMPROVED:
|
61 |
-
<li><strong>(v.2)</strong> IMPROVED:
|
62 |
-
<li><strong>(v.2)</strong> IMPROVED:
|
63 |
-
<li><strong>(v.2)</strong> IMPROVED:
|
64 |
-
<li><strong>(v.2)</strong> IMPROVED:
|
65 |
-
<li><strong>(v.1)</strong> FIXED:
|
66 |
-
<li><strong>(v.0)</strong> NEW:
|
67 |
-
<li><strong>(v.0)</strong> NEW:
|
68 |
-
<li><strong>(v.0)</strong> ADDED:
|
69 |
-
<li><strong>(v.0)</strong> ADDED:
|
70 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
71 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
72 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
73 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
74 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
75 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
76 |
-
<li><strong>(v.0)</strong> FIXED:
|
77 |
-
<li><strong>(v.0)</strong> ADDED:
|
78 |
-
</ul>
|
79 |
-
<p>= 6.9.0 - Series
|
80 |
-
<em>Released: 6th September, 2018</em> - <a href="https://
|
81 |
-
<ul>
|
82 |
-
<li><strong>(v.0)</strong> NEW:
|
83 |
-
<li><strong>(v.0)</strong> NEW:
|
84 |
-
<li><strong>(v.0)</strong> ADDED:
|
85 |
-
<li><strong>(v.0)</strong> ADDED:
|
86 |
-
<li><strong>(v.0)</strong> ADDED:
|
87 |
-
<li><strong>(v.0)</strong> CHANGED:
|
88 |
-
<li><strong>(v.0)</strong> CHANGED:
|
89 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
90 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
91 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
92 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
93 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
94 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
95 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
96 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
97 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
98 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
99 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
100 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
101 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
102 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
103 |
-
<li><strong>(v.0)</strong> UPDATED:
|
104 |
-
<li><strong>(v.0)</strong> FIXED:
|
105 |
-
<li><strong>(v.0)</strong> FIXED:
|
106 |
-
</ul>
|
107 |
-
<p>= 6.8 Series
|
108 |
-
<em>Released: 11th June, 2018</em> - <a href="https://
|
109 |
-
<ul>
|
110 |
-
<li><strong>(v.2)</strong> FIXED:
|
111 |
-
<li><strong>(v.2)</strong> FIXED:
|
112 |
-
<li><strong>(v.2)</strong> FIXED:
|
113 |
-
<li><strong>(v.2)</strong> FIXED:
|
114 |
-
<li><strong>(v.1)</strong> FIXED:
|
115 |
-
<li><strong>(v.1)</strong> FIXED:
|
116 |
-
<li><strong>(v.0)</strong> ADDED:
|
117 |
-
<li><strong>(v.0)</strong> ADDED:
|
118 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
119 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
120 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
121 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
122 |
-
</ul>
|
123 |
-
<p>= 6.7 Series
|
124 |
-
<em>Released: 21st May, 2018</em> - <a href="https://
|
125 |
-
<ul>
|
126 |
-
<li><strong>(v.2)</strong> ADDED:
|
127 |
-
<li><strong>(v.2)</strong> UPDATED:
|
128 |
-
<li><strong>(v.2)</strong> FIXED:
|
129 |
-
<li><strong>(v.2)</strong> FIXED:
|
130 |
-
<li><strong>(v.1)</strong> FIXED:
|
131 |
-
<li><strong>(v.1)</strong> ADDED:
|
132 |
-
<li><strong>(v.0)</strong> ADDED:
|
133 |
-
<li><strong>(v.0)</strong> ADDED:
|
134 |
-
<li><strong>(v.0)</strong> ADDED:
|
135 |
-
<li><strong>(v.0)</strong> ADDED:
|
136 |
-
<li><strong>(v.0)</strong> ADDED:
|
137 |
-
<li><strong>(v.0)</strong> CHANGED:
|
138 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
139 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
140 |
-
</ul>
|
141 |
-
<p>= 6.6 Series
|
142 |
-
<em>Released: 19th March, 2018</em> - <a href="https://
|
143 |
-
<ul>
|
144 |
-
<li><strong>(v.7)</strong> IMPROVED:
|
145 |
-
<li><strong>(v.7)</strong> IMPROVED:
|
146 |
-
<li><strong>(v.7)</strong> IMPROVED:
|
147 |
-
<li><strong>(v.6)</strong> ADDED:
|
148 |
-
<li><strong>(v.6)</strong> ADDED:
|
149 |
-
<li><strong>(v.6)</strong> ADDED:
|
150 |
-
<li><strong>(v.1-4)</strong> FIXED:
|
151 |
-
<li><strong>(v.4)</strong> FIXED:
|
152 |
-
<li><strong>(v.0)</strong> NEW:
|
153 |
-
<li><strong>(v.0)</strong> ADDED:
|
154 |
-
<li><strong>(v.0)</strong> ADDED:
|
155 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
156 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
157 |
-
<li><strong>(v.0)</strong> FIXED:
|
158 |
-
</ul>
|
159 |
-
<p>= 6.5 Series
|
160 |
-
<em>Released: 5th March, 2018</em> - <a href="https://
|
161 |
-
<ul>
|
162 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
163 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
164 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
165 |
-
<li><strong>(v.0)</strong> ADDED:
|
166 |
-
<li><strong>(v.0)</strong> FIXED:
|
167 |
-
<li><strong>(v.0)</strong> FIXED:
|
168 |
-
</ul>
|
169 |
-
<p>= 6.4 Series
|
170 |
-
<em>Released: 26th February, 2018</em> - <a href="https://
|
171 |
-
<ul>
|
172 |
-
<li><strong>(v.1-4)</strong> FIXED:
|
173 |
-
<li><strong>(v.0)</strong> ADDED:
|
174 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
175 |
-
<li><strong>(v.0)</strong> CHANGED:
|
176 |
-
</ul>
|
177 |
-
<p>= 6.3 Series
|
178 |
-
<em>Released: 12th February, 2018</em> - <a href="https://
|
179 |
-
<ul>
|
180 |
-
<li><strong>(v.3)</strong> FIXED:
|
181 |
-
<li><strong>(v.2)</strong> CHANGED:
|
182 |
-
<li><strong>(v.1)</strong> FIXED:
|
183 |
-
<li><strong>(v.0)</strong> ADDED:
|
184 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
185 |
-
<li><strong>(v.0)</strong> FIXED:
|
186 |
-
</ul>
|
187 |
-
<p>= 6.2 Series
|
188 |
-
<em>Released: 31st January, 2018</em> - <a href="https://
|
189 |
-
<ul>
|
190 |
-
<li><strong>(v.2)</strong> FIXED:
|
191 |
-
<li><strong>(v.2)</strong> IMPROVED:
|
192 |
-
<li><strong>(v.1)</strong> FIXED:
|
193 |
-
<li><strong>(v.1)</strong> IMPROVED:
|
194 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
195 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
196 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
197 |
-
<li><strong>(v.0)</strong> ADDED:
|
198 |
-
<li><strong>(v.0)</strong> ADDED:
|
199 |
-
</ul>
|
200 |
-
<p>= 6.1 Series
|
201 |
-
<em>Released: 15th January, 2018</em> - <a href="https://
|
202 |
-
<ul>
|
203 |
-
<li><strong>(v.1)</strong> FIXED:
|
204 |
-
<li><strong>(v.0)</strong> ADDED:
|
205 |
-
<li><strong>(v.0)</strong> ADDED:
|
206 |
-
<li><strong>(v.0)</strong> CHANGED:
|
207 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
208 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
209 |
-
</ul>
|
210 |
-
<p>= 6.0 Series
|
211 |
<em>Released: 18th December, 2017</em></p>
|
212 |
<ul>
|
213 |
-
<li><strong>(v.0)</strong> ADDED:
|
214 |
-
<li><strong>(v.0)</strong> ADDED:
|
215 |
-
<li><strong>(v.0)</strong> ADDED:
|
216 |
-
<li><strong>(v.0)</strong> CHANGED:
|
217 |
</ul>
|
218 |
-
<p>= 5.20 Series
|
219 |
<em>Released: 11th December, 2017</em></p>
|
220 |
<ul>
|
221 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
222 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
223 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
224 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
225 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
226 |
-
<li><strong>(v.0)</strong> IMPROVED:
|
227 |
</ul>
|
228 |
-
<p>= 5.19 Series
|
229 |
<em>Released: 4th December, 2017</em></p>
|
230 |
<ul>
|
231 |
-
<li><strong>(v.1)</strong> FIXED:
|
232 |
-
<li><strong>(v.0)</strong> ADDED:
|
233 |
-
<li><strong>(v.0)</strong> ADDED:
|
234 |
-
<li><strong>(v.0)</strong> ADDED:
|
235 |
-
<li><strong>(v.0)</strong> ADDED:
|
236 |
</ul>
|
237 |
-
<p>= 5.18 Series
|
238 |
<em>Released: 27th November, 2017</em></p>
|
239 |
<ul>
|
240 |
-
<li><strong>(v.0)</strong> ADDED:
|
241 |
-
<li><strong>(v.0)</strong> ADDED:
|
242 |
-
<li><strong>(v.0)</strong> IMPROVEMENT:
|
243 |
</ul>
|
244 |
-
<p>= 5.17 Series
|
245 |
<em>Released: 23rd November, 2017</em></p>
|
246 |
<ul>
|
247 |
-
<li><strong>(v.0)</strong> ADDED:
|
248 |
-
<li><strong>(v.0)</strong> IMPROVEMENT:
|
249 |
-
<li><strong>(v.0)</strong> ADDED:
|
250 |
-
<li><strong>(v.0)</strong> ADDED:
|
251 |
-
<li><strong>(v.0)</strong> ADDED:
|
252 |
</ul>
|
253 |
-
<p>= 5.16 Series
|
254 |
<em>Released: 16th October, 2017</em></p>
|
255 |
<p>With this release, we fixed a clash of options for Google reCAPTCHA. Every attempt was made to ensure no interruption to your existing settings, but please check to ensure your reCAPTCHA settings are as you expect them to be.</p>
|
256 |
<ul>
|
257 |
-
<li><strong>(v.4)</strong> FIX:
|
258 |
-
<li><strong>(v.3)</strong> IMPROVEMENT:
|
259 |
-
<li><strong>(v.3)</strong> IMPROVEMENT:
|
260 |
-
<li><strong>(v.2)</strong> FIX:
|
261 |
-
<li><strong>(v.1)</strong> FIX:
|
262 |
-
<li><strong>(v.0)</strong> IMPROVEMENT:
|
263 |
-
<li><strong>(v.0)</strong> FIX:
|
264 |
-
<li><strong>(v.0)</strong> IMPROVEMENT:
|
265 |
-
<li><strong>(v.0)</strong> FIX:
|
266 |
-
</ul>
|
267 |
-
<p>= 5.15 Series
|
268 |
<em>Released: 21st September, 2017</em></p>
|
269 |
<ul>
|
270 |
-
<li><strong>(v.1)</strong> FIX:
|
271 |
-
<li><strong>(v.1)</strong> IMPROVEMENTS:
|
272 |
-
<li><strong>(v.1)</strong> IMPROVEMENTS:
|
273 |
-
<li><strong>(v.0)</strong> ADDED:
|
274 |
-
<li><strong>(v.0)</strong> ADDED:
|
275 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
276 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
277 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
278 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
279 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
280 |
-
</ul>
|
281 |
-
<p>= 5.14 Series
|
282 |
<em>Released: 9th September, 2017</em></p>
|
283 |
<ul>
|
284 |
-
<li><strong>(v.0)</strong> ADDED:
|
285 |
-
<li><strong>(v.0)</strong> UPDATED:
|
286 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
287 |
-
<li><strong>(v.0)</strong> FIX:
|
288 |
</ul>
|
289 |
-
<p>= 5.13 Series
|
290 |
<em>Released: 15th August, 2017</em></p>
|
291 |
<ul>
|
292 |
-
<li><strong>(v.2)</strong> IMPROVEMENTS:
|
293 |
-
<li><strong>(v.2)</strong> FIX:
|
294 |
-
<li><strong>(v.1)</strong> FIX:
|
295 |
-
<li><strong>(v.0)</strong> ADDED:
|
296 |
-
<li><strong>(v.0)</strong> ADDED:
|
297 |
</ul>
|
298 |
-
<p>= 5.12 Series
|
299 |
<em>Released: 3rd August, 2017</em></p>
|
300 |
<ul>
|
301 |
-
<li><strong>(v.2)</strong> IMPROVEMENTS:
|
302 |
-
<li><strong>(v.2)</strong> CHANGED:
|
303 |
-
<li><strong>(v.2)</strong> FIX:
|
304 |
-
<li><strong>(v.1)</strong> ADDED:
|
305 |
-
<li><strong>(v.1)</strong> FIX:
|
306 |
-
<li><strong>(v.0)</strong> ADDED:
|
307 |
-
|
308 |
-
<li><strong>(v.0)</strong> ADDED:
|
309 |
</ul>
|
310 |
-
<p>= 5.11 Series
|
311 |
<em>Released: 26th July, 2017</em></p>
|
312 |
<ul>
|
313 |
-
<li><strong>(v.1)</strong> FIX:
|
314 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
315 |
</ul>
|
316 |
-
<p>= 5.10 Series
|
317 |
<em>Released: 19th June, 2017</em></p>
|
318 |
<ul>
|
319 |
-
<li><strong>(v.2)</strong> FIXED:
|
320 |
-
<li><strong>(v.2)</strong> FIXED:
|
321 |
-
<li><strong>(v.1)</strong> IMPROVEMENTS:
|
322 |
-
<li><strong>(v.0)</strong> ADDED:
|
323 |
-
|
324 |
</ul>
|
325 |
-
<p>= 5.9 Series
|
326 |
<em>Released: 31st May, 2017</em></p>
|
327 |
<ul>
|
328 |
-
<li><strong>(v.0)</strong> ADDED:
|
329 |
-
<li><strong>(v.0)</strong> ADDED:
|
330 |
<li><strong>(v.0)</strong> CHANGE: Configuration for automatic self-update for the Shield plugin has been removed.</li>
|
331 |
-
<li><strong>(v.0)</strong> CHANGE: No longer remove an existing user session when accessed from another IP address. Just redirect.<
|
332 |
-
|
333 |
-
<li><strong>(v.0)</strong> FIXED:
|
334 |
</ul>
|
335 |
-
<p>= 5.8 Series
|
336 |
<em>Released: 7th April, 2017</em></p>
|
337 |
<ul>
|
338 |
-
<li><strong>(v.2)</strong> IMPROVEMENTS:
|
339 |
<li><strong>(v.2)</strong> CHANGE: Login Cooldown now uses only the flag file as an indicator of login times.</li>
|
340 |
<li><strong>(v.2)</strong> CHANGE: Filter to allow for changing the two factor timeout period, from 5 (minutes). Filter: <code>icwp-wpsf-login_intent_timeout</code></li>
|
341 |
<li><strong>(v.2)</strong> CHANGE: Changed timeout for two-factor authentication email to 5 minutes to account for slower email-sending providers.</li>
|
342 |
<li><strong>(v.2)</strong> CHANGE: Added further clarification to the Login Notification email indicating that two-factor authentication was pending.</li>
|
343 |
-
<li><strong>(v.1)</strong> FIXED:
|
344 |
-
<li><strong>(v.0)</strong> CHANGE: Major overhaul of <a href="https://
|
345 |
-
<li><strong>(v.0)</strong> CHANGE: <a href="https://
|
346 |
-
<li><strong>(v.0)</strong> ADDED:
|
347 |
-
<li><strong>(v.0)</strong> ADDED:
|
348 |
-
<li><strong>(v.0)</strong> ADDED:
|
349 |
<li><strong>(v.0)</strong> CHANGE: Yubikey login authentication is now managed directly from the User Profile screen, as with Google Authenticator.</li>
|
350 |
<li><strong>(v.0)</strong> CHANGE: Email-based login authentication no longer uses a separate database table.</li>
|
351 |
-
<li><strong>(v.0)</strong> FIXED:
|
352 |
-
<li><strong>(v.0)</strong> FIXED:
|
353 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
354 |
</ul>
|
355 |
<p>= 5.7 Series =</p>
|
356 |
<ul>
|
357 |
-
<li><strong>(v.3)</strong> FIXED:
|
358 |
-
<li><strong>(v.2)</strong> IMPROVEMENTS:
|
359 |
-
<li><strong>(v.2)</strong> IMPROVEMENTS:
|
360 |
<li><strong>(v.1)</strong> Skipped</li>
|
361 |
-
<li><strong>(v.0)</strong> ADDED:
|
362 |
<li><strong>(v.0)</strong> CHANGE: Enabled JS eval() for the Content Security Policy by default.</li>
|
363 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
364 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
365 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
366 |
-
<li><strong>(v.0)</strong> IMPROVEMENTS:
|
367 |
</ul>
|
368 |
<p>= 5.6 Series =</p>
|
369 |
<ul>
|
370 |
-
<li>
|
371 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
372 |
</li>
|
373 |
-
<li>
|
374 |
-
<p><strong>(v.1)</strong> CHANGE: Replaying of Yubikey one-time-passwords is no longer permitted.</p>
|
375 |
-
</li>
|
376 |
-
<li>
|
377 |
-
<p><strong>(v.1)</strong> ADDED: Filter for login form GASP fields.</p>
|
378 |
-
</li>
|
379 |
-
<li>
|
380 |
-
<p><strong>(v.1)</strong> ADDED: Filter for comment form GASP fields.</p>
|
381 |
-
</li>
|
382 |
-
<li>
|
383 |
-
<p><strong>(v.1)</strong> CHANGE: Improved compatibility of HTTP Headers with WP Super Cache.</p>
|
384 |
-
</li>
|
385 |
-
<li>
|
386 |
-
<p><strong>(v.0)</strong> ADDED: Option to disable anonymous Rest API access. WordPress v4.7+ only. Note that if another plugin<br>
|
387 |
-
or service authenticates the request it will be honoured, whether anonymous or not.<br>
|
388 |
-
= 5.5 Series =</p>
|
389 |
-
</li>
|
390 |
-
<li>
|
391 |
-
<p><strong>(v.6)</strong> IMPROVED: Fixed possible leak of the Login URL from the ‘Hide WP Login URL’ feature.</p>
|
392 |
-
</li>
|
393 |
-
<li>
|
394 |
-
<p><strong>(v.5)</strong> ADDED: Ability to add custom protocols to the domains (apart from http/s) to the Content Security Policy</p>
|
395 |
-
</li>
|
396 |
-
<li>
|
397 |
-
<p><strong>(v.5)</strong> FIXED: Bug where automatic update emails would contain empty plugins.</p>
|
398 |
-
</li>
|
399 |
-
<li>
|
400 |
-
<p><strong>(v.5)</strong> FIXED: Javascript scope on GASP form elements.</p>
|
401 |
-
</li>
|
402 |
-
<li>
|
403 |
-
<p><strong>(v.5)</strong> FIXED: Various fixes and code improvements.</p>
|
404 |
-
</li>
|
405 |
-
<li>
|
406 |
-
<p><strong>(v.4)</strong> FIXED: Bug with data cleaning/storage that caused stored options to balloon resulting in database timeouts. (only certain options affected)</p>
|
407 |
-
</li>
|
408 |
-
<li>
|
409 |
-
<p><strong>(v.4)</strong> IMPROVED: Sometimes “anti-virus” scanners scared normal, everyday hard-working folk by identifying a Shield file as being a virus, because they’re not very clever - reduced chances of this.</p>
|
410 |
-
</li>
|
411 |
-
<li>
|
412 |
-
<p><strong>(v.3)</strong> ADDED: Fix for WordPress Multisite where the correct database prefix wasn’t being used.</p>
|
413 |
-
</li>
|
414 |
-
<li>
|
415 |
-
<p><strong>(v.2)</strong> ADDED: Filter to allow modification of the email footer</p>
|
416 |
-
</li>
|
417 |
-
<li>
|
418 |
-
<p><strong>(v.2)</strong> ADDED: Block auto-updates on Shield itself if PHP < 5.3 and new version is v6.0+</p>
|
419 |
-
</li>
|
420 |
-
<li>
|
421 |
-
<p><strong>(v.2)</strong> FIXED: Missing Link</p>
|
422 |
-
</li>
|
423 |
-
<li>
|
424 |
-
<p><strong>(v.2)</strong> FIXED: Plugin Installation ID wasn’t always being set</p>
|
425 |
-
</li>
|
426 |
-
<li>
|
427 |
-
<p><strong>(v.2)</strong> TRANSLATIONS: Dutch (56%)</p>
|
428 |
-
</li>
|
429 |
-
<li>
|
430 |
-
<p><strong>(v.1)</strong> ADDED: Built-in forceful protection in the form of a wp_die() against the (currently) un-patched W3 Total Cache XSS vulnerability <a href="https://icwp.io/7j">more info</a></p>
|
431 |
-
</li>
|
432 |
-
<li>
|
433 |
-
<p><strong>(v.1)</strong> IMPROVED: Better XMLRPC Lockdown - prevents ANY XMLRPC command processing.</p>
|
434 |
-
</li>
|
435 |
-
<li>
|
436 |
-
<p><strong>(v.1)</strong> IMPROVED: Make certain strings translatable</p>
|
437 |
-
</li>
|
438 |
-
<li>
|
439 |
-
<p><strong>(v.1)</strong> IMPROVED: Wrap-up certain login form elements into spans/divs to allow styling etc.</p>
|
440 |
-
</li>
|
441 |
-
<li>
|
442 |
-
<p><strong>(v.1)</strong> IMPROVED: PHP Version number cleaning during stats tracking.</p>
|
443 |
-
</li>
|
444 |
-
<li>
|
445 |
-
<p><strong>(v.0)</strong> ADDED: Options and statistics tracking ability. Over time we are looking to share statistics and performance metrics of Shield.</p>
|
446 |
-
</li>
|
447 |
-
<li>
|
448 |
-
<p><strong>(v.0)</strong> IMPROVED: Performance for options loading, especially for web hosts that don’t permit file writing</p>
|
449 |
-
</li>
|
450 |
-
<li>
|
451 |
-
<p><strong>(v.0)</strong> CHANGED: Numerous fixes and code improvements.</p>
|
452 |
-
</li>
|
453 |
-
<li>
|
454 |
-
<p><strong>(v.0)</strong> CHANGED: Removed query that deletes old GASP comment tokens on normal page loads.</p>
|
455 |
-
</li>
|
456 |
-
<li>
|
457 |
-
<p><strong>(v.0)</strong> CHANGED: Google reCAPTCHA is now based on the locale of the website, not auto-detected.</p>
|
458 |
-
</li>
|
459 |
-
<li>
|
460 |
-
<p><strong>(v.0)</strong> FIXED: Now URL encodes the username in the link for two-factor authentication by email.</p>
|
461 |
-
</li>
|
462 |
-
<li>
|
463 |
-
<p><strong>(v.0)</strong> FIXED: If the xmlrpc.php has been deleted, this is now ignore by the file scanner</p>
|
464 |
-
</li>
|
465 |
-
<li>
|
466 |
-
<p><strong>(v.0)</strong> TRANSLATIONS: Dutch (38%), Portuguese (32%)</p>
|
467 |
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
468 |
</ul>
|
469 |
<p>= 5.4 Series =</p>
|
470 |
<ul>
|
471 |
-
<li><strong>(v.5)</strong> CHANGED:
|
472 |
-
<li><strong>(v.5)</strong> CHANGED:
|
473 |
-
<li><strong>(v.5)</strong> CHANGED:
|
474 |
-
<li><strong>(v.5)</strong> FIXED:
|
475 |
-
<li><strong>(v.5)</strong> FIXED:
|
476 |
<li><strong>(v.4)</strong> SKIPPED.</li>
|
477 |
-
<li><strong>(v.3)</strong> FIXED:
|
478 |
-
<li><strong>(v.3)</strong> CHANGED:
|
479 |
-
<li><strong>(v.3)</strong> REMOVED:
|
480 |
-
<li><strong>(v.3)</strong> TRANSLATIONS:
|
481 |
-
<li><strong>(v.3)</strong> FIXED:
|
482 |
-
<li><strong>(v.3)</strong> CHANGED:
|
483 |
-
<li><strong>(v.3)</strong> REMOVED:
|
484 |
-
<li><strong>(v.3)</strong> TRANSLATIONS:
|
485 |
-
<li><strong>(v.2)</strong> ADDED:
|
486 |
-
<li><strong>(v.2)</strong> ADDED:
|
487 |
-
<li><strong>(v.2)</strong> ADDED:
|
488 |
-
<li><strong>(v.2)</strong> CHANGED:
|
489 |
-
<li><strong>(v.1)</strong> FIXED:
|
490 |
-
<li><strong>(v.0)</strong> ADDED:
|
491 |
-
<li><strong>(v.0)</strong> ADDED:
|
492 |
-
<li><strong>(v.0)</strong> ADDED:
|
493 |
-
<li><strong>(v.0)</strong> REMOVED:
|
494 |
-
<li><strong>(v.0)</strong> CHANGED:
|
495 |
-
<li><strong>(v.0)</strong> CLEANED:
|
496 |
</ul>
|
497 |
<p>= 5.3 Series =</p>
|
498 |
<ul>
|
499 |
-
<li><strong>(v.2)</strong> IMPROVED:
|
500 |
-
<li><strong>(v.2)</strong> FIXED:
|
501 |
-
<li><strong>(v.2)</strong> FIXED:
|
502 |
-
<li><strong>(v.1)</strong> TRANSLATIONS:
|
503 |
-
<li><strong>(v.0)</strong> ADDED:
|
504 |
-
<li><strong>(v.0)</strong> FIXED:
|
505 |
</ul>
|
506 |
<p>= 5.2 Series =</p>
|
507 |
<ul>
|
508 |
-
<li><strong>(v.0)</strong> ADDED:
|
509 |
-
<li><strong>(v.0)</strong> CHANGED:
|
510 |
-
<li><strong>(v.0)</strong> FIXED:
|
511 |
-
<li><strong>(v.0)</strong> FIXED:
|
512 |
-
<li><strong>(v.0)</strong> REMOVED:
|
513 |
</ul>
|
514 |
<p>= 5.1 Series =</p>
|
515 |
<ul>
|
516 |
-
<li><strong>(v.0)</strong> FIXED:
|
517 |
-
<li><strong>(v.0)</strong> CHANGED:
|
518 |
-
<li><strong>(v.0)</strong> CHANGED:
|
519 |
-
<li><strong>(v.0)</strong> ADDED:
|
520 |
-
<li><strong>(v.0)</strong> FIXED:
|
521 |
</ul>
|
522 |
<p>= 5.0 Series =</p>
|
523 |
<ul>
|
524 |
-
<li><strong>(v.3)</strong> FIXED:
|
525 |
-
<li><strong>(v.2)</strong> FIXED:
|
526 |
-
<li><strong>(v.2)</strong> CHANGED:
|
527 |
-
<li><strong>(v.1)</strong> CHANGED:
|
528 |
-
<li><strong>(v.1)</strong> CHANGED:
|
529 |
-
<li><strong>(v.1)</strong> CHANGED:
|
530 |
-
<li><strong>(v.1)</strong> CHANGED:
|
531 |
-
<li><strong>(v.1)</strong> ADDED:
|
532 |
-
<li><strong>(v.0)</strong> NEW:
|
533 |
-
<li><strong>(v.0)</strong> ADDED:
|
534 |
-
<li><strong>(v.0)</strong> ADDED:
|
535 |
-
<li><strong>(v.0)</strong> CHANGED:
|
536 |
-
<li><strong>(v.0)</strong> CHANGED:
|
537 |
-
</ul>
|
538 |
-
<p>= 4.17 Series
|
539 |
<em>Released: 17th February, 2016</em></p>
|
540 |
<ul>
|
541 |
-
<li><strong>(v.0)</strong> ADDED:
|
542 |
-
<li><strong>(v.0)</strong> ADDED:
|
543 |
-
<li><strong>(v.0)</strong> ADDED:
|
544 |
-
<li><strong>(v.0)</strong> CHANGED:
|
545 |
-
<li><strong>(v.0)</strong> CHANGED:
|
546 |
-
<li><strong>(v.0)</strong> CHANGED:
|
547 |
-
<li><strong>(v.0)</strong> CHANGED:
|
548 |
</ul>
|
549 |
-
<p>= 4.16 Series
|
550 |
<em>Released: 20th January, 2016</em></p>
|
551 |
<ul>
|
552 |
-
<li><strong>(v.2)</strong> CHANGED:
|
553 |
-
<li><strong>(v.2)</strong> CHANGED:
|
554 |
-
<li><strong>(v.2)</strong> TRANSLATIONS:
|
555 |
-
<li><strong>(v.1)</strong> CHANGED:
|
556 |
-
<li><strong>(v.1)</strong> CHANGED:
|
557 |
-
<li><strong>(v.1)</strong> CHANGED:
|
558 |
-
<li><strong>(v.0)</strong> ADDED:
|
559 |
-
<li><strong>(v.0)</strong> ADDED:
|
560 |
-
<li><strong>(v.0)</strong> ADDED:
|
561 |
-
<li><strong>(v.0)</strong> ADDED:
|
562 |
-
</ul>
|
563 |
-
<p>= 4.15 Series
|
564 |
<em>Released: 6th January, 2016</em></p>
|
565 |
<ul>
|
566 |
-
<li><strong>(v.0)</strong> ADDED:
|
567 |
-
<li><strong>(v.0)</strong> CHANGED:
|
568 |
-
<li><strong>(v.0)</strong> FIXED:
|
569 |
-
<li><strong>(v.0)</strong> FIXED:
|
570 |
-
<li><strong>(v.0)</strong> TRANSLATIONS:
|
571 |
</ul>
|
572 |
-
<p>= 4.14 Series
|
573 |
<em>Released: 20th November, 2015</em></p>
|
574 |
<ul>
|
575 |
-
<li><strong>(v.2)</strong> ADDED:
|
576 |
-
<li><strong>(v.1)</strong> ADDED:
|
577 |
-
<li><strong>(v.1)</strong> ADDED:
|
578 |
-
<li><strong>(v.1)</strong> FIXED:
|
579 |
-
<li><strong>(v.0)</strong> ADDED:
|
580 |
-
<li><strong>(v.0)</strong> ADDED:
|
581 |
-
<li><strong>(v.0)</strong> CHANGED:
|
582 |
-
<li><strong>(v.0)</strong> CHANGED:
|
583 |
-
<li><strong>(v.0)</strong> TRANSLATIONS:
|
584 |
-
<li><strong>(v.0)</strong> FIXED:
|
585 |
-
</ul>
|
586 |
-
<p>= 4.13 Series
|
587 |
<em>Released: 22nd October, 2015</em></p>
|
588 |
<ul>
|
589 |
-
<li><strong>(v.0)</strong> NEW:
|
590 |
-
<li><strong>(v.0)</strong> NEW:
|
591 |
-
<li><strong>(v.0)</strong> CHANGED:
|
592 |
-
<li><strong>(v.0)</strong> CHANGED:
|
593 |
-
<li><strong>(v.0)</strong> CHANGED:
|
594 |
-
<li><strong>(v.0)</strong> CHANGED:
|
595 |
-
<li><strong>(v.0)</strong> CHANGED:
|
596 |
-
<li><strong>(v.0)</strong> CHANGED:
|
597 |
-
<li><strong>(v.0)</strong> CHANGED:
|
598 |
-
</ul>
|
599 |
-
<p>= 4.12 Series
|
600 |
<em>Released: 10th October, 2015</em></p>
|
601 |
<ul>
|
602 |
-
<li><strong>(v.0)</strong> NEW:
|
603 |
-
<li><strong>(v.0)</strong> CHANGED:
|
604 |
</ul>
|
605 |
-
<p>= 4.11 Series
|
606 |
<em>Released: 5th October, 2015</em></p>
|
607 |
<ul>
|
608 |
-
<li><strong>(v.0)</strong> NEW:
|
609 |
-
<li><strong>(v.0)</strong> FIXED:
|
610 |
-
<li><strong>(v.0)</strong> FIXED:
|
611 |
-
<li><strong>(v.0)</strong> TRANSLATIONS:
|
612 |
</ul>
|
613 |
-
<p>= 4.10 Series
|
614 |
<em>Released: 23rd August, 2015</em></p>
|
615 |
<ul>
|
616 |
-
<li>
|
617 |
-
<
|
618 |
-
</li>
|
619 |
-
<li>
|
620 |
-
<
|
621 |
-
|
622 |
-
<li>
|
623 |
-
<p><strong>(v.4)</strong> CHANGED: Revised the order of certain hooks being created to avoid the possibility of pluggable.php not being loaded for PHP Shutdown.</p>
|
624 |
-
</li>
|
625 |
-
<li>
|
626 |
-
<p><strong>(v.4)</strong> CHANGED: The presence of IP addresses in the IP Whitelist will force the IP Manager feature to be enabled.</p>
|
627 |
-
</li>
|
628 |
-
<li>
|
629 |
-
<p><strong>(v.4)</strong> CHANGED: We now make an attempt to prevent the caching of WordPress wp_die() pages that we generate. (compatible with at least W3TC, Super Cache)</p>
|
630 |
-
</li>
|
631 |
-
<li>
|
632 |
-
<p><strong>(v.4)</strong> TRANSLATIONS: Turkish - 100%, Danish - 3%</p>
|
633 |
-
</li>
|
634 |
-
<li>
|
635 |
-
<p><strong>(v.3)</strong> FIXED: Another PHP 5.2 incompatibility.</p>
|
636 |
-
</li>
|
637 |
-
<li>
|
638 |
-
<p><strong>(v.2)</strong> ADDED: White Listing UI to the IP Manager - CIDR ranges are supported (also automatically migrates IPs, except ranges, from legacy to new)</p>
|
639 |
-
</li>
|
640 |
-
<li>
|
641 |
-
<p><strong>(v.2)</strong> ADDED: Returned the black marking of failed WP login attempts to the automatic black list system</p>
|
642 |
</li>
|
643 |
-
<li>
|
644 |
-
<p><strong>(v.2)</strong> ADDED: Using a 3rd party API service: <a href="https://www.ipify.org/">ipify.org</a> - to find the server’s own IP address so we can ensure it’s not used in the black lists</p>
|
645 |
</li>
|
646 |
-
<li>
|
647 |
-
<
|
|
|
|
|
|
|
648 |
</li>
|
649 |
-
<li>
|
650 |
-
<p><strong>(v.2)</strong> FIXED: A few black list processing bugs.</p>
|
651 |
</li>
|
652 |
-
<li>
|
653 |
-
<
|
654 |
-
</li>
|
655 |
-
<li>
|
656 |
-
<
|
657 |
-
</
|
658 |
-
<
|
659 |
-
|
660 |
-
</li>
|
661 |
-
<li>
|
662 |
-
<p><strong>(v.1)</strong> CHANGED: Default transgressions limit is now 7</p>
|
663 |
-
</li>
|
664 |
-
<li>
|
665 |
-
<p><strong>(v.1)</strong> ADDED: Ability to reset plugin options to default using ‘reset’ flag file. <a href="https://icwp.io/wpsf28">more info</a></p>
|
666 |
-
</li>
|
667 |
-
<li>
|
668 |
-
<p><strong>(v.0)</strong> NEW FEATURE: ‘FABLE’ - <a href="https://icwp.io/wpsf27">Fully Automatic Black Listing Engine</a>.</p>
|
669 |
-
</li>
|
670 |
-
</ul>
|
671 |
-
<p>Simply put, FABLE will automatically block all malicious traffic by IP, based on their activity. This Security Plugin will track malicious behaviour<br>
|
672 |
-
and count all transgressions that visitors make against the site. Once a particular visitor exceeds the specified number transgressions, FABLE<br>
|
673 |
will outright block any access they have to your WordPress site.</p>
|
674 |
<p>What makes the FABLE system better?</p>
|
675 |
<ul>
|
@@ -685,24 +709,24 @@ will outright block any access they have to your WordPress site.</p>
|
|
685 |
<li>Attempt to login with an invalid username/password combination</li>
|
686 |
<li>Any attempt to login while the login cooldown system is in-effect</li>
|
687 |
<li>Any login attempt that trips the GASP Login protection system</li>
|
688 |
-
<li>Any login attempt with a username that doesn
|
689 |
<li>Any attempt to access /wp-admin/, /login/, or wp-login.php while the Rename WP Login setting is active</li>
|
690 |
<li>Any comment that gets labelled as SPAM by the plugin</li>
|
691 |
-
<li>Failed attempt to authenticate with the plugin
|
692 |
<li>Any trigger of a Firewall block rule</li>
|
693 |
</ul>
|
694 |
-
<p>= 4.9 Series
|
695 |
<em>Released: 7th July, 2015</em></p>
|
696 |
<ul>
|
697 |
<li><strong>(v.8)</strong> CHANGED: Firewall, User Sessions and Lockdown Feature Modules are now enabled by default for new installations.</li>
|
698 |
-
<li><strong>(v.8)</strong> FIX: Some server email programs can
|
699 |
-
<li><strong>(v.8)</strong> ADDED:
|
700 |
-
<li><strong>(v.8)</strong> CHANGED: Updated Text For <a href="https://
|
701 |
<li><strong>(v.7)</strong> CHANGED: How author query blocking works to be more reliable and stricter - only runs when users are not logged in, and it will DIE instead of redirect.</li>
|
702 |
<li><strong>(v.6)</strong> ADDED: New Option: prevent detection of usernames using the ?author=N query. (location under section: Lockdown -> Obscurity)</li>
|
703 |
-
<li><strong>(v.6)</strong> FIXED: Infinite redirect loop logic prevents redirect for rejected comment SPAM that
|
704 |
<li><strong>(v.5)</strong> ADDED: The plugin will load itself first before all other plugins</li>
|
705 |
-
<li><strong>(v.5)</strong> FIXED: No longer using parse_url() to determine the request URL as it
|
706 |
<li><strong>(v.4)</strong> FIX: Audit Trail Viewer display issue with non-escaped HTML (Thanks Chris!)</li>
|
707 |
<li><strong>(v.4)</strong> ADDED: An admin warning for sites with PHP version less than 5.3.2 (future versions will require this as a minimum)</li>
|
708 |
<li><strong>(v.4)</strong> TRANSLATIONS: Danish - 6%, Spanish - 76%</li>
|
@@ -712,9 +736,9 @@ will outright block any access they have to your WordPress site.</p>
|
|
712 |
<li><strong>(v.2)</strong> ADDED: Email notifications sent out to report email address on a daily cron. <a href="https://www.icontrolwp.com/2015/07/plugin-vulnerability-email-notifications/">more info</a></li>
|
713 |
<li><strong>(v.2)</strong> FIX: Work around a WordPress inline plugin update Javascript bug.</li>
|
714 |
<li><strong>(v.1)</strong> FIX: Fix syntax support for earlier versions of PHP.</li>
|
715 |
-
<li><strong>(v.0)</strong> FEATURE: Plugin Vulnerabilities Detection: If you
|
716 |
</ul>
|
717 |
-
<p>= 4.8 Series
|
718 |
<em>Released: 21st June, 2015</em></p>
|
719 |
<ul>
|
720 |
<li><strong>(v.0)</strong> FEATURE: Admin Access Restriction Areas - Restrict access to certain WordPress areas and functionality to <strong>Administrators</strong> with the Admin Access key.</li>
|
@@ -722,15 +746,15 @@ will outright block any access they have to your WordPress site.</p>
|
|
722 |
<li><strong>(v.0)</strong> ADDED: Admin Access Restriction Area - Themes. You can now restrict access to certain Theme actions - activate, install, update, delete.</li>
|
723 |
<li><strong>(v.0)</strong> ADDED: Admin Access Restriction Area - Pages/Post. You can now restrict access to certain Page/Post actions - Create/Edit, Publish, Delete.</li>
|
724 |
</ul>
|
725 |
-
<p>= 4.7 Series
|
726 |
<em>Released: 29th April, 2015</em></p>
|
727 |
<ul>
|
728 |
<li><strong>(v.7)</strong> FIXED: The text used to explain why some comments were marked as spam was broken.</li>
|
729 |
<li><strong>(v.7)</strong> FIXED: Group sign-up form now honours your SSL setting.</li>
|
730 |
<li><strong>(v.7)</strong> TRANSLATIONS: Spanish - 74%, Russian - 91%, Turkish - 94%, Polish- 95%, Finnish - 100%</li>
|
731 |
-
<li><strong>(v.6)</strong> FIXED: Verifying ability to send/receive email doesn
|
732 |
-
<li><strong>(v.6)</strong> FIXED: GASP Login Protection feature breaks because certain key options aren
|
733 |
-
<li><strong>(v.6)</strong> FIXED: Some
|
734 |
<li><strong>(v.4)</strong> ADDED: Email Sending Verification when enabling two-factor authentication - this ensures your site can send (and you can receive) emails.</li>
|
735 |
<li><strong>(v.4)</strong> ADDED: Section Summaries - each option tab contains a small text summary outlining the purpose and recommendation for each.</li>
|
736 |
<li><strong>(v.4)</strong> CHANGED: The Admin Access Key input is now a password field.</li>
|
@@ -745,16 +769,16 @@ will outright block any access they have to your WordPress site.</p>
|
|
745 |
<li><strong>(v.1)</strong> FIX: Silence warnings from filesystem touch() command.</li>
|
746 |
<li><strong>(v.1)</strong> TRANSLATIONS: Polish (100%), Finnish (100%), Czech (73%), Arabic (34%)</li>
|
747 |
<li><strong>(v.0)</strong> UPDATED: Options page user interface re-design.</li>
|
748 |
-
<li><strong>(v.0)</strong> FIX: Audit trail time now reflects the user
|
749 |
<li><strong>(v.0)</strong> FIX: Better compatibility with BBPress.</li>
|
750 |
<li><strong>(v.0)</strong> UPDATED: Underlying plugin code improvements.</li>
|
751 |
<li><strong>(v.0)</strong> TRANSLATIONS: Russian (100%), Czech (70%), Polish (97%)</li>
|
752 |
</ul>
|
753 |
-
<p>= 4.6 Series
|
754 |
<em>Released: 10th April, 2015</em></p>
|
755 |
<ul>
|
756 |
-
<li><strong>(v.3)</strong> SECURITY: Added protection against XSS vulnerability in WordPress comments. <a href="https://
|
757 |
-
<li><strong>(v.3)</strong> SECURITY: Added extra precautions to WordPress URL redirects. <a href="https://
|
758 |
<li><strong>(v.3)</strong> TRANSLATIONS: Russian (70%), Czech (67%)</li>
|
759 |
<li><strong>(v.2)</strong> FIX: Bug with the database table verification logic.</li>
|
760 |
<li><strong>(v.2)</strong> TRANSLATIONS: Russian (New- 54%), Romanian (100%), Turkish (89%), Czech (53%)</li>
|
@@ -762,10 +786,10 @@ will outright block any access they have to your WordPress site.</p>
|
|
762 |
<li><strong>(v.1)</strong> UPDATED: Plugin Badge styling</li>
|
763 |
<li><strong>(v.1)</strong> UPDATED: Updated Czech(41%) and Spanish (60%) translations</li>
|
764 |
<li><strong>(v.0)</strong> ADDED: New feature that displays the last login time for all users on the users listing page (User Management feature must be enabled).</li>
|
765 |
-
<li><strong>(v.0)</strong> ADDED: <strong>Completely optional</strong> promotional Plugin Badge option - help us promote the plugin and reassure your site visitors at the same time. <a href="https://
|
766 |
<li><strong>(v.0)</strong> UPDATED: Updated Czech(38%) translations</li>
|
767 |
</ul>
|
768 |
-
<p>= 4.5 Series
|
769 |
<em>Released: 6th March, 2015</em></p>
|
770 |
<ul>
|
771 |
<li><strong>(v.5)</strong> CHANGED: Updated Finnish (100%), Czech (16%) translations</li>
|
@@ -779,47 +803,47 @@ will outright block any access they have to your WordPress site.</p>
|
|
779 |
<li><strong>(v.1)</strong> ADDED: New feature- GASP Login Protection can now be applied to lost password form - enabled by default</li>
|
780 |
<li><strong>(v.0)</strong> ADDED: New feature- GASP Login Protection can now be applied to user registrations - enabled by default</li>
|
781 |
</ul>
|
782 |
-
<p>= 4.4 Series
|
783 |
<em>Released: 21st February, 2015</em></p>
|
784 |
<ul>
|
785 |
<li><strong>(v.2)</strong> ADDED: Romanian Translation.</li>
|
786 |
<li><strong>(v.2)</strong> ADDED: A plugin minimum-requirements processing system.</li>
|
787 |
<li><strong>(v.2)</strong> IMPROVED: The WordPress admin-UI code is simpler and cleaner.</li>
|
788 |
<li><strong>(v.1)</strong> ADDED: <strong>Significant</strong> performance enhancement in plugin loading times (up to 50% reduction).</li>
|
789 |
-
<li><strong>(v.0)</strong> CHANGED: The
|
790 |
-
<li><strong>(v.0)</strong> CHANGED: More lax in finding the
|
791 |
<li><strong>(v.0)</strong> CHANGED: Parsing the URL no longer outputs warnings that might interfere with response headers.</li>
|
792 |
</ul>
|
793 |
-
<p>= 4.3 Series
|
794 |
<em>Released: 15th January, 2015</em></p>
|
795 |
<ul>
|
796 |
<li><strong>(v.6)</strong> FIXES: More thorough validation of whitelisted IP addresses</li>
|
797 |
<li><strong>(v.5)</strong> FIXES: Some hosting environments need absolute file paths for PHP include()/require()</li>
|
798 |
<li><strong>(v.5)</strong> CHANGED: Streamlined the detection of whitelisting and added in-plugin notification if <strong>you</strong> are whitelisted</li>
|
799 |
-
<li><strong>(v.4)</strong> FIXES: Work around for cases where PHP can
|
800 |
<li><strong>(v.2)</strong> IMPROVED: Refactoring for better code organisation</li>
|
801 |
-
<li>ADDED: New Feature - <a href="https://
|
802 |
<li>ADDED: UI indicators on whether plugins will be automatically updated in the plugins listing.</li>
|
803 |
-
<li>CHANGED: IP Address WhiteList is now global for the whole plugin, and can be accessed under the
|
804 |
<li>IMPROVED: Firewall processing code is simplified and more efficient.</li>
|
805 |
</ul>
|
806 |
-
<p>= 4.2.1
|
807 |
<em>Released: 22th December, 2014</em></p>
|
808 |
<ul>
|
809 |
<li>FIXED: Changes to how feature specifications are read from disk to prevent .tmp file build up.</li>
|
810 |
</ul>
|
811 |
-
<p>= 4.2.0
|
812 |
<em>Released: 12th December, 2014</em></p>
|
813 |
<ul>
|
814 |
<li>ADDED: Audit Trail Auto Cleaning - default cleans out entries older than 30 days.</li>
|
815 |
<li>FIXED: Various small bug fixes and code cleaning.</li>
|
816 |
</ul>
|
817 |
-
<p>= 4.1.4
|
818 |
<em>Released: 24th November, 2014</em></p>
|
819 |
<ul>
|
820 |
<li>FIXED: Fixed small logic bug which prevented deactivation of the plugin on the UI.</li>
|
821 |
</ul>
|
822 |
-
<p>= 4.1.3
|
823 |
<em>Released: 19th November, 2014</em></p>
|
824 |
<ul>
|
825 |
<li>IMPROVED: User Sessions are simplified.</li>
|
@@ -827,25 +851,25 @@ will outright block any access they have to your WordPress site.</p>
|
|
827 |
</ul>
|
828 |
<p>= 4.1.2 =</p>
|
829 |
<ul>
|
830 |
-
<li>ADDED: Self-correcting database table validation - if the structure of a database table isn
|
831 |
</ul>
|
832 |
<p>= 4.1.1 =</p>
|
833 |
<ul>
|
834 |
<li>WARNING: Due to new IPv6 support, all databases tables will be rebuilt - all active user sessions will be destroyed.</li>
|
835 |
-
<li>ADDED: Preliminary support for IPv6 addresses throughout. We don
|
836 |
-
<li>ADDED: New audit trail concept added called
|
837 |
<li>FIXED: Support for audit trail events with longer names.</li>
|
838 |
<li>IMPROVED: Comments Filtering - It now honours the WordPress settings for previously approved comment authors and never filters such comments.</li>
|
839 |
<li>REMOVED: Option to enable GASP Comments Filtering for logged-in users has been completely removed - this reduces plugin options complexity. All logged-in users by-pass <strong>all</strong> comments filtering.</li>
|
840 |
<li>FIXED: Prevention against plugin redirect loops under certain conditions.</li>
|
841 |
-
<li>FIXED: IP whitelisting wasn
|
842 |
</ul>
|
843 |
<p>= 4.0.0 =</p>
|
844 |
<ul>
|
845 |
<li>ADDED: New Feature - Audit Trail</li>
|
846 |
<li>ADDED: Audit Trail options include: Plugins, Themes, Email, WordPress Core, Posts/Pages, Shield plugin</li>
|
847 |
<li>FIXED: Full and proper cleanup of plugin options, crons, and databases upon deactivation.</li>
|
848 |
-
<li>REMOVED: Firewall Log. This is no longer an option and is instead integrated into the
|
849 |
</ul>
|
850 |
<p>= 3.5.5 =</p>
|
851 |
<ul>
|
@@ -855,18 +879,18 @@ will outright block any access they have to your WordPress site.</p>
|
|
855 |
</ul>
|
856 |
<p>= 3.5.3 =</p>
|
857 |
<ul>
|
858 |
-
<li>ADDED: A warning message on the WordPress admin if the
|
859 |
-
<li>CHANGED: The
|
860 |
-
<li>CHANGED: The
|
861 |
-
<li>FIXED: Problems with certain hosting environments reading in files with the
|
862 |
-
<li>FIXED: Small issue where when the file system paths change, some variables don
|
863 |
</ul>
|
864 |
<p>= 3.5.0 =</p>
|
865 |
<ul>
|
866 |
<li>CHANGED: Plugin features are now configured <a href="https://github.com/mustangostang/spyc/">using YAML</a> - no more in-PHP configuration.</li>
|
867 |
<li>REMOVED: A few options from User Sessions Management as they were unnecessary.</li>
|
868 |
<li>CHANGED: Database storing tables now have consistent naming.</li>
|
869 |
-
<li>FIXED: Issue with User Sessions Management where
|
870 |
<li>FIXED: Firewall log gathering.</li>
|
871 |
<li>FIXED: Various PHP warning notices.</li>
|
872 |
</ul>
|
@@ -886,10 +910,10 @@ will outright block any access they have to your WordPress site.</p>
|
|
886 |
<p>= 3.2.0 =</p>
|
887 |
<ul>
|
888 |
<li>ADDED: Options to allow by-pass XML-RPC so as to be compatible with WordPress iPhone/Android apps.</li>
|
889 |
-
<li>UPDATED: Login screen message when you
|
890 |
<li>CHANGED: Tweaked method for setting admin access protection on/off</li>
|
891 |
<li>CHANGED: comment filtering code refactoring.</li>
|
892 |
-
<li>FIXED: Options that were
|
893 |
</ul>
|
894 |
<p>= 3.1.5 =</p>
|
895 |
<ul>
|
@@ -914,7 +938,7 @@ will outright block any access they have to your WordPress site.</p>
|
|
914 |
<p>= 3.1.0 =</p>
|
915 |
<ul>
|
916 |
<li>ADDED: option to check the logged-in user session only on WordPress admin pages (now the default setting)</li>
|
917 |
-
<li>ADDED: option to auto-forward to the WordPress dashboard when you go to wp-login.php and you
|
918 |
<li>ADDED: message to login screen when no user session is found</li>
|
919 |
<li>CHANGED: does not verify session when performing AJAX request. (need to build appropriate AJAX response)</li>
|
920 |
<li>FIX: for wp_login action not passing second argument</li>
|
@@ -949,33 +973,33 @@ will outright block any access they have to your WordPress site.</p>
|
|
949 |
<p>= 2.6.4 =</p>
|
950 |
<ul>
|
951 |
<li>ENHANCED: Dashboard now shows a more visual summary of settings and removes duplicate options settings with links to sections.</li>
|
952 |
-
<li>ENHANCED: WordPress Lock Down options now also set the corresponding WordPress defines if they
|
953 |
</ul>
|
954 |
<p>= 2.6.3 =</p>
|
955 |
<ul>
|
956 |
<li>ADDED: More in-line plugin links to help/blog resources</li>
|
957 |
-
<li>ENHANCED: <a href="https://
|
958 |
-
</
|
959 |
-
<
|
960 |
-
|
961 |
<li>Blocks plugin options updating right at the point of WordPress options update so nothing can rewrite the actual plugin options.</li>
|
962 |
<li>Locks the current Admin Access session to your IP address - effectively only 1 Shield admin allowed at a time.</li>
|
963 |
-
</
|
964 |
<p>= 2.6.2 =</p>
|
965 |
<ul>
|
966 |
-
<li>ENHANCED: Added option to completely reject a SPAM comment and redirect to the home page (so it doesn
|
967 |
<li>ADDED: Plugin now has an internal stats counter for spam and other significant plugin events.</li>
|
968 |
</ul>
|
969 |
<p>= 2.6.1 =</p>
|
970 |
<ul>
|
971 |
<li>ADDED: Plugin now installs with default SPAM blacklist.</li>
|
972 |
-
<li>ADDED: Now automatically checks and updates the SPAM blacklist when it
|
973 |
<li>ENHANCED: Comment messages indicate where the SPAM content was found when marking human-based spam messages.</li>
|
974 |
</ul>
|
975 |
<p>= 2.6.0 =</p>
|
976 |
<p><strong>Major Features Release: Please review SPAM comments filtering options to determine where SPAM goes</strong></p>
|
977 |
<ul>
|
978 |
-
<li>FEATURE: Added Human SPAM comments filtering - replacement for Akismet that doesn
|
979 |
<li>ENHANCED: Two-Factor Login now automatically logs in the user to the admin area without them having to re-login again.</li>
|
980 |
<li>ENHANCED: Added ability to terminate all currently (two-factor) verified logins.</li>
|
981 |
<li>ENHANCED: Spam filter/scanning adds an explanation to the SPAM content to show why a message was filtered.</li>
|
@@ -988,7 +1012,7 @@ will outright block any access they have to your WordPress site.</p>
|
|
988 |
</ul>
|
989 |
<p>= 2.5.8 =</p>
|
990 |
<ul>
|
991 |
-
<li>FEATURE: Added
|
992 |
</ul>
|
993 |
<p>= 2.5.7 =</p>
|
994 |
<ul>
|
@@ -1000,9 +1024,9 @@ will outright block any access they have to your WordPress site.</p>
|
|
1000 |
</ul>
|
1001 |
<p>= 2.5.5 =</p>
|
1002 |
<ul>
|
1003 |
-
<li>FEATURE: Added
|
1004 |
-
<li>FEATURE: Added
|
1005 |
-
<li>FIX: Admin restricted access feature wasn
|
1006 |
</ul>
|
1007 |
<p>= 2.5.4 =</p>
|
1008 |
<ul>
|
@@ -1023,7 +1047,7 @@ will outright block any access they have to your WordPress site.</p>
|
|
1023 |
</ul>
|
1024 |
<p>= 2.5.0 =</p>
|
1025 |
<ul>
|
1026 |
-
<li>FEATURE: Two-Factor Authenticated Login using <a href="https://
|
1027 |
</ul>
|
1028 |
<p>= 2.4.3 =</p>
|
1029 |
<ul>
|
@@ -1032,7 +1056,7 @@ will outright block any access they have to your WordPress site.</p>
|
|
1032 |
</ul>
|
1033 |
<p>= 2.4.2 =</p>
|
1034 |
<ul>
|
1035 |
-
<li>ADDED: Contextual help links for many options. More to come
|
1036 |
<li>ADDED: More Portuguese (Brazil) translations (~80%)</li>
|
1037 |
</ul>
|
1038 |
<p>= 2.4.1 =</p>
|
@@ -1040,7 +1064,7 @@ will outright block any access they have to your WordPress site.</p>
|
|
1040 |
<li>ADDED: More strings to the translation set for better multilingual support</li>
|
1041 |
<li>ADDED: Portuguese (Brazil) translations (~40%)</li>
|
1042 |
<li>UPDATED: Hebrew Translations</li>
|
1043 |
-
<li>FIXED: Automatic cleaning of database logs wasn
|
1044 |
</ul>
|
1045 |
<p>= 2.4.0 =</p>
|
1046 |
<ul>
|
@@ -1055,23 +1079,23 @@ will outright block any access they have to your WordPress site.</p>
|
|
1055 |
<ul>
|
1056 |
<li>ADDED: Hebrew Translations. Thanks <a href="http://atar4u.com">Ahrale</a>!</li>
|
1057 |
<li>ADDED: Automatic trimming of the Firewall access log to 7 days - it just grows too large otherwise.</li>
|
1058 |
-
<li>FIX: The previously added automatic clean up of old comments and login protect database entries was wiping out the valid login protect<
|
1059 |
-
|
1060 |
<li>FIX: Some small bugs, errors, and PHPDoc Comments.</li>
|
1061 |
</ul>
|
1062 |
<p>= 2.3.2 =</p>
|
1063 |
<ul>
|
1064 |
-
<li>ADDED:
|
1065 |
<li>CHANGED: Huge code refactoring to allow for more easily use with other WordPress plugins.</li>
|
1066 |
</ul>
|
1067 |
<p>= 2.2.5 =</p>
|
1068 |
<ul>
|
1069 |
-
<li>ADDED:
|
1070 |
</ul>
|
1071 |
<p>= 2.2.4 =</p>
|
1072 |
<ul>
|
1073 |
<li>FIX: Small bug fix.</li>
|
1074 |
-
<li>CHANGED: When running a force automatic updates process, tries to remove influence from other plugins and uses only this plugin
|
1075 |
<li>CHANGED: A bit of automatic updates code refactoring.</li>
|
1076 |
</ul>
|
1077 |
<p>= 2.2.2 =</p>
|
@@ -1081,7 +1105,7 @@ entries and was forcing users to re-login every 24hrs.</li>
|
|
1081 |
</ul>
|
1082 |
<p>= 2.2.1 =</p>
|
1083 |
<ul>
|
1084 |
-
<li>ADDED:
|
1085 |
</ul>
|
1086 |
<p>= 2.2.0 =</p>
|
1087 |
<ul>
|
@@ -1091,8 +1115,8 @@ entries and was forcing users to re-login every 24hrs.</li>
|
|
1091 |
</ul>
|
1092 |
<p>= 2.1.5 =</p>
|
1093 |
<ul>
|
1094 |
-
<li>IMPROVED:
|
1095 |
-
<li>CHANGED: The whitelisting rule for posting pages/posts is only for the
|
1096 |
</ul>
|
1097 |
<p>= 2.1.4 =</p>
|
1098 |
<ul>
|
@@ -1102,17 +1126,17 @@ entries and was forcing users to re-login every 24hrs.</li>
|
|
1102 |
<ul>
|
1103 |
<li>FIX: A bug that prevented auto-updates of this plugin.</li>
|
1104 |
<li>FIX: Not being able to hide translations and upgrade notices.</li>
|
1105 |
-
<li>ADDED:
|
1106 |
</ul>
|
1107 |
<p>= 2.1.0 =</p>
|
1108 |
<ul>
|
1109 |
-
<li>ADDED:
|
1110 |
<li>CHANGED: The plugin now sets more options to be turned on by default when the plugin is first activated.</li>
|
1111 |
<li>CHANGED: A lot of optimizations and code refactoring.</li>
|
1112 |
</ul>
|
1113 |
<p>= 2.0.3 =</p>
|
1114 |
<ul>
|
1115 |
-
<li>FIX: Whoops, sorry, accidentally removed the option to toggle
|
1116 |
</ul>
|
1117 |
<p>= 2.0.2 =</p>
|
1118 |
<ul>
|
@@ -1120,8 +1144,8 @@ entries and was forcing users to re-login every 24hrs.</li>
|
|
1120 |
</ul>
|
1121 |
<p>= 2.0.1 =</p>
|
1122 |
<ul>
|
1123 |
-
<li>ADDED:
|
1124 |
-
<li>ADDED:
|
1125 |
</ul>
|
1126 |
<p>= 1.9.2 =</p>
|
1127 |
<ul>
|
@@ -1129,23 +1153,23 @@ entries and was forcing users to re-login every 24hrs.</li>
|
|
1129 |
</ul>
|
1130 |
<p>= 1.9.1 =</p>
|
1131 |
<ul>
|
1132 |
-
<li>ADDED:
|
1133 |
-
<li>ADDED:
|
1134 |
</ul>
|
1135 |
<p>= 1.9.0 =</p>
|
1136 |
<ul>
|
1137 |
-
<li>ADDED:
|
1138 |
</ul>
|
1139 |
<p>= 1.8.2 =</p>
|
1140 |
<ul>
|
1141 |
-
<li>ADDED:
|
1142 |
-
<li>CHANGED: Certain admin and upgrade notices now only appear when you
|
1143 |
-
<li>FIXED:
|
1144 |
</ul>
|
1145 |
<p>= 1.8.1 =</p>
|
1146 |
<ul>
|
1147 |
-
<li>ADDED:
|
1148 |
-
<li>ADDED:
|
1149 |
</ul>
|
1150 |
<p>= 1.7.3 =</p>
|
1151 |
<ul>
|
@@ -1154,13 +1178,13 @@ entries and was forcing users to re-login every 24hrs.</li>
|
|
1154 |
</ul>
|
1155 |
<p>= 1.7.1 =</p>
|
1156 |
<ul>
|
1157 |
-
<li>ADDED:
|
1158 |
</ul>
|
1159 |
<p>= 1.7.0 =</p>
|
1160 |
<ul>
|
1161 |
-
<li>ADDED:
|
1162 |
-
<li>CHANGED: The Firewall now kicks in on the
|
1163 |
-
|
1164 |
</ul>
|
1165 |
<p>= 1.6.2 =</p>
|
1166 |
<ul>
|
@@ -1168,78 +1192,78 @@ of WP Multisite support).</li>
|
|
1168 |
</ul>
|
1169 |
<p>= 1.6.1 =</p>
|
1170 |
<ul>
|
1171 |
-
<li>ADDED:
|
1172 |
-
<li>ADDED:
|
1173 |
</ul>
|
1174 |
<p>= 1.6.0 =</p>
|
1175 |
<ul>
|
1176 |
-
<li>ADDED:
|
1177 |
-
<li>ADDED:
|
1178 |
</ul>
|
1179 |
<p>= 1.5.6 =</p>
|
1180 |
<ul>
|
1181 |
-
<li>IMPROVED:
|
1182 |
-
<li>IMPROVED:
|
1183 |
-
<li>FIXED:
|
1184 |
</ul>
|
1185 |
<p>= 1.5.5 =</p>
|
1186 |
<ul>
|
1187 |
-
<li>FIXED:
|
1188 |
</ul>
|
1189 |
<p>= 1.5.4 =</p>
|
1190 |
<ul>
|
1191 |
-
<li>FIXED:
|
1192 |
</ul>
|
1193 |
<p>= 1.5.3 =</p>
|
1194 |
<ul>
|
1195 |
-
<li>FIXED:
|
1196 |
</ul>
|
1197 |
<p>= 1.5.2 =</p>
|
1198 |
<ul>
|
1199 |
<li>CHANGED: The method for finding the client IP address is more thorough, in a bid to work with Proxy servers etc.</li>
|
1200 |
-
<li>FIXED:
|
1201 |
</ul>
|
1202 |
<p>= 1.5.1 =</p>
|
1203 |
<ul>
|
1204 |
-
<li>FIXED:
|
1205 |
-
<li>FIXED:
|
1206 |
</ul>
|
1207 |
<p>= 1.5.0 =</p>
|
1208 |
<ul>
|
1209 |
-
<li>ADDED:
|
1210 |
<li>REMOVED: Firewall rule for wp-login.php and whitelisted IPs.</li>
|
1211 |
</ul>
|
1212 |
<p>= 1.4.2 =</p>
|
1213 |
<ul>
|
1214 |
-
<li>ADDED:
|
1215 |
</ul>
|
1216 |
<p>= 1.4.1 =</p>
|
1217 |
<ul>
|
1218 |
-
<li>ADDED:
|
1219 |
-
<li>ADDED:
|
1220 |
-
<li>ADDED:
|
1221 |
-
<li>FIXED:
|
1222 |
</ul>
|
1223 |
<p>= 1.4.0 =</p>
|
1224 |
<ul>
|
1225 |
-
<li>ADDED:
|
1226 |
<li>CHANGED: Huge improvements on database calls and efficiency in loading plugin options.</li>
|
1227 |
-
<li>FIXED:
|
1228 |
</ul>
|
1229 |
<p>= 1.3.2 =</p>
|
1230 |
<ul>
|
1231 |
-
<li>FIXED:
|
1232 |
</ul>
|
1233 |
<p>= 1.3.0 =</p>
|
1234 |
<ul>
|
1235 |
-
<li>ADDED:
|
1236 |
-
<li>ADDED:
|
1237 |
-
<li>ADDED:
|
1238 |
-
<li>ADDED:
|
1239 |
-
<li>ADDED:
|
1240 |
-
|
1241 |
<li>CHANGED: Login Protect checking now better logs out users immediately with a redirect.</li>
|
1242 |
-
<li>CHANGED: We now escape the log data being printed - just in case there
|
1243 |
<li>CHANGED: Optimized and cleaned a lot of the option caching code to improve reliability and performance (more to come).</li>
|
1244 |
</ul>
|
1245 |
<p>= 1.2.7 =</p>
|
@@ -1248,13 +1272,13 @@ of WP Multisite support).</li>
|
|
1248 |
</ul>
|
1249 |
<p>= 1.2.6 =</p>
|
1250 |
<ul>
|
1251 |
-
<li>ADDED:
|
1252 |
<li>FIX: A reported bug - parameter values could also be arrays.</li>
|
1253 |
</ul>
|
1254 |
<p>= 1.2.5 =</p>
|
1255 |
<ul>
|
1256 |
-
<li>ADDED:
|
1257 |
-
<li>ADDED:
|
1258 |
<li>FIX: A few bugfixes and logic corrections.</li>
|
1259 |
</ul>
|
1260 |
<p>= 1.2.4 =</p>
|
@@ -1272,23 +1296,23 @@ of WP Multisite support).</li>
|
|
1272 |
</ul>
|
1273 |
<p>= 1.2.1 =</p>
|
1274 |
<ul>
|
1275 |
-
<li>ADDED:
|
1276 |
-
|
1277 |
<li>CHANGED: Optimized some settings for performance.</li>
|
1278 |
<li>CHANGED: Cleaned up the UI when the Firewall / Login Protect features are disabled (more to come).</li>
|
1279 |
<li>CHANGED: Further code improvements (more to come).</li>
|
1280 |
</ul>
|
1281 |
<p>= 1.2.0 =</p>
|
1282 |
<ul>
|
1283 |
-
<li>ADDED:
|
1284 |
<li>CHANGED: The method for processing the IP address lists is improved.</li>
|
1285 |
<li>CHANGED: Improved .htaccess rules (thanks MickeyRoush)</li>
|
1286 |
<li>CHANGED: Mailing method now uses WP_MAIL</li>
|
1287 |
-
<li>CHANGED: Lot
|
1288 |
</ul>
|
1289 |
<p>= 1.1.6 =</p>
|
1290 |
<ul>
|
1291 |
-
<li>ADDED:
|
1292 |
</ul>
|
1293 |
<p>= 1.1.5 =</p>
|
1294 |
<ul>
|
@@ -1311,13 +1335,13 @@ which WordPress will wait before processing any more login attempts on a site.</
|
|
1311 |
</ul>
|
1312 |
<p>= 1.1.1 =</p>
|
1313 |
<ul>
|
1314 |
-
<li>Fix: Block notification emails weren
|
1315 |
</ul>
|
1316 |
<p>= 1.1.0 =</p>
|
1317 |
<ul>
|
1318 |
-
<li>You can now specify IP ranges in whitelists and blacklists. To do this separate the start and end address with a hyphen (-)
|
1319 |
<li>You can now specify which email address to send the notification emails.</li>
|
1320 |
-
<li>You can now add a comment to IP addresses in the whitelist/blacklist. To do this, write your IP address then type a SPACE and write whatever you want (don
|
1321 |
<li>You can now set to delete ALL firewall settings when you deactivate the plugin.</li>
|
1322 |
<li>Improved formatting of the firewall log.</li>
|
1323 |
</ul>
|
@@ -1329,12 +1353,10 @@ which WordPress will wait before processing any more login attempts on a site.</
|
|
1329 |
<p>= 1.1.2 =</p>
|
1330 |
<ul>
|
1331 |
<li>CHANGED: Logging now has its own dedicated database table.</li>
|
1332 |
-
<li>Fix: Block notification emails weren
|
1333 |
-
<li>You can now specify IP ranges in whitelists and blacklists. To do this separate the start and end address with a hyphen (-)
|
1334 |
<li>You can now specify which email address to send the notification emails.</li>
|
1335 |
-
<li>You can now add a comment to IP addresses in the whitelist/blacklist. To do this, write your IP address then type a SPACE and write whatever you want (don
|
1336 |
<li>You can now set to delete ALL firewall settings when you deactivate the plugin.</li>
|
1337 |
<li>Improved formatting of the firewall log.</li>
|
1338 |
-
</ul>
|
1339 |
-
|
1340 |
-
</body></html>
|
1 |
+
<p>= 8.3 - Series =
|
2 |
+
<em>Released: 18th November, 2019</em> - <a href="https://shsec.io/g3">Release Notes</a></p>
|
3 |
+
<ul>
|
4 |
+
<li><strong>(v.0)</strong> IMPROVED: Improvements to Malware scanner to <a href="https://shsec.io/g3">now track malware results</a> by specific lines, not just by file.</li>
|
5 |
+
<li><strong>(v.0)</strong> IMPROVED: Support colons (:) in IP addresses during visitor IP address detection.</li>
|
6 |
+
<li><strong>(v.0)</strong> IMPROVED: Ensure license lookups use the correct site URL.</li>
|
7 |
+
<li><strong>(v.0)</strong> IMPROVED: Attempt to ensure that if there is an interruption in the API, malware patterns are available for scanning.</li>
|
8 |
+
<li><strong>(v.0)</strong> IMPROVED: Added default firewall whitelist parameter for AffiliateWP requests.</li>
|
9 |
+
<li><strong>(v.0)</strong> IMPROVED: Spanish, French, Japanese translations.</li>
|
10 |
+
</ul>
|
11 |
+
<p>= 8.2 - Series =
|
12 |
+
<em>Released: 1st October, 2019</em> - <a href="https://shsec.io/g0">Release Notes</a></p>
|
13 |
+
<ul>
|
14 |
+
<li><strong>(v.3)</strong> FIXED: Fix for reported RXSS vulnerability - <a href="https://shsec.io/g1">more info</a>.</li>
|
15 |
+
<li><strong>(v.3)</strong> FIXED: Fix for Rest API detection.</li>
|
16 |
+
<li><strong>(v.3)</strong> FIXED: Fix for translation of some strings.</li>
|
17 |
+
<li><strong>(v.2)</strong> FIXED: Fixes for scans running under Windows/IIS.</li>
|
18 |
+
<li><strong>(v.2)</strong> IMPROVED: Adds a check that a site can send an HTTP request to itself before allowing scans to run.</li>
|
19 |
+
<li><strong>(v.2)</strong> IMPROVED: Scans clean up after themselves better, if they fail to run.</li>
|
20 |
+
<li><strong>(v.2)</strong> IMPROVED: Server's own IP address detection when site migrated to a new host.</li>
|
21 |
+
<li><strong>(v.2)</strong> UPDATED: International translations.</li>
|
22 |
+
<li><strong>(v.2)</strong> FIXED: PHP notices when data wasn't as expected.</li>
|
23 |
+
<li><strong>(v.1)</strong> IMPROVED: Further reduce Malware false positives by also using SVN trunk data when verifying files for plugins and themes.</li>
|
24 |
+
<li><strong>(v.1)</strong> ADDED: Initial support for repairing Themes that have been installed from WordPress.org.</li>
|
25 |
+
<li><strong>(v.1)</strong> ADDED: Support for using <a href="https://wphashes.com">WP Hashes.com</a> for WordPress.org themes (already done for plugins).</li>
|
26 |
+
<li><strong>(v.1)</strong> FIXED: PHP notices in the logs.</li>
|
27 |
+
<li><strong>(v.0)</strong> IMPROVED: [<strong>PRO</strong>] Malware scanner now uses network intelligence to the gather information on malware results.</li>
|
28 |
+
<li><strong>(v.0)</strong> NEW: Traffic Watcher feature is now free for all users (no longer Pro-only).</li>
|
29 |
+
<li><strong>(v.0)</strong> IMPROVED: Scanning cron is improved and more efficient.</li>
|
30 |
+
<li><strong>(v.0)</strong> ADDED: Bulk Delete/Repair/Ignore actions now available for Malware scan results.</li>
|
31 |
+
<li><strong>(v.0)</strong> IMPROVED: Malware scan results now provide details of affected line numbers and patterns discovered.</li>
|
32 |
+
<li><strong>(v.0)</strong> IMPROVED: Malware scanner only scans <code>wp-admin</code>, <code>wp-includes</code>, <code>wp-content</code> folders, and files in top-level directory.</li>
|
33 |
+
<li><strong>(v.0)</strong> IMPROVED: Malware scanner now excludes <code>wp-content/cache/</code> directory.</li>
|
34 |
+
<li><strong>(v.0)</strong> IMPROVED: Malware scanner performance improved with caching.</li>
|
35 |
+
<li><strong>(v.0)</strong> IMPROVED: Malware auto-repair now works more consistently.</li>
|
36 |
+
<li><strong>(v.0)</strong> IMPROVED: Updated default firewall whitelist rules.</li>
|
37 |
+
<li><strong>(v.0)</strong> IMPROVED: If the PWNED Passwords API request fails entirely, the password check is skipped.</li>
|
38 |
+
<li><strong>(v.0)</strong> ADDED: Japanese translations are at 100%.</li>
|
39 |
+
<li><strong>(v.0)</strong> IMPROVED: Dutch translations are greatly improved (a huge thank you to Fred!).</li>
|
40 |
+
<li><strong>(v.0)</strong> FIXED: Audit Trail correctly logs multiple occurrences for the same type of event on the same page request.</li>
|
41 |
+
<li><strong>(v.0)</strong> FIXED: Audit Trail now correctly logs Google reCAPTCHA failure events.</li>
|
42 |
+
<li><strong>(v.0)</strong> FIXED: PHP error when firewall was set to kill response without a user message.</li>
|
43 |
+
</ul>
|
44 |
+
<p>= 8.1 - Series =
|
45 |
+
<em>Released: 18th September, 2019</em> - <a href="https://shsec.io/fy">Release Notes</a></p>
|
46 |
+
<ul>
|
47 |
+
<li><strong>(v.1)</strong> FIXED: Error for sites pre-5.0 that don't have function <code>determine_locale()</code></li>
|
48 |
+
<li><strong>(v.0)</strong> IMPROVED: Massive improvements to asynchronous scans in performance and reliability.</li>
|
49 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Possible to supply multiple email addresses for Administrator login notifications.</li>
|
50 |
+
<li><strong>(v.0)</strong> ADDED: New firewall whitelist rule to prevent firewall blocks when activating certain plugins.</li>
|
51 |
+
<li><strong>(v.0)</strong> IMPROVED: Prevent errors caused by other plugins not passing correctly-formatted data through WP filters.</li>
|
52 |
+
<li><strong>(v.0)</strong> ADDED: Japanese translations (14%).</li>
|
53 |
+
<li><strong>(v.0)</strong> IMPROVED: Plugin locale now respects user profile locale setting.</li>
|
54 |
+
<li><strong>(v.0)</strong> IMPROVED: Audit Trail filter for specific events.</li>
|
55 |
+
<li><strong>(v.0)</strong> IMPROVED: Lots of cleanup of deprecated PHP code following the the v7-v8 upgrade.</li>
|
56 |
+
</ul>
|
57 |
+
<p>= 8.0 - Series =
|
58 |
+
<em>Released: 27th August, 2019</em> - <a href="https://shsec.io/fv">Release Notes</a></p>
|
59 |
+
<ul>
|
60 |
+
<li><strong>(v.2)</strong> IMPROVED: Password strength metering now better aligns with WordPress library (PHP 5.6+)</li>
|
61 |
+
<li><strong>(v.2)</strong> IMPROVED: Dutch translations have been adjusted.</li>
|
62 |
+
<li><strong>(v.2)</strong> FIXED: Setting 'Month' for IP block duration wasn't being applied.</li>
|
63 |
+
<li><strong>(v.2)</strong> FIXED: Certain admin notices not displayed when they should be.</li>
|
64 |
+
<li><strong>(v.1)</strong> FIXED: Comment SPAM blocking wasn't working if set to "Detect and Reject".</li>
|
65 |
+
<li><strong>(v.1)</strong> FIXED: Shield Widget/Badge broken in some cases.</li>
|
66 |
+
<li><strong>(v.1)</strong> ADDED: You can force Shield to operate in any <a href="https://shsec.io/gistshieldlocale">locale, regardless of site locale</a>.</li>
|
67 |
+
<li><strong>(v.1)</strong> ADDED: Russian translations are now at 100% and some Dutch translations have been adjusted.</li>
|
68 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] New Malware Scanner with automated file repair for WordPress.org Plugins and Core.</li>
|
69 |
+
<li><strong>(v.0)</strong> NEW: Complete overhaul of events system to better audit and collect statistics.</li>
|
70 |
+
<li><strong>(v.0)</strong> IMPROVED: Asynchronous scans - scans run in the background and so support more restrictive hosting.</li>
|
71 |
+
<li><strong>(v.0)</strong> IMPROVED: Plugin notification system is much improved.</li>
|
72 |
+
<li><strong>(v.0)</strong> IMPROVED: [<strong>PRO</strong>] Plugin Guard uses SVN repositories for file references <a href="https://shsec.io/fw">via WP Hashes API</a>.</li>
|
73 |
+
<li><strong>(v.0)</strong> CHANGED: Comment SPAM system now uses WordPress Transients API instead of dedicated DB table.</li>
|
74 |
+
<li><strong>(v.0)</strong> ADDED: 100% Translation coverage for French, Spanish, German, Portuguese, Serbian, Bosnian, Dutch. (Russian on the way)</li>
|
75 |
+
<li><strong>(v.0)</strong> CHANGED: Major code cleaning/refactoring for much of the plugin. More to come.</li>
|
76 |
+
</ul>
|
77 |
+
<p>= 7.4 - Series =
|
78 |
+
<em>Released: 13th May, 2019</em> - <a href="https://shsec.io/fc">Release Notes</a></p>
|
79 |
+
<ul>
|
80 |
+
<li><strong>(v.2)</strong> NEW: Options finder/jumper menu lets you find and jump to any option in the plugin instantly.</li>
|
81 |
+
<li><strong>(v.2)</strong> NEW: Help/explainer videos for a few sections - more to come.</li>
|
82 |
+
<li><strong>(v.2)</strong> FIXES: Fixes for a few problems introduced with the recent UI changes.</li>
|
83 |
+
<li><strong>(v.2)</strong> FIXED: Welcome wizard launching was broken.</li>
|
84 |
+
<li><strong>(v.1)</strong> NEW: Adjustments and redesign of Shield options pages.</li>
|
85 |
+
<li><strong>(v.1)</strong> IMPROVED: Further prep for better internationalization.</li>
|
86 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] <a href="https://shsec.io/fa">Manual/Automatic User Suspension</a></li>
|
87 |
+
<li><strong>(v.0)</strong> NEW: Comment SPAM - Increase minimum number of approved comments before scanning is skipped</li>
|
88 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] Comment SPAM - Trusted user roles where comments scanning is skipped</li>
|
89 |
+
<li><strong>(v.0)</strong> IMPROVED: AntiBot JS was improperly included when not required.</li>
|
90 |
+
<li><strong>(v.0)</strong> IMPROVED: Added a GeoIP caching table and removed bundled GeoIP database - greatly reduces download size.</li>
|
91 |
+
<li><strong>(v.0)</strong> FIXED: Inconsistent behaviour when PWA plugin is active and it infinitely reloads pages.</li>
|
92 |
+
<li><strong>(v.0)</strong> FIXED: Inconsistent behaviour with Anonymous API blocking.</li>
|
93 |
+
<li><strong>(v.0)</strong> IMPROVED: Code improvements and refactoring.</li>
|
94 |
+
<li><strong>(v.0)</strong> ADDED: Prep for upcoming malware scanner.</li>
|
95 |
+
</ul>
|
96 |
+
<p>= 7.3 - Series =
|
97 |
+
<em>Released: 15th April, 2019</em> - <a href="https://shsec.io/f0">Release Notes</a></p>
|
98 |
+
<ul>
|
99 |
+
<li><strong>(v.2)</strong> IMPROVED: Provided inline links for new <a href="https://shsec.io/ez">Bot Signals</a> options.</li>
|
100 |
+
<li><strong>(v.2)</strong> CHANGED: Added a workaround for WPML plugin using old, buggy version of TWIG library.</li>
|
101 |
+
<li><strong>(v.1)</strong> FIX: Protection against 404 tracking blocking visitors in some cases.</li>
|
102 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] <a href="https://shsec.io/ez">7x New Bot Signals</a> - rules to catch and block bad bots.</li>
|
103 |
+
<li><strong>(v.0)</strong> ADDED: Date picker for filtering Audit Log entries.</li>
|
104 |
+
<li><strong>(v.0)</strong> IMPROVED: Audit Log viewer now combines entries from the same request into 1 for better readability.</li>
|
105 |
+
<li><strong>(v.0)</strong> CHANGED: Use a more refined clearing of WP Fastest Cache.</li>
|
106 |
+
<li><strong>(v.0)</strong> FIX: Error displayed when deleting plugins in some cases.</li>
|
107 |
+
<li><strong>(v.0)</strong> UPDATED: Translations for Chinese, Finnish, Turkish, Dutch, Italian, and German.</li>
|
108 |
+
</ul>
|
109 |
+
<p>= 7.2 - Series =
|
110 |
+
<em>Released: 7th March, 2019</em> - <a href="https://shsec.io/ep">Release Notes</a></p>
|
111 |
+
<ul>
|
112 |
+
<li><strong>(v.2)</strong> SKIPPED: with error.</li>
|
113 |
+
<li><strong>(v.1)</strong> NEW: Provisional support for WP-CLI - no longer blocks Security Admin protected operations</li>
|
114 |
+
<li><strong>(v.1)</strong> FIX: Fix PHP warning notice on login page.</li>
|
115 |
+
<li><strong>(v.1)</strong> FIX: Unrecognised file scanning not operating as expected on Windows hosts.</li>
|
116 |
+
<li><strong>(v.0)</strong> NEW: <a href="https://shsec.io/eq">Scanner to detect and alert</a> to presence of abandoned plugins.</li>
|
117 |
+
<li><strong>(v.0)</strong> FIX: Fix bug with Security Admin passwords.</li>
|
118 |
+
<li><strong>(v.0)</strong> FIX: Fix bug with vulnerability scanner not correctly comparing versions.</li>
|
119 |
+
</ul>
|
120 |
+
<p>= 7.1 - Series =
|
121 |
+
<em>Released: 21st February, 2019</em> - <a href="https://shsec.io/ek">Release Notes</a></p>
|
122 |
+
<ul>
|
123 |
+
<li><strong>(v.2)</strong> IMPROVED: Firewall email notification content now better reflect the information in the audit trail.</li>
|
124 |
+
<li><strong>(v.2)</strong> FIX: Firewall email notification was breaking in some instances.</li>
|
125 |
+
<li><strong>(v.1)</strong> FIX: IP retrieval.</li>
|
126 |
+
<li><strong>(v.0)</strong> NEW: Moved Import/Export UI from Wizard to main Shield Dashboard.</li>
|
127 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] Option to import/export settings using file downloads/uploads</li>
|
128 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] Option to allow visitors to automatically unblock themselves (once in 24hrs)</li>
|
129 |
+
<li><strong>(v.0)</strong> NEW: Integrated changelog directly into plugin admin for easy updates (between releases)</li>
|
130 |
+
<li><strong>(v.0)</strong> FIXED: WP Core files scanner now correctly ignores certain files as it used to do, pre-v7. e.g. wp-config-sample.php</li>
|
131 |
+
<li><strong>(v.0)</strong> FIXED: Shield was indicating plugin/theme file editing was possible, when it in-fact was disabled.</li>
|
132 |
+
<li><strong>(v.0)</strong> IMPROVED: Consolidate crons into fewer crons. e.g. all scans run under the same cron.</li>
|
133 |
+
</ul>
|
134 |
+
<p>= 7.0 - Series =
|
135 |
+
<em>Released: 28th January, 2019</em> - <a href="https://shsec.io/ef">Release Notes</a></p>
|
136 |
+
<ul>
|
137 |
+
<li><strong>(v.4)</strong> IMPROVED: Refactored IP address blocking with improved audit trail messages.</li>
|
138 |
+
<li><strong>(v.4)</strong> CHANGED: Expanded anonymous REST API whitelist to include 'wpstatistics' namespace.</li>
|
139 |
+
<li><strong>(v.4)</strong> IMPROVED: Access protection for shield temp/caching dir.</li>
|
140 |
+
<li><strong>(v.4)</strong> IMPROVED: Clarification on reCAPTCHA - v3 is <strong>not</strong> supported.</li>
|
141 |
+
<li><strong>(v.4)</strong> IMPROVED: Clarification on user sessions timeout - Shield sets an absolutely session maximum.</li>
|
142 |
+
<li><strong>(v.4)</strong> IMPROVED: Options form submission is adjusted to work around poorly restrictive webhosts.</li>
|
143 |
+
<li><strong>(v.4)</strong> FIX: Various tweaks and fixes across the plugin.</li>
|
144 |
+
<li><strong>(v.4)</strong> FIX: Error with ClassicPress.</li>
|
145 |
+
<li><strong>(v.3)</strong> NEW: Automatically whitelist anonymous REST API Access for 3 plugins: Contact Form 7, WooCommerce, JetPack.</li>
|
146 |
+
<li><strong>(v.3)</strong> IMPROVED: Security admin login failure messages are clearer.</li>
|
147 |
+
<li><strong>(v.3)</strong> IMPROVED: Admin notification for email sending 2FA verification easily lets you resend email.</li>
|
148 |
+
<li><strong>(v.3)</strong> IMPROVED: File download code for WordPress Core file scanner repairs.</li>
|
149 |
+
<li><strong>(v.3)</strong> IMPROVED: Attempt to also capture B/CC email addresses included in outgoing emails in Audit logs.</li>
|
150 |
+
<li><strong>(v.3)</strong> FIX: Allow use of IPv4 ranges in whitelist again.</li>
|
151 |
+
<li><strong>(v.3)</strong> CHANGED: Numerous code refactoring and improvements building upon the major v7 release and prepping for v7.1.</li>
|
152 |
+
<li><strong>(v.1-2)</strong> FIXED: Some JS fixes.</li>
|
153 |
+
<li><strong>(v.0)</strong> NEW: New primary UI for Shield site security management. Easy access to scans, audit trail, user sessions etc.</li>
|
154 |
+
<li><strong>(v.0)</strong> NEW: Supports only PHP 5.4 or higher</li>
|
155 |
+
<li><strong>(v.0)</strong> NEW: Rebuilt scans architecture and UI</li>
|
156 |
+
<li><strong>(v.0)</strong> NEW: A huge amount of code cleaning and refactoring</li>
|
157 |
+
<li><strong>(v.0)</strong> CHANGED: Too many many changes and bug fixes to list -best to just take a look! :)</li>
|
158 |
+
</ul>
|
159 |
+
<p>= 6.10 - Series =
|
160 |
+
<em>Released: 15th October, 2018</em> - <a href="https://shsec.io/dg">Release Notes</a></p>
|
161 |
+
<ul>
|
162 |
+
<li><strong>(v.9)</strong> FIXED: Admin notices displaying to non-admins.</li>
|
163 |
+
<li><strong>(v.7)</strong> ADDED: [<strong>PRO</strong>] New option to specify usernames for Security Admin role.</li>
|
164 |
+
<li><strong>(v.7)</strong> IMPROVED: Idle user detection.</li>
|
165 |
+
<li><strong>(v.7)</strong> IMPROVED: Support for redirect/cancel URLs in 2FA login page.</li>
|
166 |
+
<li><strong>(v.7)</strong> CHANGED: Final release before Shield v7. Small warning shown on plugins page if PHP < 5.4</li>
|
167 |
+
<li><strong>(v.6)</strong> ADDED: New option to control plugin automatic updates.</li>
|
168 |
+
<li><strong>(v.6)</strong> IMPROVED: Enhancements to the experimental bot JS.</li>
|
169 |
+
<li><strong>(v.6)</strong> IMPROVED: Support for Easy Digital Downloads forms.</li>
|
170 |
<li><strong>(v.5)</strong> Release skipped.</li>
|
171 |
+
<li><strong>(v.4)</strong> FIXED: Couldn't deactivate plugin.</li>
|
172 |
+
<li><strong>(v.3)</strong> ADDED: Support for Ultimate Member forms</li>
|
173 |
+
<li><strong>(v.3)</strong> ADDED: Support for LearnPress login/registration forms</li>
|
174 |
+
<li><strong>(v.3)</strong> FIXED: Security Admin now correctly honours the WordPress Options zone setting.</li>
|
175 |
+
<li><strong>(v.3)</strong> IMPROVED: Distinguish which sub-site (sub-domain) for WPMS installations on <a href="https://shsec.io/c1">Traffic Watcher</a>.</li>
|
176 |
+
<li><strong>(v.3)</strong> IMPROVED: Server's own IP lookup is only attempted once.</li>
|
177 |
+
<li><strong>(v.3)</strong> ADDED: Experimental feature to help with some custom 3rd party login/registration forms</li>
|
178 |
+
<li><strong>(v.2)</strong> IMPROVED: Visitor IP address detection</li>
|
179 |
+
<li><strong>(v.2)</strong> IMPROVED: Automatic whitelisting of Manage WP IP addresses</li>
|
180 |
+
<li><strong>(v.2)</strong> IMPROVED: SPAM Comments code enhanced and optimised</li>
|
181 |
+
<li><strong>(v.2)</strong> IMPROVED: IP Whitelisting code enhanced and optimised</li>
|
182 |
+
<li><strong>(v.2)</strong> IMPROVED: Code cleaning and refactoring.</li>
|
183 |
+
<li><strong>(v.1)</strong> FIXED: Googlebot PHP error notice.</li>
|
184 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] 2FA Login Backup Codes - all users can create a backup login code in-case their MFA factors are temporarily unavailable.</li>
|
185 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] White Label - you can now specify custom image for 2FA login screen.</li>
|
186 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Custom Exclusion Rules for Traffic Watcher so you can exclude certain User Agents and request paths.</li>
|
187 |
+
<li><strong>(v.0)</strong> ADDED: Detection of official spiders/bots for Google, Bing, Apple and Yandex - these visitors will never get blacklisted.</li>
|
188 |
+
<li><strong>(v.0)</strong> IMPROVED: Two-Factor Authentication system much improved (+ critical bug fix).</li>
|
189 |
+
<li><strong>(v.0)</strong> IMPROVED: Audit Trail entries for 2FA login factors.</li>
|
190 |
+
<li><strong>(v.0)</strong> IMPROVED: Fixes for Two-Factor Authentication wizard UX.</li>
|
191 |
+
<li><strong>(v.0)</strong> IMPROVED: Traffic Watcher now honours the IP Whitelist.</li>
|
192 |
+
<li><strong>(v.0)</strong> IMPROVED: Security Admin restriction for creating/editing/deleting Administrator users is much improved.</li>
|
193 |
+
<li><strong>(v.0)</strong> IMPROVED: All Shield cookies are SSL-only by default for HTTPS sites.</li>
|
194 |
+
<li><strong>(v.0)</strong> FIXED: GASP checkbox Javascript breaking in a particular scenario.</li>
|
195 |
+
<li><strong>(v.0)</strong> ADDED: Optional plugin deactivation survey.</li>
|
196 |
+
</ul>
|
197 |
+
<p>= 6.9.0 - Series =
|
198 |
+
<em>Released: 6th September, 2018</em> - <a href="https://shsec.io/dc">Release Notes</a></p>
|
199 |
+
<ul>
|
200 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] <a href="https://shsec.io/c1">Traffic Watcher</a> - live tracking of all requests to your site.</li>
|
201 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] <a href="https://shsec.io/c1">Yubikey</a> - Allows for multiple Yubikeys on the same user profile.</li>
|
202 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Option to include listing of affected files within Hack Guard notification emails.</li>
|
203 |
+
<li><strong>(v.0)</strong> ADDED: Option to delete the Security Admin Access Key</li>
|
204 |
+
<li><strong>(v.0)</strong> ADDED: Option to add WooCommerce roles to 2FA-Email setting.</li>
|
205 |
+
<li><strong>(v.0)</strong> CHANGED: Basic Stats system now requires minimum PHP v5.4.</li>
|
206 |
+
<li><strong>(v.0)</strong> CHANGED: Password Policies now requires minimum WordPress v4.4.</li>
|
207 |
+
<li><strong>(v.0)</strong> IMPROVED: Password expiration now redirects to the 'set password' screen, instead of the user profile.</li>
|
208 |
+
<li><strong>(v.0)</strong> IMPROVED: Password capture for purposes of password policies is improved.</li>
|
209 |
+
<li><strong>(v.0)</strong> IMPROVED: You can now delete the 'forceoff' file from inside the WP Admin.</li>
|
210 |
+
<li><strong>(v.0)</strong> IMPROVED: Audit Trail entries for emails will identify the file that's calling the <code>wp_mail</code> function.</li>
|
211 |
+
<li><strong>(v.0)</strong> IMPROVED: Audit Trail entries for post editing will identify the post type wherever possible.</li>
|
212 |
+
<li><strong>(v.0)</strong> IMPROVED: Audit Trail entries will try to display all message text correctly.</li>
|
213 |
+
<li><strong>(v.0)</strong> IMPROVED: Login/Register/Password forms are only checked when visitor is not logged-in.</li>
|
214 |
+
<li><strong>(v.0)</strong> IMPROVED: Major database code refactoring and other code improvements.</li>
|
215 |
+
<li><strong>(v.0)</strong> IMPROVED: User sessions handling.</li>
|
216 |
+
<li><strong>(v.0)</strong> IMPROVED: Security Admin UX - ajax session checking, with admin notifications and auto-page reload.</li>
|
217 |
+
<li><strong>(v.0)</strong> IMPROVED: Security Admin password setting now requires a confirmation password entry.</li>
|
218 |
+
<li><strong>(v.0)</strong> IMPROVED: Refined Cooldown timing system.</li>
|
219 |
+
<li><strong>(v.0)</strong> IMPROVED: Refined Bot checkbox Javascript.</li>
|
220 |
+
<li><strong>(v.0)</strong> IMPROVED: Cron entry cleanup after deactivation.</li>
|
221 |
+
<li><strong>(v.0)</strong> UPDATED: Bootstrap libraries to latest release v4.1.3.</li>
|
222 |
+
<li><strong>(v.0)</strong> FIXED: Potential bug with Plugin/Themes guard scanning.</li>
|
223 |
+
<li><strong>(v.0)</strong> FIXED: PHP Warning(s).</li>
|
224 |
+
</ul>
|
225 |
+
<p>= 6.8 Series =
|
226 |
+
<em>Released: 11th June, 2018</em> - <a href="https://shsec.io/d4">Release Notes</a></p>
|
227 |
+
<ul>
|
228 |
+
<li><strong>(v.2)</strong> FIXED: Bug with multi-factor authentication verification.</li>
|
229 |
+
<li><strong>(v.2)</strong> FIXED: Bug with chosen reCAPTCHA style not being honoured on login pages</li>
|
230 |
+
<li><strong>(v.2)</strong> FIXED: Bug with Invisible reCAPTCHA + WooCommerce</li>
|
231 |
+
<li><strong>(v.2)</strong> FIXED: Bug with Pwned passwords always being checked even if setting turned off.</li>
|
232 |
+
<li><strong>(v.1)</strong> FIXED: A couple of bugs with WooCommerce reCAPTCHA processing.</li>
|
233 |
+
<li><strong>(v.1)</strong> FIXED: A bug with user sessions cleaning</li>
|
234 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] White Label - ability to re-brand the entire Shield Security plugin to your company brand.</li>
|
235 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Option for all users to receive notification email upon login to their accounts.</li>
|
236 |
+
<li><strong>(v.0)</strong> IMPROVED: Completely rebuilt the bot and reCAPTCHA login protection system.</li>
|
237 |
+
<li><strong>(v.0)</strong> IMPROVED: Import/Export system hugely improved with respect to automated push of options from Master sites.</li>
|
238 |
+
<li><strong>(v.0)</strong> IMPROVED: A different approach to sessions management that should handle sessions a bit better.</li>
|
239 |
+
<li><strong>(v.0)</strong> IMPROVED: Expired user sessions are cleaned from the DB using a cron, and on Insights Dashboard load.</li>
|
240 |
+
</ul>
|
241 |
+
<p>= 6.7 Series =
|
242 |
+
<em>Released: 21st May, 2018</em> - <a href="https://shsec.io/cx">Release Notes</a></p>
|
243 |
+
<ul>
|
244 |
+
<li><strong>(v.2)</strong> ADDED: [<strong>PRO</strong>] Admin Notes feature - Notes can now be easily deleted (editing will not be possible).</li>
|
245 |
+
<li><strong>(v.2)</strong> UPDATED: Some translations.</li>
|
246 |
+
<li><strong>(v.2)</strong> FIXED: A few bugs with the Insights Dashboard.</li>
|
247 |
+
<li><strong>(v.2)</strong> FIXED: Removed the dependency on jQuery with Invisible reCAPTCHA.</li>
|
248 |
+
<li><strong>(v.1)</strong> FIXED: A few bugs with the Insights Dashboard</li>
|
249 |
+
<li><strong>(v.1)</strong> ADDED: [<strong>PRO</strong>] Admin Notes feature - you can now add notes to the Shield plugin in the Insights Dashboard.</li>
|
250 |
+
<li><strong>(v.0)</strong> ADDED: All-New Insights Dashboard providing a high-level overview of your site security, with recommendations.</li>
|
251 |
+
<li><strong>(v.0)</strong> ADDED: Helpful, explanatory videos directly into the Guided Welcome Wizard.</li>
|
252 |
+
<li><strong>(v.0)</strong> ADDED: A simple test cron to demonstrate whether your site crons are running.</li>
|
253 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Full support for new WordPress GDPR Privacy Policy controls for exporting and erasing data.</li>
|
254 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] New GDPR guided wizard for exporting/erasing particular data based on custom search results.</li>
|
255 |
+
<li><strong>(v.0)</strong> CHANGED: Guided Wizards now load through WP admin to fix ajax problems for poorly configured SSL on some sites</li>
|
256 |
+
<li><strong>(v.0)</strong> IMPROVED: Upgraded Bootstrap library to 4.1.1.</li>
|
257 |
+
<li><strong>(v.0)</strong> IMPROVED: Compatibility with AIO Events Cal - they like to force their old Twig libraries on everyone else.</li>
|
258 |
+
</ul>
|
259 |
+
<p>= 6.6 Series =
|
260 |
+
<em>Released: 19th March, 2018</em> - <a href="https://shsec.io/c3">Release Notes</a></p>
|
261 |
+
<ul>
|
262 |
+
<li><strong>(v.7)</strong> IMPROVED: reCAPTCHA JS is only included on pages where it's actually used by Shield.</li>
|
263 |
+
<li><strong>(v.7)</strong> IMPROVED: Upgrade Bootstrap library to 4.1.0.</li>
|
264 |
+
<li><strong>(v.7)</strong> IMPROVED: Include jQuery for the plugin badge as required</li>
|
265 |
+
<li><strong>(v.6)</strong> ADDED: Small exclusion in the firewall for a jetpack parameter.</li>
|
266 |
+
<li><strong>(v.6)</strong> ADDED: SVGs to the default list of files scanned by the plugin guard.</li>
|
267 |
+
<li><strong>(v.6)</strong> ADDED: Workaround for a <a href="https://wordpress.org/support/topic/forcefully-executing-wp_footer-not-compatible-with-other-plugins/">ridiculous NGG bug</a>.</li>
|
268 |
+
<li><strong>(v.1-4)</strong> FIXED: Various small fixes and improvements</li>
|
269 |
+
<li><strong>(v.4)</strong> FIXED: PHP Fatal Error on wp object cache.</li>
|
270 |
+
<li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] <a href="https://shsec.io/c1">Keyless Activation of Pro licenses</a>.</li>
|
271 |
+
<li><strong>(v.0)</strong> ADDED: <a href="https://shsec.io/c2">WordPress Password Policies</a>.</li>
|
272 |
+
<li><strong>(v.0)</strong> ADDED: Pwned Passwords Detection.</li>
|
273 |
+
<li><strong>(v.0)</strong> IMPROVED: Major rewrite of plugin AJAX handling.</li>
|
274 |
+
<li><strong>(v.0)</strong> IMPROVED: Notices to indicate the time of the last scans.</li>
|
275 |
+
<li><strong>(v.0)</strong> FIXED: A few bugs</li>
|
276 |
+
</ul>
|
277 |
+
<p>= 6.5 Series =
|
278 |
+
<em>Released: 5th March, 2018</em> - <a href="https://shsec.io/bu">Release Notes</a></p>
|
279 |
+
<ul>
|
280 |
+
<li><strong>(v.0)</strong> IMPROVED: <a href="https://shsec.io/bq">Plugin Guard</a> better handles the case where a plugin/theme has been entirely renamed/removed.</li>
|
281 |
+
<li><strong>(v.0)</strong> IMPROVED: Attempts to access the XML-RPC system when it's disabled will now result in a transgression increment in the IP Black List</li>
|
282 |
+
<li><strong>(v.0)</strong> IMPROVED: Try to prevent black listing the server's own public IP address where visitor IP address detection is not correctly configured.</li>
|
283 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Provisional support for not processing 2FA logins for Woocommerce Social Login plugin.</li>
|
284 |
+
<li><strong>(v.0)</strong> FIXED: Plugin Guard better handles ignoring non-WordPress.org Plugins/Themes</li>
|
285 |
+
<li><strong>(v.0)</strong> FIXED: A few small bugs</li>
|
286 |
+
</ul>
|
287 |
+
<p>= 6.4 Series =
|
288 |
+
<em>Released: 26th February, 2018</em> - <a href="https://shsec.io/br">Release Notes</a></p>
|
289 |
+
<ul>
|
290 |
+
<li><strong>(v.1-4)</strong> FIXED: Various Fixes</li>
|
291 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] New Scanner to <a href="https://shsec.io/bq">detect file changes for active plugins and themes</a></li>
|
292 |
+
<li><strong>(v.0)</strong> IMPROVED: Automatic updates for vulnerable plugins ignores <a href="https://shsec.io/bc">automatic updates delay setting</a></li>
|
293 |
+
<li><strong>(v.0)</strong> CHANGED: Email notifications for scanners will now link to the Wizard where possible, instead of listing files.</li>
|
294 |
+
</ul>
|
295 |
+
<p>= 6.3 Series =
|
296 |
+
<em>Released: 12th February, 2018</em> - <a href="https://shsec.io/bc">Release Notes</a></p>
|
297 |
+
<ul>
|
298 |
+
<li><strong>(v.3)</strong> FIXED: Bug with automatic updates delay setting</li>
|
299 |
+
<li><strong>(v.2)</strong> CHANGED: Changed a text that seems to cause servers to swallow-up emails. <a href="https://shsec.io/bi">See here for more reliable email</a></li>
|
300 |
+
<li><strong>(v.1)</strong> FIXED: Options page javascript to work around conflicts.</li>
|
301 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] <a href="https://shsec.io/bc">Automatic updates stability delay</a></li>
|
302 |
+
<li><strong>(v.0)</strong> IMPROVED: Complete <a href="https://shsec.io/bd">plugin UI rebuild</a>, using the new Bootstrap 4.</li>
|
303 |
+
<li><strong>(v.0)</strong> FIXED: A few bugs with Google Authenticator.</li>
|
304 |
+
</ul>
|
305 |
+
<p>= 6.2 Series =
|
306 |
+
<em>Released: 31st January, 2018</em> - <a href="https://shsec.io/b6">Release Notes</a></p>
|
307 |
+
<ul>
|
308 |
+
<li><strong>(v.2)</strong> FIXED: Fix for IP Manager PHP error.</li>
|
309 |
+
<li><strong>(v.2)</strong> IMPROVED: Two-factor verification email.</li>
|
310 |
+
<li><strong>(v.1)</strong> FIXED: Bug where administrator login email notification setting is not being honoured.</li>
|
311 |
+
<li><strong>(v.1)</strong> IMPROVED: If a site is having trouble with database creation, User Sessions wont lock you out.</li>
|
312 |
+
<li><strong>(v.0)</strong> IMPROVED: Major overhaul of the Shield User Sessions system.</li>
|
313 |
+
<li><strong>(v.0)</strong> IMPROVED: Link the Security Admin authentication with the new Sessions system.</li>
|
314 |
+
<li><strong>(v.0)</strong> IMPROVED: Major overhaul to plugin's user meta data storage, limiting to a single DB entry for all data.</li>
|
315 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Ability to increase frequency of file system scans up to once every hour.</li>
|
316 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Add a "remember me" option, to allow users to skip Multi-factor authentication for a set number of days.</li>
|
317 |
+
</ul>
|
318 |
+
<p>= 6.1 Series =
|
319 |
+
<em>Released: 15th January, 2018</em> - <a href="https://shsec.io/ay">Release Notes</a></p>
|
320 |
+
<ul>
|
321 |
+
<li><strong>(v.1)</strong> FIXED: Verify link missing from the two-factor authentication verification email.</li>
|
322 |
+
<li><strong>(v.0)</strong> ADDED: 3x more Shield Wizards: Multi-factor Authentication, Core File Scanning, Unrecognised File Scanning.</li>
|
323 |
+
<li><strong>(v.0)</strong> ADDED: You can now use regular expressions for file exclusions in the 'Unrecognised File Scanner'.</li>
|
324 |
+
<li><strong>(v.0)</strong> CHANGED: File Scanner email notifications now link to the appropriate scanner wizard directly.</li>
|
325 |
+
<li><strong>(v.0)</strong> IMPROVED: Plugin options pages restyling.</li>
|
326 |
+
<li><strong>(v.0)</strong> IMPROVED: Plugin refactoring and improvements.</li>
|
327 |
+
</ul>
|
328 |
+
<p>= 6.0 Series =
|
329 |
<em>Released: 18th December, 2017</em></p>
|
330 |
<ul>
|
331 |
+
<li><strong>(v.0)</strong> ADDED: All-new Shield Welcome and Setup Wizard - more helpful guided wizards to come.</li>
|
332 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] <a href="https://shsec.io/at">Shield options import and export</a></li>
|
333 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] In conjunction with import/export - Shield Security Network: automated options syncing.</li>
|
334 |
+
<li><strong>(v.0)</strong> CHANGED: Going forward, new features and options will <a href="https://shsec.io/au">support only PHP 5.4+</a>. Existing features will remain unaffected.</li>
|
335 |
</ul>
|
336 |
+
<p>= 5.20 Series =
|
337 |
<em>Released: 11th December, 2017</em></p>
|
338 |
<ul>
|
339 |
+
<li><strong>(v.0)</strong> IMPROVED: [<strong>PRO</strong>] Audit Trail length are configurable. Length for free is 50 entries (the original unpaginated limit)</li>
|
340 |
+
<li><strong>(v.0)</strong> IMPROVED: Large redesign of options sections to be more intuitive and cleaner</li>
|
341 |
+
<li><strong>(v.0)</strong> IMPROVED: Added dedicated help section for each module.</li>
|
342 |
+
<li><strong>(v.0)</strong> IMPROVED: Certain modules have an new <em>Actions</em> centre, such a Audit Trail viewer and User Sessions manager</li>
|
343 |
+
<li><strong>(v.0)</strong> IMPROVED: Audit Trails are now ajax-paginated. You can browse through all your audit trail entries</li>
|
344 |
+
<li><strong>(v.0)</strong> IMPROVED: User session tables are also ajax-paginated.</li>
|
345 |
</ul>
|
346 |
+
<p>= 5.19 Series =
|
347 |
<em>Released: 4th December, 2017</em></p>
|
348 |
<ul>
|
349 |
+
<li><strong>(v.1)</strong> FIXED: Plugin Vulnerabilities scan for premium plugins.</li>
|
350 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Automated WordPress plugins vulnerability scanner with auto updates email notifications</li>
|
351 |
+
<li><strong>(v.0)</strong> ADDED: Added Google reCAPTCHA support for register/forget password pages.</li>
|
352 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Support for Multi-Factor Authentication for WooCommerce and other 3rd party plugins.</li>
|
353 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Bot-protection/Google reCAPTCHA support for BuddyPress register pages.</li>
|
354 |
</ul>
|
355 |
+
<p>= 5.18 Series =
|
356 |
<em>Released: 27th November, 2017</em></p>
|
357 |
<ul>
|
358 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Invisible Google reCAPTCHA option.</li>
|
359 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Support for Google reCAPTCHA themes - light and dark.</li>
|
360 |
+
<li><strong>(v.0)</strong> IMPROVEMENT: Google reCAPTCHA is more reliable and configurable.</li>
|
361 |
</ul>
|
362 |
+
<p>= 5.17 Series =
|
363 |
<em>Released: 23rd November, 2017</em></p>
|
364 |
<ul>
|
365 |
+
<li><strong>(v.0)</strong> ADDED: Shield Security goes Pro! Added new options and extras to premium clients.</li>
|
366 |
+
<li><strong>(v.0)</strong> IMPROVEMENT: Fix and improvement to Google reCAPTCHA.</li>
|
367 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Support for Woocommerce and Easy Digital Downloads login/registration form protection.</li>
|
368 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Ability to customise most user-facing texts.</li>
|
369 |
+
<li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Extra IP Transgression signal.</li>
|
370 |
</ul>
|
371 |
+
<p>= 5.16 Series =
|
372 |
<em>Released: 16th October, 2017</em></p>
|
373 |
<p>With this release, we fixed a clash of options for Google reCAPTCHA. Every attempt was made to ensure no interruption to your existing settings, but please check to ensure your reCAPTCHA settings are as you expect them to be.</p>
|
374 |
<ul>
|
375 |
+
<li><strong>(v.4)</strong> FIX: Error with incorrect/unprefixed database table name used in SQL query.</li>
|
376 |
+
<li><strong>(v.3)</strong> IMPROVEMENT: Tweak to the Visitor IP Auto-detection to better ensure CloudFlare IP addresses are ignored.</li>
|
377 |
+
<li><strong>(v.3)</strong> IMPROVEMENT: Plugin Badge will now stay closed when a visitor closes it.</li>
|
378 |
+
<li><strong>(v.2)</strong> FIX: Removed some namespace parsing that broke on sites with PHP 5.2.</li>
|
379 |
+
<li><strong>(v.1)</strong> FIX: 404 page displayed for password reset request when Login URL is renamed.</li>
|
380 |
+
<li><strong>(v.0)</strong> IMPROVEMENT: Much better auto-detection of valid request/visitor IP addresses.</li>
|
381 |
+
<li><strong>(v.0)</strong> FIX: Clashing of reCAPTCHA options for Comments and Login Protection.</li>
|
382 |
+
<li><strong>(v.0)</strong> IMPROVEMENT: Statistic Reporting database management and pruning.</li>
|
383 |
+
<li><strong>(v.0)</strong> FIX: Various system fixes and improvements.</li>
|
384 |
+
</ul>
|
385 |
+
<p>= 5.15 Series =
|
386 |
<em>Released: 21st September, 2017</em></p>
|
387 |
<ul>
|
388 |
+
<li><strong>(v.1)</strong> FIX: Processing AJAX requests from the Network Admin side of WordPress.</li>
|
389 |
+
<li><strong>(v.1)</strong> IMPROVEMENTS: Better handling of file exclusions in the Hack Guard module.</li>
|
390 |
+
<li><strong>(v.1)</strong> IMPROVEMENTS: Better handling of fatal errors in loading Shield where some core files are missing.</li>
|
391 |
+
<li><strong>(v.0)</strong> ADDED: New HTTP Security Header: Referrer Policy.</li>
|
392 |
+
<li><strong>(v.0)</strong> ADDED: Supports paths for file exclusions in the Unrecognised File Scanner.</li>
|
393 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Better interception of unintentional redirects to the hidden Login URL (e.g. /wp-admin/customize.php).</li>
|
394 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Better handling of email sending entries in the Audit Trail.</li>
|
395 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Improved (tabbed) display of Audit Trail.</li>
|
396 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Better generation & handling of the One Time Password for email-based two-factor authentication.</li>
|
397 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Some code clean up and refactoring.</li>
|
398 |
+
</ul>
|
399 |
+
<p>= 5.14 Series =
|
400 |
<em>Released: 9th September, 2017</em></p>
|
401 |
<ul>
|
402 |
+
<li><strong>(v.0)</strong> ADDED: Option for administrators to manually override and set the source of the visitor IP address.</li>
|
403 |
+
<li><strong>(v.0)</strong> UPDATED: In-plugin documentation links to updated and revised helpdesk articles/blogs.</li>
|
404 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Strip out any non-alphanumeric characters uses in the generation of Google Authenticator URLs.</li>
|
405 |
+
<li><strong>(v.0)</strong> FIX: Shield now ignores any requests sent to Rest API URIs with respect to Shield user sessions.</li>
|
406 |
</ul>
|
407 |
+
<p>= 5.13 Series =
|
408 |
<em>Released: 15th August, 2017</em></p>
|
409 |
<ul>
|
410 |
+
<li><strong>(v.2)</strong> IMPROVEMENTS: Small adjustment to handling of Shield User sessions in conjunction with WordPress sessions.</li>
|
411 |
+
<li><strong>(v.2)</strong> FIX: Restore display of help links for options.</li>
|
412 |
+
<li><strong>(v.1)</strong> FIX: PHP 5.2 incompatibility.</li>
|
413 |
+
<li><strong>(v.0)</strong> ADDED: New option for <a href="https://shsec.io/94">Unrecognised File Scanner</a> to scan the Uploads folder for JS and PHP files.</li>
|
414 |
+
<li><strong>(v.0)</strong> ADDED: Option to provide custom list of files to be excluded from the <a href="https://shsec.io/94">Unrecognised File Scanner</a>.</li>
|
415 |
</ul>
|
416 |
+
<p>= 5.12 Series =
|
417 |
<em>Released: 3rd August, 2017</em></p>
|
418 |
<ul>
|
419 |
+
<li><strong>(v.2)</strong> IMPROVEMENTS: Improved support for Windows IIS hosting for <a href="https://shsec.io/94">Unrecognised File Scanner</a></li>
|
420 |
+
<li><strong>(v.2)</strong> CHANGED: Removed the email-based 2FA automatic login link.</li>
|
421 |
+
<li><strong>(v.2)</strong> FIX: Potential bug with Shield not recognising plugin configuration updates and not rebuilding options accordingly.</li>
|
422 |
+
<li><strong>(v.1)</strong> ADDED: A few more exclusions for the <a href="https://shsec.io/94">Unrecognised File Scanner</a></li>
|
423 |
+
<li><strong>(v.1)</strong> FIX: Fix for Fatal error.</li>
|
424 |
+
<li><strong>(v.0)</strong> ADDED: <a href="https://shsec.io/94">Unrecognised File Scanner</a> release. Automatically detect and delete<pre><code> <span class="hljs-keyword">any</span> <span class="hljs-built_in">files</span> present <span class="hljs-keyword">in</span> core WordPress <span class="hljs-built_in">directories</span> that aren<span class="hljs-string">'t part of your core installation.</span>
|
425 |
+
</code></pre></li>
|
426 |
+
<li><strong>(v.0)</strong> ADDED: Updated Firewall rules for SQL under the 'Aggressive' rule set.</li>
|
427 |
</ul>
|
428 |
+
<p>= 5.11 Series =
|
429 |
<em>Released: 26th July, 2017</em></p>
|
430 |
<ul>
|
431 |
+
<li><strong>(v.1)</strong> FIX: JSON syntax</li>
|
432 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Final preparation for <a href="https://shsec.io/83">Shield Central</a> release.</li>
|
433 |
</ul>
|
434 |
+
<p>= 5.10 Series =
|
435 |
<em>Released: 19th June, 2017</em></p>
|
436 |
<ul>
|
437 |
+
<li><strong>(v.2)</strong> FIXED: Fatal error with GASP + Password Reset.</li>
|
438 |
+
<li><strong>(v.2)</strong> FIXED: Fatal error with failing reCAPTCHA HTTP requests.</li>
|
439 |
+
<li><strong>(v.1)</strong> IMPROVEMENTS: Further preparation for <a href="https://shsec.io/83">Shield Central</a> release.</li>
|
440 |
+
<li><strong>(v.0)</strong> ADDED: More in-depth reporting and statistics gathering - options for reports will be made available<pre><code> <span class="hljs-keyword">in</span> <span class="hljs-selector-tag">a</span> later release.
|
441 |
+
</code></pre></li>
|
442 |
</ul>
|
443 |
+
<p>= 5.9 Series =
|
444 |
<em>Released: 31st May, 2017</em></p>
|
445 |
<ul>
|
446 |
+
<li><strong>(v.0)</strong> ADDED: Help Videos for 1 or 2 modules. More to come and just testing format and uptake.</li>
|
447 |
+
<li><strong>(v.0)</strong> ADDED: Special handling for WP Fastest Cache.</li>
|
448 |
<li><strong>(v.0)</strong> CHANGE: Configuration for automatic self-update for the Shield plugin has been removed.</li>
|
449 |
+
<li><strong>(v.0)</strong> CHANGE: No longer remove an existing user session when accessed from another IP address. Just redirect.<pre><code> Protects existing, legitimate sessions <span class="hljs-keyword">from</span> <span class="hljs-keyword">being</span> forcefully expired.
|
450 |
+
</code></pre></li>
|
451 |
+
<li><strong>(v.0)</strong> FIXED: Danish string translation.</li>
|
452 |
</ul>
|
453 |
+
<p>= 5.8 Series =
|
454 |
<em>Released: 7th April, 2017</em></p>
|
455 |
<ul>
|
456 |
+
<li><strong>(v.2)</strong> IMPROVEMENTS: The core file scanner now works more reliably for international WordPress installations.</li>
|
457 |
<li><strong>(v.2)</strong> CHANGE: Login Cooldown now uses only the flag file as an indicator of login times.</li>
|
458 |
<li><strong>(v.2)</strong> CHANGE: Filter to allow for changing the two factor timeout period, from 5 (minutes). Filter: <code>icwp-wpsf-login_intent_timeout</code></li>
|
459 |
<li><strong>(v.2)</strong> CHANGE: Changed timeout for two-factor authentication email to 5 minutes to account for slower email-sending providers.</li>
|
460 |
<li><strong>(v.2)</strong> CHANGE: Added further clarification to the Login Notification email indicating that two-factor authentication was pending.</li>
|
461 |
+
<li><strong>(v.1)</strong> FIXED: Fixed a couple of bugs with the Login Authentication Portal, for certain edge cases.</li>
|
462 |
+
<li><strong>(v.0)</strong> CHANGE: Major overhaul of <a href="https://shsec.io/87">Two-Factor / Multi-Factor Login Authentication</a>.</li>
|
463 |
+
<li><strong>(v.0)</strong> CHANGE: <a href="https://shsec.io/86">Introduction of Login Authentication Portal</a> for improved Multi-Factor Authentication.</li>
|
464 |
+
<li><strong>(v.0)</strong> ADDED: Option to choose between two-factor or multi-factor login authentication.</li>
|
465 |
+
<li><strong>(v.0)</strong> ADDED: Administrators can remove Google Authenticator from another user's profile.</li>
|
466 |
+
<li><strong>(v.0)</strong> ADDED: When Security Admin is active, only Security Admins may remove Google Authenticator from other admins.</li>
|
467 |
<li><strong>(v.0)</strong> CHANGE: Yubikey login authentication is now managed directly from the User Profile screen, as with Google Authenticator.</li>
|
468 |
<li><strong>(v.0)</strong> CHANGE: Email-based login authentication no longer uses a separate database table.</li>
|
469 |
+
<li><strong>(v.0)</strong> FIXED: Core file scanning now adequately handles Windows/Unix new lines during scan.</li>
|
470 |
+
<li><strong>(v.0)</strong> FIXED: Certain crons weren't setup correctly.</li>
|
471 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Further preparation for <a href="https://shsec.io/83">Shield Central</a> release.</li>
|
472 |
</ul>
|
473 |
<p>= 5.7 Series =</p>
|
474 |
<ul>
|
475 |
+
<li><strong>(v.3)</strong> FIXED: Attempt to improve the Google Authenticator flow for more reliable activation.</li>
|
476 |
+
<li><strong>(v.2)</strong> IMPROVEMENTS: More admin notices when saving Google Authenticator settings.</li>
|
477 |
+
<li><strong>(v.2)</strong> IMPROVEMENTS: Further preparation for <a href="https://shsec.io/83">Shield Central</a> release.</li>
|
478 |
<li><strong>(v.1)</strong> Skipped</li>
|
479 |
+
<li><strong>(v.0)</strong> ADDED: Shortcode for displaying plugin badge in pages/posts.</li>
|
480 |
<li><strong>(v.0)</strong> CHANGE: Enabled JS eval() for the Content Security Policy by default.</li>
|
481 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Replace YAML configuration files with JSON.</li>
|
482 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Preparation for <a href="https://shsec.io/83">Shield Central</a> release.</li>
|
483 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Security Admin notices are more refined and optimized.</li>
|
484 |
+
<li><strong>(v.0)</strong> IMPROVEMENTS: Removed unnecessary files/code.</li>
|
485 |
</ul>
|
486 |
<p>= 5.6 Series =</p>
|
487 |
<ul>
|
488 |
+
<li><strong>(v.2)</strong> CHANGE: Fix an instance where the hidden Login URL would be leaded.</li>
|
489 |
+
<li><strong>(v.1)</strong> CHANGE: Replaying of Yubikey one-time-passwords is no longer permitted.</li>
|
490 |
+
<li><strong>(v.1)</strong> ADDED: Filter for login form GASP fields.</li>
|
491 |
+
<li><strong>(v.1)</strong> ADDED: Filter for comment form GASP fields.</li>
|
492 |
+
<li><strong>(v.1)</strong> CHANGE: Improved compatibility of HTTP Headers with WP Super Cache.</li>
|
493 |
+
<li><p><strong>(v.0)</strong> ADDED: Option to disable anonymous Rest API access. WordPress v4.7+ only. Note that if another plugin</p>
|
494 |
+
<pre><code> <span class="hljs-keyword">or</span> service authenticates <span class="hljs-keyword">the</span> request <span class="hljs-keyword">it</span> will be honoured, whether anonymous <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span>.
|
495 |
+
</code></pre><p>= 5.5 Series =</p>
|
496 |
</li>
|
497 |
+
<li><p><strong>(v.6)</strong> IMPROVED: Fixed possible leak of the Login URL from the 'Hide WP Login URL' feature.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
498 |
</li>
|
499 |
+
<li><strong>(v.5)</strong> ADDED: Ability to add custom protocols to the domains (apart from http/s) to the Content Security Policy</li>
|
500 |
+
<li><strong>(v.5)</strong> FIXED: Bug where automatic update emails would contain empty plugins.</li>
|
501 |
+
<li><strong>(v.5)</strong> FIXED: Javascript scope on GASP form elements.</li>
|
502 |
+
<li><strong>(v.5)</strong> FIXED: Various fixes and code improvements.</li>
|
503 |
+
<li><strong>(v.4)</strong> FIXED: Bug with data cleaning/storage that caused stored options to balloon resulting in database timeouts. (only certain options affected)</li>
|
504 |
+
<li><strong>(v.4)</strong> IMPROVED: Sometimes "anti-virus" scanners scared normal, everyday hard-working folk by identifying a Shield file as being a virus, because they're not very clever - reduced chances of this.</li>
|
505 |
+
<li><strong>(v.3)</strong> ADDED: Fix for WordPress Multisite where the correct database prefix wasn't being used.</li>
|
506 |
+
<li><strong>(v.2)</strong> ADDED: Filter to allow modification of the email footer</li>
|
507 |
+
<li><strong>(v.2)</strong> ADDED: Block auto-updates on Shield itself if PHP < 5.3 and new version is v6.0+</li>
|
508 |
+
<li><strong>(v.2)</strong> FIXED: Missing Link</li>
|
509 |
+
<li><strong>(v.2)</strong> FIXED: Plugin Installation ID wasn't always being set</li>
|
510 |
+
<li><strong>(v.2)</strong> TRANSLATIONS: Dutch (56%)</li>
|
511 |
+
<li><strong>(v.1)</strong> ADDED: Built-in forceful protection in the form of a wp_die() against the (currently) un-patched W3 Total Cache XSS vulnerability <a href="https://shsec.io/7j">more info</a></li>
|
512 |
+
<li><strong>(v.1)</strong> IMPROVED: Better XMLRPC Lockdown - prevents ANY XMLRPC command processing.</li>
|
513 |
+
<li><strong>(v.1)</strong> IMPROVED: Make certain strings translatable</li>
|
514 |
+
<li><strong>(v.1)</strong> IMPROVED: Wrap-up certain login form elements into spans/divs to allow styling etc.</li>
|
515 |
+
<li><strong>(v.1)</strong> IMPROVED: PHP Version number cleaning during stats tracking.</li>
|
516 |
+
<li><strong>(v.0)</strong> ADDED: Options and statistics tracking ability. Over time we are looking to share statistics and performance metrics of Shield.</li>
|
517 |
+
<li><strong>(v.0)</strong> IMPROVED: Performance for options loading, especially for web hosts that don't permit file writing</li>
|
518 |
+
<li><strong>(v.0)</strong> CHANGED: Numerous fixes and code improvements.</li>
|
519 |
+
<li><strong>(v.0)</strong> CHANGED: Removed query that deletes old GASP comment tokens on normal page loads.</li>
|
520 |
+
<li><strong>(v.0)</strong> CHANGED: Google reCAPTCHA is now based on the locale of the website, not auto-detected.</li>
|
521 |
+
<li><strong>(v.0)</strong> FIXED: Now URL encodes the username in the link for two-factor authentication by email.</li>
|
522 |
+
<li><strong>(v.0)</strong> FIXED: If the xmlrpc.php has been deleted, this is now ignore by the file scanner</li>
|
523 |
+
<li><strong>(v.0)</strong> TRANSLATIONS: Dutch (38%), Portuguese (32%)</li>
|
524 |
</ul>
|
525 |
<p>= 5.4 Series =</p>
|
526 |
<ul>
|
527 |
+
<li><strong>(v.5)</strong> CHANGED: User Management module is no-longer enabled by default on clean installations</li>
|
528 |
+
<li><strong>(v.5)</strong> CHANGED: Made the GASP checkbox for Login protection clickable by label. <a href="https://github.com/FernleafSystems/Shield/pull/22">Thanks Aubrey!</a></li>
|
529 |
+
<li><strong>(v.5)</strong> CHANGED: Shield Statistics only shows for WordPress admins (instead of all users)</li>
|
530 |
+
<li><strong>(v.5)</strong> FIXED: Added a couple of guards to ensure data is of the correct format to prevent spurious errors</li>
|
531 |
+
<li><strong>(v.5)</strong> FIXED: Bug where automatic file repair links from emails we're not working.</li>
|
532 |
<li><strong>(v.4)</strong> SKIPPED.</li>
|
533 |
+
<li><strong>(v.3)</strong> FIXED: Various fixes and improvements</li>
|
534 |
+
<li><strong>(v.3)</strong> CHANGED: Lots of cleaning of old code.</li>
|
535 |
+
<li><strong>(v.3)</strong> REMOVED: Various old, unused options, and the force_ssl_login option as it's deprecated by WordPress Core</li>
|
536 |
+
<li><strong>(v.3)</strong> TRANSLATIONS: Dutch (36%), Swedish (35%)</li>
|
537 |
+
<li><strong>(v.3)</strong> FIXED: Various fixes and improvements</li>
|
538 |
+
<li><strong>(v.3)</strong> CHANGED: Lots of cleaning of old code.</li>
|
539 |
+
<li><strong>(v.3)</strong> REMOVED: Various old, unused options, and the force_ssl_login option as it's deprecated by WordPress Core</li>
|
540 |
+
<li><strong>(v.3)</strong> TRANSLATIONS: Dutch (36%), Swedish (35%)</li>
|
541 |
+
<li><strong>(v.2)</strong> ADDED: A guard around certain modules like, User Sessions, to ensure the DB has been initiated properly before use.</li>
|
542 |
+
<li><strong>(v.2)</strong> ADDED: Exclusion for Swedish license files that don't exist in the SVN repo.</li>
|
543 |
+
<li><strong>(v.2)</strong> ADDED: Parameter exclusion for reCAPTCHA.</li>
|
544 |
+
<li><strong>(v.2)</strong> CHANGED: <a href="https://shsec.io/7b">HTTP Security Headers</a> module is enabled by default on new installs.</li>
|
545 |
+
<li><strong>(v.1)</strong> FIXED: Nasty bug that caused an infinite loop bug in some configurations.</li>
|
546 |
+
<li><strong>(v.0)</strong> ADDED: Per-site plugin statistics gathering - summary display on admin dashboard.</li>
|
547 |
+
<li><strong>(v.0)</strong> ADDED: HTML class to the "I'm a human" checkbox field.</li>
|
548 |
+
<li><strong>(v.0)</strong> ADDED: Ability to change minimum user role for login notification emails with use of <code>add_filter()</code>. See FAQs.</li>
|
549 |
+
<li><strong>(v.0)</strong> REMOVED: Option 'Prevent Remote Login' causes more trouble with than it's worth with too many hosting configurations.</li>
|
550 |
+
<li><strong>(v.0)</strong> CHANGED: For websites that don't run WP Crons correctly, added code for automatic database cleaning.</li>
|
551 |
+
<li><strong>(v.0)</strong> CLEANED: Removed Twig render code as it was never being used.</li>
|
552 |
</ul>
|
553 |
<p>= 5.3 Series =</p>
|
554 |
<ul>
|
555 |
+
<li><strong>(v.2)</strong> IMPROVED: <a href="https://shsec.io/7b">HTTP Security Headers</a> Content Security Policy now supports specifying HTTPS for domains/hosts.</li>
|
556 |
+
<li><strong>(v.2)</strong> FIXED: Human Comment SPAM Feature didn't fire under certain circumstances.</li>
|
557 |
+
<li><strong>(v.2)</strong> FIXED: Fixed parsing of Human Comment SPAM dictionary words.</li>
|
558 |
+
<li><strong>(v.1)</strong> TRANSLATIONS: Dutch (32%)</li>
|
559 |
+
<li><strong>(v.0)</strong> ADDED: New Feature - <a href="https://shsec.io/7b">HTTP Security Headers</a>.</li>
|
560 |
+
<li><strong>(v.0)</strong> FIXED: Prevent renaming WP Login to "/login"</li>
|
561 |
</ul>
|
562 |
<p>= 5.2 Series =</p>
|
563 |
<ul>
|
564 |
+
<li><strong>(v.0)</strong> ADDED: Guard against core file scanner and automatic WordPress updates clashing.</li>
|
565 |
+
<li><strong>(v.0)</strong> CHANGED: Logic for brute force login checking is improved - they all run before username/password checking</li>
|
566 |
+
<li><strong>(v.0)</strong> FIXED: Certain older versions of PHP don't like combined IPv4 and IPv6 filter flags</li>
|
567 |
+
<li><strong>(v.0)</strong> FIXED: Google reCAPTCHA for WordPress sites that have restrictive settings for sockets etc.</li>
|
568 |
+
<li><strong>(v.0)</strong> REMOVED: <a href="https://shsec.io/75">Plugin vulnerabilities scanner</a>. It's out-of-date and unsuitable.</li>
|
569 |
</ul>
|
570 |
<p>= 5.1 Series =</p>
|
571 |
<ul>
|
572 |
+
<li><strong>(v.0)</strong> FIXED: Improved compatibility with bbPress.</li>
|
573 |
+
<li><strong>(v.0)</strong> CHANGED: Optimizations around options and definitions (storing fewer options data)</li>
|
574 |
+
<li><strong>(v.0)</strong> CHANGED: Improved styling and responsiveness of plugin badge.</li>
|
575 |
+
<li><strong>(v.0)</strong> ADDED: Ability to programmatically export/import options - further preparation for iControlWP+Shield integration.</li>
|
576 |
+
<li><strong>(v.0)</strong> FIXED: Issue where Core automatic updates would fail, but notification email was sent anyway</li>
|
577 |
</ul>
|
578 |
<p>= 5.0 Series =</p>
|
579 |
<ul>
|
580 |
+
<li><strong>(v.3)</strong> FIXED: Issue with setting session cookies with PHP 7</li>
|
581 |
+
<li><strong>(v.2)</strong> FIXED: <a href="https://shsec.io/5s">Rename WordPress Login URL</a> bug</li>
|
582 |
+
<li><strong>(v.2)</strong> CHANGED: reCAPTCHA text usage corrected throughout plugin.</li>
|
583 |
+
<li><strong>(v.1)</strong> CHANGED: Removed the whole 'wp-content' directory from the <a href="https://shsec.io/wpsf40">Core File Scanner</a> feature.</li>
|
584 |
+
<li><strong>(v.1)</strong> CHANGED: A WordPress filter to change the plugin badge text content (see FAQ)</li>
|
585 |
+
<li><strong>(v.1)</strong> CHANGED: Tweaked the plugin badge styling.</li>
|
586 |
+
<li><strong>(v.1)</strong> CHANGED: All emails sent by the plugin contain the name of the site and the current plugin version in the email footer.</li>
|
587 |
+
<li><strong>(v.1)</strong> ADDED: In-plugin links to blogs and info articles for Google ReCaptcha and <a href="https://shsec.io/wpsf43">Google Authenticator</a></li>
|
588 |
+
<li><strong>(v.0)</strong> NEW: WordPress Simple Firewall plugin has been re-branded and is called <strong>Shield</strong></li>
|
589 |
+
<li><strong>(v.0)</strong> ADDED: NEW feature - <a href="https://shsec.io/shld2">Google ReCaptcha</a> for Comment SPAM and Login protection.</li>
|
590 |
+
<li><strong>(v.0)</strong> ADDED: Support for this plugin is now Premium. Added Premium Support page that links to Helpdesk.</li>
|
591 |
+
<li><strong>(v.0)</strong> CHANGED: Refactor of comment spam code.</li>
|
592 |
+
<li><strong>(v.0)</strong> CHANGED: Core File Scanner now handles the odd Hungarian distribution.</li>
|
593 |
+
</ul>
|
594 |
+
<p>= 4.17 Series =
|
595 |
<em>Released: 17th February, 2016</em></p>
|
596 |
<ul>
|
597 |
+
<li><strong>(v.0)</strong> ADDED: NEW feature - <a href="https://shsec.io/wpsf43">Google Authenticator Login option</a>.</li>
|
598 |
+
<li><strong>(v.0)</strong> ADDED: <a href="https://shsec.io/wpsf40">Core File Scanner</a> now includes an automatic link to repair files (you must be logged in as admin for this link to work!).</li>
|
599 |
+
<li><strong>(v.0)</strong> ADDED: NEW - if you already have a logged-in session and you open the login screen, you'll be provided with a link to go straight to the admin area.</li>
|
600 |
+
<li><strong>(v.0)</strong> CHANGED: Email-based Two-Factor Authentication is now stateless/session-less - it will not check validity per-page load.</li>
|
601 |
+
<li><strong>(v.0)</strong> CHANGED: Changes to the email-based authentication system - now only 1 option and it no longer locks to IP or browser.</li>
|
602 |
+
<li><strong>(v.0)</strong> CHANGED: Various efficiency improvements including reduced SQL updates.</li>
|
603 |
+
<li><strong>(v.0)</strong> CHANGED: Email system is improved and now send emails from the default WordPress sender. This may be <a href="https://icontrolwp.freshdesk.com/support/solutions/articles/3000048723">changed with filter</a>.</li>
|
604 |
</ul>
|
605 |
+
<p>= 4.16 Series =
|
606 |
<em>Released: 20th January, 2016</em></p>
|
607 |
<ul>
|
608 |
+
<li><strong>(v.2)</strong> CHANGED: Further changes and improvements to the <a href="https://shsec.io/wpsf40">Core File Scanner</a>.</li>
|
609 |
+
<li><strong>(v.2)</strong> CHANGED: Improvements to the <a href="https://shsec.io/wpsf27">automatic black list system</a> for failed login attempts.</li>
|
610 |
+
<li><strong>(v.2)</strong> TRANSLATIONS: Turkish (100%)</li>
|
611 |
+
<li><strong>(v.1)</strong> CHANGED: Improved the contents of the <a href="https://shsec.io/wpsf40">Core File Scanner</a> notification email with links to original source files.</li>
|
612 |
+
<li><strong>(v.1)</strong> CHANGED: Now also excluding the /wp-content/languages/ directory since translations may update independently.</li>
|
613 |
+
<li><strong>(v.1)</strong> CHANGED: Handles the special case of <a href="https://wordpress.org/support/topic/problem-with-checksum-hashes">old index.php files</a></li>
|
614 |
+
<li><strong>(v.0)</strong> ADDED: Feature: <a href="https://shsec.io/wpsf40">Automatically scans WordPress Core files</a> and detects alterations from the default WordPress Core File data</li>
|
615 |
+
<li><strong>(v.0)</strong> ADDED: Feature: to automatically attempt to repair/replace WordPress Core files that are discovered which have been altered.</li>
|
616 |
+
<li><strong>(v.0)</strong> ADDED: Option to toggle the <a href="https://shsec.io/wpsf41">Plugin Vulnerabilities cron</a>.</li>
|
617 |
+
<li><strong>(v.0)</strong> ADDED: Two-Factor Authentication links now honour the WordPress 'redirect_to' parameter.</li>
|
618 |
+
</ul>
|
619 |
+
<p>= 4.15 Series =
|
620 |
<em>Released: 6th January, 2016</em></p>
|
621 |
<ul>
|
622 |
+
<li><strong>(v.0)</strong> ADDED: New and updated Firewall rules as well as a new 'Aggressive' option that looks for additional request data. Disabled by default, but may cause an increase in false positives.</li>
|
623 |
+
<li><strong>(v.0)</strong> CHANGED: Improved and optimized Firewall processing.</li>
|
624 |
+
<li><strong>(v.0)</strong> FIXED: <a href="https://github.com/FernleafSystems/wp-simple-firewall/issues/3">Issue</a> where automatic update notification emails are sent out without any update notices (probably due to failed updates).</li>
|
625 |
+
<li><strong>(v.0)</strong> FIXED: Small conflict with WP Login Rename and other security plugins.</li>
|
626 |
+
<li><strong>(v.0)</strong> TRANSLATIONS: Czech (91%), Finnish (98%), Turkish (98%).</li>
|
627 |
</ul>
|
628 |
+
<p>= 4.14 Series =
|
629 |
<em>Released: 20th November, 2015</em></p>
|
630 |
<ul>
|
631 |
+
<li><strong>(v.2)</strong> ADDED: User notice message displayed when the 'Theme My Login' plugin is active and you try to rename your login URL - It is not compatible.</li>
|
632 |
+
<li><strong>(v.1)</strong> ADDED: Added WordPress filter option to specify URL instead of present a 404 when Rename WP Login is active. <a href="https://icontrolwp.freshdesk.com/solution/articles/3000044812">more info</a></li>
|
633 |
+
<li><strong>(v.1)</strong> ADDED: Added 'Unique Plugin Installation ID' to be utilized in the future.</li>
|
634 |
+
<li><strong>(v.1)</strong> FIXED: WordPress Comments bug where some comments didn't pass through the SPAM filters in a certain scenario.</li>
|
635 |
+
<li><strong>(v.0)</strong> ADDED: <a href="https://shsec.io/wpsf33">Custom Automatic Update Notifications Email</a> that runs separately to the in-built WordPress core notification email.</li>
|
636 |
+
<li><strong>(v.0)</strong> ADDED: Filter to remove the admin area IP address footer text</li>
|
637 |
+
<li><strong>(v.0)</strong> CHANGED: Added native support for PayPal return links - whitelisting "verify_sign" parameter.</li>
|
638 |
+
<li><strong>(v.0)</strong> CHANGED: Tweak patterns for matching on 'WordPress terms'.</li>
|
639 |
+
<li><strong>(v.0)</strong> TRANSLATIONS: Danish (100%), Czech (92%), Turkish (92%), Finnish (88%),</li>
|
640 |
+
<li><strong>(v.0)</strong> FIXED: Small bugs and readying for WordPress 4.4</li>
|
641 |
+
</ul>
|
642 |
+
<p>= 4.13 Series =
|
643 |
<em>Released: 22nd October, 2015</em></p>
|
644 |
<ul>
|
645 |
+
<li><strong>(v.0)</strong> NEW: Added option to block the modification, addition/promotion and deletion of WordPress administrators users within the 'Security Admin' module.</li>
|
646 |
+
<li><strong>(v.0)</strong> NEW: Renamed 'Admin Access' module to 'Security Admin'.</li>
|
647 |
+
<li><strong>(v.0)</strong> CHANGED: Simplified and consolidated the use of cookies for User Session - sets and removes cookies better to reduce their usage.</li>
|
648 |
+
<li><strong>(v.0)</strong> CHANGED: Simplified and consolidated the use of cookies for Two Factor Login Authentication.</li>
|
649 |
+
<li><strong>(v.0)</strong> CHANGED: Cleaned up some Comment SPAM filtering code.</li>
|
650 |
+
<li><strong>(v.0)</strong> CHANGED: Comments Filter doesn't use cookies unless a session cookie for the visitor already exists.</li>
|
651 |
+
<li><strong>(v.0)</strong> CHANGED: IP Manager Automatic Black List - default black list duration is now 1 minute & default transgressions limit is 10</li>
|
652 |
+
<li><strong>(v.0)</strong> CHANGED: Improvements to the database create queries: use MySQL Engine defaults (instead of MyISAM); use WordPress dbDelta() for updates.</li>
|
653 |
+
<li><strong>(v.0)</strong> CHANGED: Various code optimizations and cleaning.</li>
|
654 |
+
</ul>
|
655 |
+
<p>= 4.12 Series =
|
656 |
<em>Released: 10th October, 2015</em></p>
|
657 |
<ul>
|
658 |
+
<li><strong>(v.0)</strong> NEW: Option to completely disable the XML-RPC system. <a href="https://shsec.io/wpsf31">more info</a></li>
|
659 |
+
<li><strong>(v.0)</strong> CHANGED: Logged-in users are automatically forwarded to the WordPress admin only if they are Administrators.</li>
|
660 |
</ul>
|
661 |
+
<p>= 4.11 Series =
|
662 |
<em>Released: 5th October, 2015</em></p>
|
663 |
<ul>
|
664 |
+
<li><strong>(v.0)</strong> NEW: Ability to now completely block the update/changing of certain WordPress site options. <a href="https://shsec.io/wpsf30">more info</a></li>
|
665 |
+
<li><strong>(v.0)</strong> FIXED: Various small bugs with the IP Manager UI ajax.</li>
|
666 |
+
<li><strong>(v.0)</strong> FIXED: Uncaught PHP Exception when a site's hosting isn't properly configured to handle IPv6 addresses.</li>
|
667 |
+
<li><strong>(v.0)</strong> TRANSLATIONS: Danish - 57%, Czech - 100%, Finnish - 94%</li>
|
668 |
</ul>
|
669 |
+
<p>= 4.10 Series =
|
670 |
<em>Released: 23rd August, 2015</em></p>
|
671 |
<ul>
|
672 |
+
<li><strong>(v.4)</strong> REFACTOR: Notifications system is more reliable and most notices can be hidden/closed (at least for the current page load as some notices are persistent).</li>
|
673 |
+
<li><strong>(v.4)</strong> REMOVED: The old manual black list option has been completely removed - in favour of the automatic black list system.</li>
|
674 |
+
<li><strong>(v.4)</strong> CHANGED: Revised the order of certain hooks being created to avoid the possibility of pluggable.php not being loaded for PHP Shutdown.</li>
|
675 |
+
<li><strong>(v.4)</strong> CHANGED: The presence of IP addresses in the IP Whitelist will force the IP Manager feature to be enabled.</li>
|
676 |
+
<li><strong>(v.4)</strong> CHANGED: We now make an attempt to prevent the caching of WordPress wp_die() pages that we generate. (compatible with at least W3TC, Super Cache)</li>
|
677 |
+
<li><p><strong>(v.4)</strong> TRANSLATIONS: Turkish - 100%, Danish - 3%</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
678 |
</li>
|
679 |
+
<li><p><strong>(v.3)</strong> FIXED: Another PHP 5.2 incompatibility.</p>
|
|
|
680 |
</li>
|
681 |
+
<li><strong>(v.2)</strong> ADDED: White Listing UI to the IP Manager - CIDR ranges are supported (also automatically migrates IPs, except ranges, from legacy to new)</li>
|
682 |
+
<li><strong>(v.2)</strong> ADDED: Returned the black marking of failed WP login attempts to the automatic black list system</li>
|
683 |
+
<li><strong>(v.2)</strong> ADDED: Using a 3rd party API service: <a href="https://www.ipify.org/">ipify.org</a> - to find the server's own IP address so we can ensure it's not used in the black lists</li>
|
684 |
+
<li><strong>(v.2)</strong> CHANGED: AJAX calls are handled more robustly with actual error messages where possible.</li>
|
685 |
+
<li><p><strong>(v.2)</strong> FIXED: A few black list processing bugs.</p>
|
686 |
</li>
|
687 |
+
<li><p><strong>(v.1)</strong> ADDED: UI to view and remove IP address from Automatic Black List Engine.</p>
|
|
|
688 |
</li>
|
689 |
+
<li><strong>(v.1)</strong> FIX: Removed transgression counting on failed logins - WP data is inconsistent.</li>
|
690 |
+
<li><strong>(v.1)</strong> CHANGED: Original legacy white list now takes priority over new auto black list</li>
|
691 |
+
<li><strong>(v.1)</strong> CHANGED: Default transgressions limit is now 7</li>
|
692 |
+
<li><strong>(v.1)</strong> ADDED: Ability to reset plugin options to default using 'reset' flag file. <a href="https://shsec.io/wpsf28">more info</a></li>
|
693 |
+
<li><strong>(v.0)</strong> NEW FEATURE: 'FABLE' - <a href="https://shsec.io/wpsf27">Fully Automatic Black Listing Engine</a>.</li>
|
694 |
+
</ul>
|
695 |
+
<p>Simply put, FABLE will automatically block all malicious traffic by IP, based on their activity. This Security Plugin will track malicious behaviour
|
696 |
+
and count all transgressions that visitors make against the site. Once a particular visitor exceeds the specified number transgressions, FABLE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
697 |
will outright block any access they have to your WordPress site.</p>
|
698 |
<p>What makes the FABLE system better?</p>
|
699 |
<ul>
|
709 |
<li>Attempt to login with an invalid username/password combination</li>
|
710 |
<li>Any attempt to login while the login cooldown system is in-effect</li>
|
711 |
<li>Any login attempt that trips the GASP Login protection system</li>
|
712 |
+
<li>Any login attempt with a username that doesn't exist</li>
|
713 |
<li>Any attempt to access /wp-admin/, /login/, or wp-login.php while the Rename WP Login setting is active</li>
|
714 |
<li>Any comment that gets labelled as SPAM by the plugin</li>
|
715 |
+
<li>Failed attempt to authenticate with the plugin's Admin Access Protection module</li>
|
716 |
<li>Any trigger of a Firewall block rule</li>
|
717 |
</ul>
|
718 |
+
<p>= 4.9 Series =
|
719 |
<em>Released: 7th July, 2015</em></p>
|
720 |
<ul>
|
721 |
<li><strong>(v.8)</strong> CHANGED: Firewall, User Sessions and Lockdown Feature Modules are now enabled by default for new installations.</li>
|
722 |
+
<li><strong>(v.8)</strong> FIX: Some server email programs can't handle colons (:) in the email subject (because supporting all characters would be waaay too radical man).</li>
|
723 |
+
<li><strong>(v.8)</strong> ADDED: Function to better get the WordPress home URL to prevent interference from other plugins.</li>
|
724 |
+
<li><strong>(v.8)</strong> CHANGED: Updated Text For <a href="https://shsec.io/6e">Author Scan Block</a> feature.</li>
|
725 |
<li><strong>(v.7)</strong> CHANGED: How author query blocking works to be more reliable and stricter - only runs when users are not logged in, and it will DIE instead of redirect.</li>
|
726 |
<li><strong>(v.6)</strong> ADDED: New Option: prevent detection of usernames using the ?author=N query. (location under section: Lockdown -> Obscurity)</li>
|
727 |
+
<li><strong>(v.6)</strong> FIXED: Infinite redirect loop logic prevents redirect for rejected comment SPAM that's posted in bulk. This results in email notifications for spam comments.</li>
|
728 |
<li><strong>(v.5)</strong> ADDED: The plugin will load itself first before all other plugins</li>
|
729 |
+
<li><strong>(v.5)</strong> FIXED: No longer using parse_url() to determine the request URL as it's too inconsistent and unreliable.</li>
|
730 |
<li><strong>(v.4)</strong> FIX: Audit Trail Viewer display issue with non-escaped HTML (Thanks Chris!)</li>
|
731 |
<li><strong>(v.4)</strong> ADDED: An admin warning for sites with PHP version less than 5.3.2 (future versions will require this as a minimum)</li>
|
732 |
<li><strong>(v.4)</strong> TRANSLATIONS: Danish - 6%, Spanish - 76%</li>
|
736 |
<li><strong>(v.2)</strong> ADDED: Email notifications sent out to report email address on a daily cron. <a href="https://www.icontrolwp.com/2015/07/plugin-vulnerability-email-notifications/">more info</a></li>
|
737 |
<li><strong>(v.2)</strong> FIX: Work around a WordPress inline plugin update Javascript bug.</li>
|
738 |
<li><strong>(v.1)</strong> FIX: Fix syntax support for earlier versions of PHP.</li>
|
739 |
+
<li><strong>(v.0)</strong> FEATURE: Plugin Vulnerabilities Detection: If you're running plugins with known vulnerabilities you will be warned - <a href="https://shsec.io/wpsf22">more info</a></li>
|
740 |
</ul>
|
741 |
+
<p>= 4.8 Series =
|
742 |
<em>Released: 21st June, 2015</em></p>
|
743 |
<ul>
|
744 |
<li><strong>(v.0)</strong> FEATURE: Admin Access Restriction Areas - Restrict access to certain WordPress areas and functionality to <strong>Administrators</strong> with the Admin Access key.</li>
|
746 |
<li><strong>(v.0)</strong> ADDED: Admin Access Restriction Area - Themes. You can now restrict access to certain Theme actions - activate, install, update, delete.</li>
|
747 |
<li><strong>(v.0)</strong> ADDED: Admin Access Restriction Area - Pages/Post. You can now restrict access to certain Page/Post actions - Create/Edit, Publish, Delete.</li>
|
748 |
</ul>
|
749 |
+
<p>= 4.7 Series =
|
750 |
<em>Released: 29th April, 2015</em></p>
|
751 |
<ul>
|
752 |
<li><strong>(v.7)</strong> FIXED: The text used to explain why some comments were marked as spam was broken.</li>
|
753 |
<li><strong>(v.7)</strong> FIXED: Group sign-up form now honours your SSL setting.</li>
|
754 |
<li><strong>(v.7)</strong> TRANSLATIONS: Spanish - 74%, Russian - 91%, Turkish - 94%, Polish- 95%, Finnish - 100%</li>
|
755 |
+
<li><strong>(v.6)</strong> FIXED: Verifying ability to send/receive email doesn't complete if Admin Access Protection is turned on.</li>
|
756 |
+
<li><strong>(v.6)</strong> FIXED: GASP Login Protection feature breaks because certain key options aren't initialized when the feature is enabled.</li>
|
757 |
+
<li><strong>(v.6)</strong> FIXED: Some "more info" links were empty.</li>
|
758 |
<li><strong>(v.4)</strong> ADDED: Email Sending Verification when enabling two-factor authentication - this ensures your site can send (and you can receive) emails.</li>
|
759 |
<li><strong>(v.4)</strong> ADDED: Section Summaries - each option tab contains a small text summary outlining the purpose and recommendation for each.</li>
|
760 |
<li><strong>(v.4)</strong> CHANGED: The Admin Access Key input is now a password field.</li>
|
769 |
<li><strong>(v.1)</strong> FIX: Silence warnings from filesystem touch() command.</li>
|
770 |
<li><strong>(v.1)</strong> TRANSLATIONS: Polish (100%), Finnish (100%), Czech (73%), Arabic (34%)</li>
|
771 |
<li><strong>(v.0)</strong> UPDATED: Options page user interface re-design.</li>
|
772 |
+
<li><strong>(v.0)</strong> FIX: Audit trail time now reflects the user's timezone correctly.</li>
|
773 |
<li><strong>(v.0)</strong> FIX: Better compatibility with BBPress.</li>
|
774 |
<li><strong>(v.0)</strong> UPDATED: Underlying plugin code improvements.</li>
|
775 |
<li><strong>(v.0)</strong> TRANSLATIONS: Russian (100%), Czech (70%), Polish (97%)</li>
|
776 |
</ul>
|
777 |
+
<p>= 4.6 Series =
|
778 |
<em>Released: 10th April, 2015</em></p>
|
779 |
<ul>
|
780 |
+
<li><strong>(v.3)</strong> SECURITY: Added protection against XSS vulnerability in WordPress comments. <a href="https://shsec.io/63">Learn More</a> - Note: This is not a vulnerability with the Firewall plugin.</li>
|
781 |
+
<li><strong>(v.3)</strong> SECURITY: Added extra precautions to WordPress URL redirects. <a href="https://shsec.io/64">Learn More</a>.</li>
|
782 |
<li><strong>(v.3)</strong> TRANSLATIONS: Russian (70%), Czech (67%)</li>
|
783 |
<li><strong>(v.2)</strong> FIX: Bug with the database table verification logic.</li>
|
784 |
<li><strong>(v.2)</strong> TRANSLATIONS: Russian (New- 54%), Romanian (100%), Turkish (89%), Czech (53%)</li>
|
786 |
<li><strong>(v.1)</strong> UPDATED: Plugin Badge styling</li>
|
787 |
<li><strong>(v.1)</strong> UPDATED: Updated Czech(41%) and Spanish (60%) translations</li>
|
788 |
<li><strong>(v.0)</strong> ADDED: New feature that displays the last login time for all users on the users listing page (User Management feature must be enabled).</li>
|
789 |
+
<li><strong>(v.0)</strong> ADDED: <strong>Completely optional</strong> promotional Plugin Badge option - help us promote the plugin and reassure your site visitors at the same time. <a href="https://shsec.io/5x">Learn More</a></li>
|
790 |
<li><strong>(v.0)</strong> UPDATED: Updated Czech(38%) translations</li>
|
791 |
</ul>
|
792 |
+
<p>= 4.5 Series =
|
793 |
<em>Released: 6th March, 2015</em></p>
|
794 |
<ul>
|
795 |
<li><strong>(v.5)</strong> CHANGED: Updated Finnish (100%), Czech (16%) translations</li>
|
803 |
<li><strong>(v.1)</strong> ADDED: New feature- GASP Login Protection can now be applied to lost password form - enabled by default</li>
|
804 |
<li><strong>(v.0)</strong> ADDED: New feature- GASP Login Protection can now be applied to user registrations - enabled by default</li>
|
805 |
</ul>
|
806 |
+
<p>= 4.4 Series =
|
807 |
<em>Released: 21st February, 2015</em></p>
|
808 |
<ul>
|
809 |
<li><strong>(v.2)</strong> ADDED: Romanian Translation.</li>
|
810 |
<li><strong>(v.2)</strong> ADDED: A plugin minimum-requirements processing system.</li>
|
811 |
<li><strong>(v.2)</strong> IMPROVED: The WordPress admin-UI code is simpler and cleaner.</li>
|
812 |
<li><strong>(v.1)</strong> ADDED: <strong>Significant</strong> performance enhancement in plugin loading times (up to 50% reduction).</li>
|
813 |
+
<li><strong>(v.0)</strong> CHANGED: The 'Prevent Remote Login' option now tries to detect web hosting server compatibility before allowing it to be enabled.</li>
|
814 |
+
<li><strong>(v.0)</strong> CHANGED: More lax in finding the 'forceOff' file when users are trying to turn off the firewall.</li>
|
815 |
<li><strong>(v.0)</strong> CHANGED: Parsing the URL no longer outputs warnings that might interfere with response headers.</li>
|
816 |
</ul>
|
817 |
+
<p>= 4.3 Series =
|
818 |
<em>Released: 15th January, 2015</em></p>
|
819 |
<ul>
|
820 |
<li><strong>(v.6)</strong> FIXES: More thorough validation of whitelisted IP addresses</li>
|
821 |
<li><strong>(v.5)</strong> FIXES: Some hosting environments need absolute file paths for PHP include()/require()</li>
|
822 |
<li><strong>(v.5)</strong> CHANGED: Streamlined the detection of whitelisting and added in-plugin notification if <strong>you</strong> are whitelisted</li>
|
823 |
+
<li><strong>(v.4)</strong> FIXES: Work around for cases where PHP can't successfully run parse_url()</li>
|
824 |
<li><strong>(v.2)</strong> IMPROVED: Refactoring for better code organisation</li>
|
825 |
+
<li>ADDED: New Feature - <a href="https://shsec.io/5s">Rename WP Login Page</a>.</li>
|
826 |
<li>ADDED: UI indicators on whether plugins will be automatically updated in the plugins listing.</li>
|
827 |
+
<li>CHANGED: IP Address WhiteList is now global for the whole plugin, and can be accessed under the "Dashboard" area</li>
|
828 |
<li>IMPROVED: Firewall processing code is simplified and more efficient.</li>
|
829 |
</ul>
|
830 |
+
<p>= 4.2.1 =
|
831 |
<em>Released: 22th December, 2014</em></p>
|
832 |
<ul>
|
833 |
<li>FIXED: Changes to how feature specifications are read from disk to prevent .tmp file build up.</li>
|
834 |
</ul>
|
835 |
+
<p>= 4.2.0 =
|
836 |
<em>Released: 12th December, 2014</em></p>
|
837 |
<ul>
|
838 |
<li>ADDED: Audit Trail Auto Cleaning - default cleans out entries older than 30 days.</li>
|
839 |
<li>FIXED: Various small bug fixes and code cleaning.</li>
|
840 |
</ul>
|
841 |
+
<p>= 4.1.4 =
|
842 |
<em>Released: 24th November, 2014</em></p>
|
843 |
<ul>
|
844 |
<li>FIXED: Fixed small logic bug which prevented deactivation of the plugin on the UI.</li>
|
845 |
</ul>
|
846 |
+
<p>= 4.1.3 =
|
847 |
<em>Released: 19th November, 2014</em></p>
|
848 |
<ul>
|
849 |
<li>IMPROVED: User Sessions are simplified.</li>
|
851 |
</ul>
|
852 |
<p>= 4.1.2 =</p>
|
853 |
<ul>
|
854 |
+
<li>ADDED: Self-correcting database table validation - if the structure of a database table isn't what is expected, it'll be re-created.</li>
|
855 |
</ul>
|
856 |
<p>= 4.1.1 =</p>
|
857 |
<ul>
|
858 |
<li>WARNING: Due to new IPv6 support, all databases tables will be rebuilt - all active user sessions will be destroyed.</li>
|
859 |
+
<li>ADDED: Preliminary support for IPv6 addresses throughout. We don't support whitelist ranges but IPv6 addresses are handled much more reliably in general.</li>
|
860 |
+
<li>ADDED: New audit trail concept added called "immutable" that represents entries that will never be deleted - such entries would usually involve actions taken on the audit trail itself.</li>
|
861 |
<li>FIXED: Support for audit trail events with longer names.</li>
|
862 |
<li>IMPROVED: Comments Filtering - It now honours the WordPress settings for previously approved comment authors and never filters such comments.</li>
|
863 |
<li>REMOVED: Option to enable GASP Comments Filtering for logged-in users has been completely removed - this reduces plugin options complexity. All logged-in users by-pass <strong>all</strong> comments filtering.</li>
|
864 |
<li>FIXED: Prevention against plugin redirect loops under certain conditions.</li>
|
865 |
+
<li>FIXED: IP whitelisting wasn't working under certain cases.</li>
|
866 |
</ul>
|
867 |
<p>= 4.0.0 =</p>
|
868 |
<ul>
|
869 |
<li>ADDED: New Feature - Audit Trail</li>
|
870 |
<li>ADDED: Audit Trail options include: Plugins, Themes, Email, WordPress Core, Posts/Pages, Shield plugin</li>
|
871 |
<li>FIXED: Full and proper cleanup of plugin options, crons, and databases upon deactivation.</li>
|
872 |
+
<li>REMOVED: Firewall Log. This is no longer an option and is instead integrated into the "Shield" Audit Trail.</li>
|
873 |
</ul>
|
874 |
<p>= 3.5.5 =</p>
|
875 |
<ul>
|
879 |
</ul>
|
880 |
<p>= 3.5.3 =</p>
|
881 |
<ul>
|
882 |
+
<li>ADDED: A warning message on the WordPress admin if the "forceOff" override is active.</li>
|
883 |
+
<li>CHANGED: The 'forceOff' system is now temporary - i.e. it doesn't save the configuration, and so once this file is removed, the plugin returns to the settings specified.</li>
|
884 |
+
<li>CHANGED: The 'forceOn' option is now removed.</li>
|
885 |
+
<li>FIXED: Problems with certain hosting environments reading in files with the ".yaml" extension - <a href="https://wordpress.org/support/topic/yaml-breaks-plugin">support ref</a></li>
|
886 |
+
<li>FIXED: Small issue where when the file system paths change, some variables don't update properly.</li>
|
887 |
</ul>
|
888 |
<p>= 3.5.0 =</p>
|
889 |
<ul>
|
890 |
<li>CHANGED: Plugin features are now configured <a href="https://github.com/mustangostang/spyc/">using YAML</a> - no more in-PHP configuration.</li>
|
891 |
<li>REMOVED: A few options from User Sessions Management as they were unnecessary.</li>
|
892 |
<li>CHANGED: Database storing tables now have consistent naming.</li>
|
893 |
+
<li>FIXED: Issue with User Sessions Management where '0' was specified for session length, resulting in lock out.</li>
|
894 |
<li>FIXED: Firewall log gathering.</li>
|
895 |
<li>FIXED: Various PHP warning notices.</li>
|
896 |
</ul>
|
910 |
<p>= 3.2.0 =</p>
|
911 |
<ul>
|
912 |
<li>ADDED: Options to allow by-pass XML-RPC so as to be compatible with WordPress iPhone/Android apps.</li>
|
913 |
+
<li>UPDATED: Login screen message when you're forced logged-out due to 2-factor auth failure on IP or cookie.</li>
|
914 |
<li>CHANGED: Tweaked method for setting admin access protection on/off</li>
|
915 |
<li>CHANGED: comment filtering code refactoring.</li>
|
916 |
+
<li>FIXED: Options that were "multiple selects" weren't saving correctly</li>
|
917 |
</ul>
|
918 |
<p>= 3.1.5 =</p>
|
919 |
<ul>
|
938 |
<p>= 3.1.0 =</p>
|
939 |
<ul>
|
940 |
<li>ADDED: option to check the logged-in user session only on WordPress admin pages (now the default setting)</li>
|
941 |
+
<li>ADDED: option to auto-forward to the WordPress dashboard when you go to wp-login.php and you're already logged in.</li>
|
942 |
<li>ADDED: message to login screen when no user session is found</li>
|
943 |
<li>CHANGED: does not verify session when performing AJAX request. (need to build appropriate AJAX response)</li>
|
944 |
<li>FIX: for wp_login action not passing second argument</li>
|
973 |
<p>= 2.6.4 =</p>
|
974 |
<ul>
|
975 |
<li>ENHANCED: Dashboard now shows a more visual summary of settings and removes duplicate options settings with links to sections.</li>
|
976 |
+
<li>ENHANCED: WordPress Lock Down options now also set the corresponding WordPress defines if they're not already.</li>
|
977 |
</ul>
|
978 |
<p>= 2.6.3 =</p>
|
979 |
<ul>
|
980 |
<li>ADDED: More in-line plugin links to help/blog resources</li>
|
981 |
+
<li><p>ENHANCED: <a href="https://shsec.io/5b">Admin Access Protection</a> is further enhanced in 3 ways:</p>
|
982 |
+
</li>
|
983 |
+
<li><p>More robust cookie values using MD5s</p>
|
984 |
+
</li>
|
985 |
<li>Blocks plugin options updating right at the point of WordPress options update so nothing can rewrite the actual plugin options.</li>
|
986 |
<li>Locks the current Admin Access session to your IP address - effectively only 1 Shield admin allowed at a time.</li>
|
987 |
+
</ul>
|
988 |
<p>= 2.6.2 =</p>
|
989 |
<ul>
|
990 |
+
<li>ENHANCED: Added option to completely reject a SPAM comment and redirect to the home page (so it doesn't fill up your database with rubbish)</li>
|
991 |
<li>ADDED: Plugin now has an internal stats counter for spam and other significant plugin events.</li>
|
992 |
</ul>
|
993 |
<p>= 2.6.1 =</p>
|
994 |
<ul>
|
995 |
<li>ADDED: Plugin now installs with default SPAM blacklist.</li>
|
996 |
+
<li>ADDED: Now automatically checks and updates the SPAM blacklist when it's older than 48hrs.</li>
|
997 |
<li>ENHANCED: Comment messages indicate where the SPAM content was found when marking human-based spam messages.</li>
|
998 |
</ul>
|
999 |
<p>= 2.6.0 =</p>
|
1000 |
<p><strong>Major Features Release: Please review SPAM comments filtering options to determine where SPAM goes</strong></p>
|
1001 |
<ul>
|
1002 |
+
<li>FEATURE: Added Human SPAM comments filtering - replacement for Akismet that doesn't use or send any data to 3rd party services. Uses <a href="https://github.com/splorp/wordpress-comment-blacklist">Blacklist provided and maintained by Grant Hutchinson</a></li>
|
1003 |
<li>ENHANCED: Two-Factor Login now automatically logs in the user to the admin area without them having to re-login again.</li>
|
1004 |
<li>ENHANCED: Added ability to terminate all currently (two-factor) verified logins.</li>
|
1005 |
<li>ENHANCED: Spam filter/scanning adds an explanation to the SPAM content to show why a message was filtered.</li>
|
1012 |
</ul>
|
1013 |
<p>= 2.5.8 =</p>
|
1014 |
<ul>
|
1015 |
+
<li>FEATURE: Added 'PHP Code' Firewall checking option.</li>
|
1016 |
</ul>
|
1017 |
<p>= 2.5.7 =</p>
|
1018 |
<ul>
|
1024 |
</ul>
|
1025 |
<p>= 2.5.5 =</p>
|
1026 |
<ul>
|
1027 |
+
<li>FEATURE: Added 'Lockdown' feature to force login to WordPress over SSL.</li>
|
1028 |
+
<li>FEATURE: Added 'Lockdown' feature to force WordPress Admin dashboard to be delivered over SSL.</li>
|
1029 |
+
<li>FIX: Admin restricted access feature wasn't disabled with the "forceOff" option.</li>
|
1030 |
</ul>
|
1031 |
<p>= 2.5.4 =</p>
|
1032 |
<ul>
|
1047 |
</ul>
|
1048 |
<p>= 2.5.0 =</p>
|
1049 |
<ul>
|
1050 |
+
<li>FEATURE: Two-Factor Authenticated Login using <a href="https://shsec.io/4i">Yubikey</a> One Time Passwords (OTP).</li>
|
1051 |
</ul>
|
1052 |
<p>= 2.4.3 =</p>
|
1053 |
<ul>
|
1056 |
</ul>
|
1057 |
<p>= 2.4.2 =</p>
|
1058 |
<ul>
|
1059 |
+
<li>ADDED: Contextual help links for many options. More to come...</li>
|
1060 |
<li>ADDED: More Portuguese (Brazil) translations (~80%)</li>
|
1061 |
</ul>
|
1062 |
<p>= 2.4.1 =</p>
|
1064 |
<li>ADDED: More strings to the translation set for better multilingual support</li>
|
1065 |
<li>ADDED: Portuguese (Brazil) translations (~40%)</li>
|
1066 |
<li>UPDATED: Hebrew Translations</li>
|
1067 |
+
<li>FIXED: Automatic cleaning of database logs wasn't actually working as expected. Should now be fixed.</li>
|
1068 |
</ul>
|
1069 |
<p>= 2.4.0 =</p>
|
1070 |
<ul>
|
1079 |
<ul>
|
1080 |
<li>ADDED: Hebrew Translations. Thanks <a href="http://atar4u.com">Ahrale</a>!</li>
|
1081 |
<li>ADDED: Automatic trimming of the Firewall access log to 7 days - it just grows too large otherwise.</li>
|
1082 |
+
<li>FIX: The previously added automatic clean up of old comments and login protect database entries was wiping out the valid login protect<pre><code> entries <span class="hljs-keyword">and</span> was forcing users <span class="hljs-keyword">to</span> re-login <span class="hljs-keyword">every</span> <span class="hljs-number">24</span>hrs.
|
1083 |
+
</code></pre></li>
|
1084 |
<li>FIX: Some small bugs, errors, and PHPDoc Comments.</li>
|
1085 |
</ul>
|
1086 |
<p>= 2.3.2 =</p>
|
1087 |
<ul>
|
1088 |
+
<li>ADDED: Automatic cleaning of GASP Comments Filter and Login Protection database entries (older than 24hrs) using WordPress Cron (everyday @ 6am)</li>
|
1089 |
<li>CHANGED: Huge code refactoring to allow for more easily use with other WordPress plugins.</li>
|
1090 |
</ul>
|
1091 |
<p>= 2.2.5 =</p>
|
1092 |
<ul>
|
1093 |
+
<li>ADDED: Email sending options for automatic update notifications - options to change the notification email address, or turn it off completely.</li>
|
1094 |
</ul>
|
1095 |
<p>= 2.2.4 =</p>
|
1096 |
<ul>
|
1097 |
<li>FIX: Small bug fix.</li>
|
1098 |
+
<li>CHANGED: When running a force automatic updates process, tries to remove influence from other plugins and uses only this plugin's automatic updates settings.</li>
|
1099 |
<li>CHANGED: A bit of automatic updates code refactoring.</li>
|
1100 |
</ul>
|
1101 |
<p>= 2.2.2 =</p>
|
1105 |
</ul>
|
1106 |
<p>= 2.2.1 =</p>
|
1107 |
<ul>
|
1108 |
+
<li>ADDED: Verified compatibility with WordPress 3.8</li>
|
1109 |
</ul>
|
1110 |
<p>= 2.2.0 =</p>
|
1111 |
<ul>
|
1115 |
</ul>
|
1116 |
<p>= 2.1.5 =</p>
|
1117 |
<ul>
|
1118 |
+
<li>IMPROVED: Improved logic for Firewall whitelisting for pages and parameters to ensure whitelisting rules are followed.</li>
|
1119 |
+
<li>CHANGED: The whitelisting rule for posting pages/posts is only for the "content" and the firewall checking will apply to all other page parameters.</li>
|
1120 |
</ul>
|
1121 |
<p>= 2.1.4 =</p>
|
1122 |
<ul>
|
1126 |
<ul>
|
1127 |
<li>FIX: A bug that prevented auto-updates of this plugin.</li>
|
1128 |
<li>FIX: Not being able to hide translations and upgrade notices.</li>
|
1129 |
+
<li>ADDED: Tweaks to auto-update feature to allow interfacing with the iControlWP service to customize the auto update system.</li>
|
1130 |
</ul>
|
1131 |
<p>= 2.1.0 =</p>
|
1132 |
<ul>
|
1133 |
+
<li>ADDED: A button that lets you run the WordPress Automatic Updates process on-demand (so you don't have to wait for WordPress cron).</li>
|
1134 |
<li>CHANGED: The plugin now sets more options to be turned on by default when the plugin is first activated.</li>
|
1135 |
<li>CHANGED: A lot of optimizations and code refactoring.</li>
|
1136 |
</ul>
|
1137 |
<p>= 2.0.3 =</p>
|
1138 |
<ul>
|
1139 |
+
<li>FIX: Whoops, sorry, accidentally removed the option to toggle "disable file editing". It's back now.</li>
|
1140 |
</ul>
|
1141 |
<p>= 2.0.2 =</p>
|
1142 |
<ul>
|
1144 |
</ul>
|
1145 |
<p>= 2.0.1 =</p>
|
1146 |
<ul>
|
1147 |
+
<li>ADDED: Localization capabilities. All we need now are translators! <a href="http://translate.icontrolwp.com/">Go here to get started</a>.</li>
|
1148 |
+
<li>ADDED: Option to mask the WordPress version so the real version is never publicly visible.</li>
|
1149 |
</ul>
|
1150 |
<p>= 1.9.2 =</p>
|
1151 |
<ul>
|
1153 |
</ul>
|
1154 |
<p>= 1.9.1 =</p>
|
1155 |
<ul>
|
1156 |
+
<li>ADDED: Increased admin access security features - blocks the deactivation of itself if you're not authenticated fully with the plugin.</li>
|
1157 |
+
<li>ADDED: If you're not authenticated with the plugin, the plugin listing view wont have 'Deactivate' or 'Edit' links.</li>
|
1158 |
</ul>
|
1159 |
<p>= 1.9.0 =</p>
|
1160 |
<ul>
|
1161 |
+
<li>ADDED: New WordPress Automatic Updates Configuration settings</li>
|
1162 |
</ul>
|
1163 |
<p>= 1.8.2 =</p>
|
1164 |
<ul>
|
1165 |
+
<li>ADDED: Notification of available plugin upgrade is now an option under the 'Dashboard'</li>
|
1166 |
+
<li>CHANGED: Certain admin and upgrade notices now only appear when you're authenticated with the plugin (if this is enabled)</li>
|
1167 |
+
<li>FIXED: PHP Notice with undefined index.</li>
|
1168 |
</ul>
|
1169 |
<p>= 1.8.1 =</p>
|
1170 |
<ul>
|
1171 |
+
<li>ADDED: Feature- Access Key Restriction <a href="https://shsec.io/2s">more info</a>.</li>
|
1172 |
+
<li>ADDED: Feature- WordPress Lockdown. Currently only provides 1 option, but more to come.</li>
|
1173 |
</ul>
|
1174 |
<p>= 1.7.3 =</p>
|
1175 |
<ul>
|
1178 |
</ul>
|
1179 |
<p>= 1.7.1 =</p>
|
1180 |
<ul>
|
1181 |
+
<li>ADDED: Much more efficiency yet again in the loading/saving of the plugin options.</li>
|
1182 |
</ul>
|
1183 |
<p>= 1.7.0 =</p>
|
1184 |
<ul>
|
1185 |
+
<li>ADDED: Preliminary WordPress Multisite (WPMS/WPMU) Support.</li>
|
1186 |
+
<li>CHANGED: The Firewall now kicks in on the 'plugins_loaded' hook instead of as the actual firewall plugin is initialized (as a result<pre><code> <span class="hljs-keyword">of</span> WP Multisite support).
|
1187 |
+
</code></pre></li>
|
1188 |
</ul>
|
1189 |
<p>= 1.6.2 =</p>
|
1190 |
<ul>
|
1192 |
</ul>
|
1193 |
<p>= 1.6.1 =</p>
|
1194 |
<ul>
|
1195 |
+
<li>ADDED: Options to fully customize the text displayed by the GASP comments section.</li>
|
1196 |
+
<li>ADDED: Option to include logged-in users in the GASP Comments Filter.</li>
|
1197 |
</ul>
|
1198 |
<p>= 1.6.0 =</p>
|
1199 |
<ul>
|
1200 |
+
<li>ADDED: A new section - 'Comments Filtering' that will form the basis for filtering comments with SPAM etc.</li>
|
1201 |
+
<li>ADDED: Option to add enhanced GASP based comments filtering to prevent SPAM bots posting comments to your site.</li>
|
1202 |
</ul>
|
1203 |
<p>= 1.5.6 =</p>
|
1204 |
<ul>
|
1205 |
+
<li>IMPROVED: Whitelist/Blacklist IP range processing to better cater for ranges when saving, with more thorough checking.</li>
|
1206 |
+
<li>IMPROVED: Whitelist/Blacklist IP range processing for 32-bit systems.</li>
|
1207 |
+
<li>FIXED: A bug with Whitelist/Blacklist IP checking.</li>
|
1208 |
</ul>
|
1209 |
<p>= 1.5.5 =</p>
|
1210 |
<ul>
|
1211 |
+
<li>FIXED: Quite a few bugs fixed.</li>
|
1212 |
</ul>
|
1213 |
<p>= 1.5.4 =</p>
|
1214 |
<ul>
|
1215 |
+
<li>FIXED: Typo error.</li>
|
1216 |
</ul>
|
1217 |
<p>= 1.5.3 =</p>
|
1218 |
<ul>
|
1219 |
+
<li>FIXED: Some of the firewall processors were saving unnecessary data.</li>
|
1220 |
</ul>
|
1221 |
<p>= 1.5.2 =</p>
|
1222 |
<ul>
|
1223 |
<li>CHANGED: The method for finding the client IP address is more thorough, in a bid to work with Proxy servers etc.</li>
|
1224 |
+
<li>FIXED: PHP notice reported here: <a href="http://wordpress.org/support/topic/getting-errors-when-logged-in">http://wordpress.org/support/topic/getting-errors-when-logged-in</a></li>
|
1225 |
</ul>
|
1226 |
<p>= 1.5.1 =</p>
|
1227 |
<ul>
|
1228 |
+
<li>FIXED: Bug fix where IP address didn't show in email.</li>
|
1229 |
+
<li>FIXED: Attempt to fix problem where update message never hides.</li>
|
1230 |
</ul>
|
1231 |
<p>= 1.5.0 =</p>
|
1232 |
<ul>
|
1233 |
+
<li>ADDED: A new IP whitelist on the Login Protect that lets you by-pass login protect rules for given IP addresses.</li>
|
1234 |
<li>REMOVED: Firewall rule for wp-login.php and whitelisted IPs.</li>
|
1235 |
</ul>
|
1236 |
<p>= 1.4.2 =</p>
|
1237 |
<ul>
|
1238 |
+
<li>ADDED: The plugin now has an option to automatically upgrade itself when an update is detected - enabled by default.</li>
|
1239 |
</ul>
|
1240 |
<p>= 1.4.1 =</p>
|
1241 |
<ul>
|
1242 |
+
<li>ADDED: The plugin will now displays an admin notice when a plugin upgrade is available with a link to immediately update.</li>
|
1243 |
+
<li>ADDED: Plugin collision: removes the main hook by 'All In One WordPress Security'. No need to have both plugins running.</li>
|
1244 |
+
<li>ADDED: Improved Login Cooldown Feature- works more like email throttling as it now uses an extra filesystem-based level of protection.</li>
|
1245 |
+
<li>FIXED: Login Cooldown Feature didn't take effect in certain circumstances.</li>
|
1246 |
</ul>
|
1247 |
<p>= 1.4.0 =</p>
|
1248 |
<ul>
|
1249 |
+
<li>ADDED: All-new plugin options handling making them more efficient, easier to manage/update, using far fewer WordPress database options.</li>
|
1250 |
<li>CHANGED: Huge improvements on database calls and efficiency in loading plugin options.</li>
|
1251 |
+
<li>FIXED: Nonce implementation.</li>
|
1252 |
</ul>
|
1253 |
<p>= 1.3.2 =</p>
|
1254 |
<ul>
|
1255 |
+
<li>FIXED: Small compatibility issue with Quick Cache menu not showing.</li>
|
1256 |
</ul>
|
1257 |
<p>= 1.3.0 =</p>
|
1258 |
<ul>
|
1259 |
+
<li>ADDED: Email Throttle Feature - this will prevent you getting bombarded by 1000s of emails in case you're hit by a bot.</li>
|
1260 |
+
<li>ADDED: Another Firewall die() option. New option will print a message and uses the wp_die() function instead.</li>
|
1261 |
+
<li>ADDED: Refactored and improved the logging system (upgrading will delete your current logs!).</li>
|
1262 |
+
<li>ADDED: Option to separately log Login Protect features.</li>
|
1263 |
+
<li>ADDED: Option to by-pass 2-factor authentication in the case sending the verification email fails<pre><code> <span class="hljs-comment">(so you don't get locked out if your hosting doesn't support email!)</span>.
|
1264 |
+
</code></pre></li>
|
1265 |
<li>CHANGED: Login Protect checking now better logs out users immediately with a redirect.</li>
|
1266 |
+
<li>CHANGED: We now escape the log data being printed - just in case there's any HTML/JS etc in there we don't want.</li>
|
1267 |
<li>CHANGED: Optimized and cleaned a lot of the option caching code to improve reliability and performance (more to come).</li>
|
1268 |
</ul>
|
1269 |
<p>= 1.2.7 =</p>
|
1272 |
</ul>
|
1273 |
<p>= 1.2.6 =</p>
|
1274 |
<ul>
|
1275 |
+
<li>ADDED: Ability to import settings from WordPress Firewall 2 plugin options - note, doesn't import page and variables whitelisting.</li>
|
1276 |
<li>FIX: A reported bug - parameter values could also be arrays.</li>
|
1277 |
</ul>
|
1278 |
<p>= 1.2.5 =</p>
|
1279 |
<ul>
|
1280 |
+
<li>ADDED: New Feature - Option to add a checkbox that blocks automated SPAM Bots trying to log into your site.</li>
|
1281 |
+
<li>ADDED: Added a clear user message when they verify their 2-factor authentication.</li>
|
1282 |
<li>FIX: A few bugfixes and logic corrections.</li>
|
1283 |
</ul>
|
1284 |
<p>= 1.2.4 =</p>
|
1296 |
</ul>
|
1297 |
<p>= 1.2.1 =</p>
|
1298 |
<ul>
|
1299 |
+
<li>ADDED: New Feature - Login Wait Interval. To reduce the effectiveness of brute force login attacks, you can add an interval by<pre><code> which WordPress will <span class="hljs-built_in">wait</span> <span class="hljs-keyword">before</span> processing <span class="hljs-keyword">any</span> more login attempts <span class="hljs-keyword">on</span> <span class="hljs-title">a</span> <span class="hljs-title">site</span>.
|
1300 |
+
</code></pre></li>
|
1301 |
<li>CHANGED: Optimized some settings for performance.</li>
|
1302 |
<li>CHANGED: Cleaned up the UI when the Firewall / Login Protect features are disabled (more to come).</li>
|
1303 |
<li>CHANGED: Further code improvements (more to come).</li>
|
1304 |
</ul>
|
1305 |
<p>= 1.2.0 =</p>
|
1306 |
<ul>
|
1307 |
+
<li>ADDED: New Feature - <strong>Login Protect</strong>. Added 2-Factor Login Authentication for all users and their associated IP addresses.</li>
|
1308 |
<li>CHANGED: The method for processing the IP address lists is improved.</li>
|
1309 |
<li>CHANGED: Improved .htaccess rules (thanks MickeyRoush)</li>
|
1310 |
<li>CHANGED: Mailing method now uses WP_MAIL</li>
|
1311 |
+
<li>CHANGED: Lot's of code improvements.</li>
|
1312 |
</ul>
|
1313 |
<p>= 1.1.6 =</p>
|
1314 |
<ul>
|
1315 |
+
<li>ADDED: Option to include Cookies in the firewall checking.</li>
|
1316 |
</ul>
|
1317 |
<p>= 1.1.5 =</p>
|
1318 |
<ul>
|
1335 |
</ul>
|
1336 |
<p>= 1.1.1 =</p>
|
1337 |
<ul>
|
1338 |
+
<li>Fix: Block notification emails weren't showing the user-friendly IP Address format.</li>
|
1339 |
</ul>
|
1340 |
<p>= 1.1.0 =</p>
|
1341 |
<ul>
|
1342 |
+
<li>You can now specify IP ranges in whitelists and blacklists. To do this separate the start and end address with a hyphen (-) E.g. For everything between 1.2.3.4 and 1.2.3.10, you would do: 1.2.3.4-1.2.3.10</li>
|
1343 |
<li>You can now specify which email address to send the notification emails.</li>
|
1344 |
+
<li>You can now add a comment to IP addresses in the whitelist/blacklist. To do this, write your IP address then type a SPACE and write whatever you want (don't take a new line).</li>
|
1345 |
<li>You can now set to delete ALL firewall settings when you deactivate the plugin.</li>
|
1346 |
<li>Improved formatting of the firewall log.</li>
|
1347 |
</ul>
|
1353 |
<p>= 1.1.2 =</p>
|
1354 |
<ul>
|
1355 |
<li>CHANGED: Logging now has its own dedicated database table.</li>
|
1356 |
+
<li>Fix: Block notification emails weren't showing the user-friendly IP Address format.</li>
|
1357 |
+
<li>You can now specify IP ranges in whitelists and blacklists. To do this separate the start and end address with a hyphen (-) E.g. For everything between 1.2.3.4 and 1.2.3.10, you would do: 1.2.3.4-1.2.3.10</li>
|
1358 |
<li>You can now specify which email address to send the notification emails.</li>
|
1359 |
+
<li>You can now add a comment to IP addresses in the whitelist/blacklist. To do this, write your IP address then type a SPACE and write whatever you want (don't take a new line).</li>
|
1360 |
<li>You can now set to delete ALL firewall settings when you deactivate the plugin.</li>
|
1361 |
<li>Improved formatting of the firewall log.</li>
|
1362 |
+
</ul>
|
|
|
|
filesnotfound.php
CHANGED
@@ -1,12 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
foreach (
|
4 |
-
[
|
5 |
-
'ICWP_WPSF_FeatureHandler_Base',
|
6 |
-
'ICWP_WPSF_FeatureHandler_BaseWpsf',
|
7 |
-
'ICWP_WPSF_Processor_Base',
|
8 |
-
'ICWP_WPSF_Processor_BaseWpsf',
|
9 |
-
] as $sClass
|
10 |
) {
|
11 |
if ( !@class_exists( $sClass ) ) {
|
12 |
add_action( 'admin_notices', 'icwp_wpsf_checkfilesnotfound' );
|
1 |
<?php
|
2 |
|
3 |
foreach (
|
4 |
+
[ 'ICWP_WPSF_FeatureHandler_Base', 'ICWP_WPSF_FeatureHandler_BaseWpsf', ] as $sClass
|
|
|
|
|
|
|
|
|
|
|
5 |
) {
|
6 |
if ( !@class_exists( $sClass ) ) {
|
7 |
add_action( 'admin_notices', 'icwp_wpsf_checkfilesnotfound' );
|
icwp-plugin-controller.php
DELETED
@@ -1,25 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Copyright (c) 2019 One Dollar Plugin <support@onedollarplugin.com>
|
4 |
-
* All rights reserved.
|
5 |
-
* "Shield" (formerly WordPress Simple Firewall) is distributed under the GNU
|
6 |
-
* General Public License, Version 2, June 1991. Copyright (C) 1989, 1991 Free
|
7 |
-
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
8 |
-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
9 |
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
10 |
-
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
11 |
-
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
12 |
-
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
13 |
-
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
14 |
-
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
15 |
-
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
16 |
-
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
17 |
-
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
18 |
-
*/
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Class ICWP_WPSF_Plugin_Controller
|
22 |
-
* @deprecated 7.5
|
23 |
-
*/
|
24 |
-
class ICWP_WPSF_Plugin_Controller extends \FernleafSystems\Wordpress\Plugin\Shield\Controller\Controller {
|
25 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
icwp-wpsf.php
CHANGED
@@ -1,17 +1,17 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
* Plugin Name: Shield Security
|
4 |
-
* Plugin URI: https://
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
-
* Version: 8.
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
-
* Author:
|
10 |
-
* Author URI: https://
|
11 |
*/
|
12 |
|
13 |
/**
|
14 |
-
* Copyright (c) 2019
|
15 |
* All rights reserved.
|
16 |
* "Shield" (formerly WordPress Simple Firewall) is distributed under the GNU
|
17 |
* General Public License, Version 2, June 1991. Copyright (C) 1989, 1991 Free
|
1 |
<?php
|
2 |
/*
|
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: 8.4.4
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
+
* Author: Shield Security
|
10 |
+
* Author URI: https://shsec.io/bv
|
11 |
*/
|
12 |
|
13 |
/**
|
14 |
+
* Copyright (c) 2019 Shield Security <support@shieldsecurity.io>
|
15 |
* All rights reserved.
|
16 |
* "Shield" (formerly WordPress Simple Firewall) is distributed under the GNU
|
17 |
* General Public License, Version 2, June 1991. Copyright (C) 1989, 1991 Free
|
plugin-spec.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "8.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield",
|
@@ -75,23 +75,23 @@
|
|
75 |
"Name": "Shield",
|
76 |
"Description": "Ultimate WP Security Protection - Scans, 2FA, Firewall, SPAM, Audit Trail, Security Admin, and so much more.",
|
77 |
"Title": "Shield Security",
|
78 |
-
"Author": "
|
79 |
-
"AuthorName": "
|
80 |
-
"PluginURI": "https://
|
81 |
-
"AuthorURI": "https://
|
82 |
"icon_url_16x16": "pluginlogo_16x16.png",
|
83 |
"icon_url_32x32": "pluginlogo_32x32.png",
|
84 |
"icon_url_128x128": "pluginlogo_128x128.png"
|
85 |
},
|
86 |
"meta": {
|
87 |
-
"url_repo_home": "https://
|
88 |
"headway_changelog_id": "xaoEZJ",
|
89 |
-
"privacy_policy_href": "https://
|
90 |
},
|
91 |
"plugin_meta": [
|
92 |
{
|
93 |
"name": "5✩ Rate This Plugin",
|
94 |
-
"href": "https://
|
95 |
}
|
96 |
],
|
97 |
"action_links": {
|
@@ -107,7 +107,7 @@
|
|
107 |
{
|
108 |
"name": "↑ Go Pro ↑",
|
109 |
"title": "For just $1/month. Seriously.",
|
110 |
-
"href": "https://
|
111 |
"target": "_blank",
|
112 |
"highlight": true,
|
113 |
"show": "free"
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "8.4.4",
|
4 |
+
"release_timestamp": 1575630000,
|
5 |
+
"build": "201912.0601",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield",
|
75 |
"Name": "Shield",
|
76 |
"Description": "Ultimate WP Security Protection - Scans, 2FA, Firewall, SPAM, Audit Trail, Security Admin, and so much more.",
|
77 |
"Title": "Shield Security",
|
78 |
+
"Author": "Shield Security",
|
79 |
+
"AuthorName": "Shield Security",
|
80 |
+
"PluginURI": "https://shsec.io/2f",
|
81 |
+
"AuthorURI": "https://shsec.io/bv",
|
82 |
"icon_url_16x16": "pluginlogo_16x16.png",
|
83 |
"icon_url_32x32": "pluginlogo_32x32.png",
|
84 |
"icon_url_128x128": "pluginlogo_128x128.png"
|
85 |
},
|
86 |
"meta": {
|
87 |
+
"url_repo_home": "https://shsec.io/eh",
|
88 |
"headway_changelog_id": "xaoEZJ",
|
89 |
+
"privacy_policy_href": "https://shsec.io/shieldprivacypolicy"
|
90 |
},
|
91 |
"plugin_meta": [
|
92 |
{
|
93 |
"name": "5✩ Rate This Plugin",
|
94 |
+
"href": "https://shsec.io/wpsf29"
|
95 |
}
|
96 |
],
|
97 |
"action_links": {
|
107 |
{
|
108 |
"name": "↑ Go Pro ↑",
|
109 |
"title": "For just $1/month. Seriously.",
|
110 |
+
"href": "https://shsec.io/d8",
|
111 |
"target": "_blank",
|
112 |
"highlight": true,
|
113 |
"show": "free"
|
readme.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
-
=== Shield Security: Protection with Smarter Automation ===
|
2 |
Contributors: onedollarplugin, paultgoodchild
|
3 |
-
Donate link: https://
|
4 |
License: GPLv3
|
5 |
License URI: http://www.gnu.org/licenses/gpl.html
|
6 |
Tags: scan, malware, firewall, two factor authentication, login protection
|
@@ -8,7 +8,7 @@ Requires at least: 3.5.2
|
|
8 |
Requires PHP: 5.4.0
|
9 |
Recommended PHP: 7.0
|
10 |
Tested up to: 5.3
|
11 |
-
Stable tag: 8.
|
12 |
|
13 |
Smarter security protection from hackers through automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
|
14 |
|
@@ -18,7 +18,7 @@ Smarter security protection from hackers through automation. Powerful scanners,
|
|
18 |
|
19 |
Shield - highest average 5* rating for any WordPress security plugin (2019/05). [See what people are saying here](https://wordpress.org/support/plugin/wp-simple-firewall/reviews/?filter=5).
|
20 |
|
21 |
-
#### It's
|
22 |
|
23 |
You don't need another 100 email notifications.
|
24 |
|
@@ -107,9 +107,9 @@ From November 2017, Shield Security now has a Pro version for those that need to
|
|
107 |
### Dedicated Premium Support
|
108 |
|
109 |
The Shield Security team prioritises email technical support over the WordPress.org forums.
|
110 |
-
Individual, dedicated technical support is only available to customers who have [purchased Shield Pro](https://
|
111 |
|
112 |
-
|
113 |
|
114 |
= Our Mission =
|
115 |
|
@@ -136,19 +136,19 @@ downloading and installing Shield now
|
|
136 |
* Exclusive membership to a private security group where you can learn more about WordPress security.
|
137 |
|
138 |
= Super Admin Security Protection =
|
139 |
-
The **only** WordPress security plugin with a WordPress-independent security key to protect itself. [more info](https://
|
140 |
|
141 |
= Audit Trail Activity Monitor =
|
142 |
With the Audit Trail you can review all major actions that have taken place on your WordPress site, by all users.
|
143 |
|
144 |
= Firewall Protection =
|
145 |
-
Blocks all web requests to the site that violate the firewall security rules! [more info](https://
|
146 |
|
147 |
= Brute Force Login Guard and Two-Factor Authentication =
|
148 |
-
Provides effective security against Brute Force Hacking and email based Two-Factor Authenticated login. [more info](https://
|
149 |
|
150 |
= Comment SPAM (Full replacement and upgrade from Akismet) =
|
151 |
-
Blocks **ALL** automatic Bot-SPAM, and catches Human Comments SPAM without sending data to 3rd parties or charging subscription fees. [more info](https://
|
152 |
|
153 |
= FABLE - Fully Automatic Black Listing Engine =
|
154 |
No more manual IP Black lists. This plugin handles the blocking of IP addresses for hosts that are naughty.
|
@@ -172,9 +172,9 @@ and force users to verify themselves when they login.
|
|
172 |
|
173 |
Three core security features provide layers to protect the WordPress Login system.
|
174 |
|
175 |
-
1. [Email-based 2-Factor Login Authentication](https://
|
176 |
-
1. [Login Cooldown Interval](https://
|
177 |
-
1. [GASP Anti-Bot Login Form Protection](https://
|
178 |
|
179 |
These options alone will protect and secure your WordPress sites from nearly all forms of Brute Force login attacks.
|
180 |
|
@@ -227,7 +227,7 @@ A new menu item will appear on the left-hand side called 'Shield'.
|
|
227 |
|
228 |
== Frequently Asked Questions ==
|
229 |
|
230 |
-
Please see the dedicated [help centre](https://
|
231 |
|
232 |
= How does the Shield compare with other WordPress Security Plugins? =
|
233 |
|
@@ -318,15 +318,15 @@ When enabled the plugin will prevent more than 1 login attempt to your site ever
|
|
318 |
of 60 seconds, only 1 login attempt will be processed every 60 seconds. If you login incorrectly, you wont be able to attempt another
|
319 |
login for a further 60 seconds.
|
320 |
|
321 |
-
More Info: https://
|
322 |
|
323 |
= How does the GASP Login Guard work? =
|
324 |
|
325 |
-
This is best [described on the blog](https://
|
326 |
|
327 |
= How does the 2-factor authentication work? =
|
328 |
|
329 |
-
[2-Factor Authentication is best described here](https://
|
330 |
|
331 |
= I'm getting an update message although I have auto update enabled? =
|
332 |
|
@@ -368,101 +368,24 @@ You'll also have access to our email technical support team.
|
|
368 |
|
369 |
You will always be able to use Shield Security and its free features in-full.
|
370 |
|
371 |
-
[Go Pro for just $1/month](https://
|
372 |
-
|
373 |
-
= 8.
|
374 |
-
*Released:
|
375 |
-
|
376 |
-
* **(v.
|
377 |
-
* **(v.
|
378 |
-
|
379 |
-
|
380 |
-
*
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
*
|
385 |
-
|
386 |
-
* **(v.
|
387 |
-
* **(v.
|
388 |
-
* **(v.
|
389 |
-
* **(v.
|
390 |
-
|
391 |
-
|
392 |
-
* **(v.2)** IMPROVED: Server's own IP address detection when site migrated to a new host.
|
393 |
-
* **(v.2)** UPDATED: International translations.
|
394 |
-
* **(v.2)** FIXED: PHP notices when data wasn't as expected.
|
395 |
-
* **(v.1)** IMPROVED: Further reduce Malware false positives by also using SVN trunk data when verifying files for plugins and themes.
|
396 |
-
* **(v.1)** ADDED: Initial support for repairing Themes that have been installed from WordPress.org.
|
397 |
-
* **(v.1)** ADDED: Support for using [WP Hashes.com](https://wphashes.com) for WordPress.org themes (already done for plugins).
|
398 |
-
* **(v.1)** FIXED: PHP notices in the logs.
|
399 |
-
* **(v.0)** IMPROVED: [**PRO**] Malware scanner now uses network intelligence to the gather information on malware results.
|
400 |
-
* **(v.0)** NEW: Traffic Watcher feature is now free for all users (no longer Pro-only).
|
401 |
-
* **(v.0)** IMPROVED: Scanning cron is improved and more efficient.
|
402 |
-
* **(v.0)** ADDED: Bulk Delete/Repair/Ignore actions now available for Malware scan results.
|
403 |
-
* **(v.0)** IMPROVED: Malware scan results now provide details of affected line numbers and patterns discovered.
|
404 |
-
* **(v.0)** IMPROVED: Malware scanner only scans `wp-admin`, `wp-includes`, `wp-content` folders, and files in top-level directory.
|
405 |
-
* **(v.0)** IMPROVED: Malware scanner now excludes `wp-content/cache/` directory.
|
406 |
-
* **(v.0)** IMPROVED: Malware scanner performance improved with caching.
|
407 |
-
* **(v.0)** IMPROVED: Malware auto-repair now works more consistently.
|
408 |
-
* **(v.0)** IMPROVED: Updated default firewall whitelist rules.
|
409 |
-
* **(v.0)** IMPROVED: If the PWNED Passwords API request fails entirely, the password check is skipped.
|
410 |
-
* **(v.0)** ADDED: Japanese translations are at 100%.
|
411 |
-
* **(v.0)** IMPROVED: Dutch translations are greatly improved (a huge thank you to Fred!).
|
412 |
-
* **(v.0)** FIXED: Audit Trail correctly logs multiple occurrences for the same type of event on the same page request.
|
413 |
-
* **(v.0)** FIXED: Audit Trail now correctly logs Google reCAPTCHA failure events.
|
414 |
-
* **(v.0)** FIXED: PHP error when firewall was set to kill response without a user message.
|
415 |
-
|
416 |
-
= 8.1 - Series =
|
417 |
-
*Released: 18th September, 2019* - [Release Notes](https://icwp.io/fy)
|
418 |
-
|
419 |
-
* **(v.1)** FIXED: Error for sites pre-5.0 that don't have function `determine_locale()`
|
420 |
-
* **(v.0)** IMPROVED: Massive improvements to asynchronous scans in performance and reliability.
|
421 |
-
* **(v.0)** ADDED: [**PRO**] Possible to supply multiple email addresses for Administrator login notifications.
|
422 |
-
* **(v.0)** ADDED: New firewall whitelist rule to prevent firewall blocks when activating certain plugins.
|
423 |
-
* **(v.0)** IMPROVED: Prevent errors caused by other plugins not passing correctly-formatted data through WP filters.
|
424 |
-
* **(v.0)** ADDED: Japanese translations (14%).
|
425 |
-
* **(v.0)** IMPROVED: Plugin locale now respects user profile locale setting.
|
426 |
-
* **(v.0)** IMPROVED: Audit Trail filter for specific events.
|
427 |
-
* **(v.0)** IMPROVED: Lots of cleanup of deprecated PHP code following the the v7-v8 upgrade.
|
428 |
-
|
429 |
-
= 8.0 - Series =
|
430 |
-
*Released: 27th August, 2019* - [Release Notes](https://icwp.io/fv)
|
431 |
-
|
432 |
-
* **(v.2)** IMPROVED: Password strength metering now better aligns with WordPress library (PHP 5.6+)
|
433 |
-
* **(v.2)** IMPROVED: Dutch translations have been adjusted.
|
434 |
-
* **(v.2)** FIXED: Setting 'Month' for IP block duration wasn't being applied.
|
435 |
-
* **(v.2)** FIXED: Certain admin notices not displayed when they should be.
|
436 |
-
* **(v.1)** FIXED: Comment SPAM blocking wasn't working if set to "Detect and Reject".
|
437 |
-
* **(v.1)** FIXED: Shield Widget/Badge broken in some cases.
|
438 |
-
* **(v.1)** ADDED: You can force Shield to operate in any [locale, regardless of site locale](https://icwp.io/gistshieldlocale).
|
439 |
-
* **(v.1)** ADDED: Russian translations are now at 100% and some Dutch translations have been adjusted.
|
440 |
-
* **(v.0)** NEW: [**PRO**] New Malware Scanner with automated file repair for WordPress.org Plugins and Core.
|
441 |
-
* **(v.0)** NEW: Complete overhaul of events system to better audit and collect statistics.
|
442 |
-
* **(v.0)** IMPROVED: Asynchronous scans - scans run in the background and so support more restrictive hosting.
|
443 |
-
* **(v.0)** IMPROVED: Plugin notification system is much improved.
|
444 |
-
* **(v.0)** IMPROVED: [**PRO**] Plugin Guard uses SVN repositories for file references [via WP Hashes API](https://icwp.io/fw).
|
445 |
-
* **(v.0)** CHANGED: Comment SPAM system now uses WordPress Transients API instead of dedicated DB table.
|
446 |
-
* **(v.0)** ADDED: 100% Translation coverage for French, Spanish, German, Portuguese, Serbian, Bosnian, Dutch. (Russian on the way)
|
447 |
-
* **(v.0)** CHANGED: Major code cleaning/refactoring for much of the plugin. More to come.
|
448 |
-
|
449 |
-
= 7.4 - Series =
|
450 |
-
*Released: 13th May, 2019* - [Release Notes](https://icwp.io/fc)
|
451 |
-
|
452 |
-
* **(v.2)** NEW: Options finder/jumper menu lets you find and jump to any option in the plugin instantly.
|
453 |
-
* **(v.2)** NEW: Help/explainer videos for a few sections - more to come.
|
454 |
-
* **(v.2)** FIXES: Fixes for a few problems introduced with the recent UI changes.
|
455 |
-
* **(v.2)** FIXED: Welcome wizard launching was broken.
|
456 |
-
* **(v.1)** NEW: Adjustments and redesign of Shield options pages.
|
457 |
-
* **(v.1)** IMPROVED: Further prep for better internationalization.
|
458 |
-
* **(v.0)** NEW: [**PRO**] [Manual/Automatic User Suspension](https://icwp.io/fa)
|
459 |
-
* **(v.0)** NEW: Comment SPAM - Increase minimum number of approved comments before scanning is skipped
|
460 |
-
* **(v.0)** NEW: [**PRO**] Comment SPAM - Trusted user roles where comments scanning is skipped
|
461 |
-
* **(v.0)** IMPROVED: AntiBot JS was improperly included when not required.
|
462 |
-
* **(v.0)** IMPROVED: Added a GeoIP caching table and removed bundled GeoIP database - greatly reduces download size.
|
463 |
-
* **(v.0)** FIXED: Inconsistent behaviour when PWA plugin is active and it infinitely reloads pages.
|
464 |
-
* **(v.0)** FIXED: Inconsistent behaviour with Anonymous API blocking.
|
465 |
-
* **(v.0)** IMPROVED: Code improvements and refactoring.
|
466 |
-
* **(v.0)** ADDED: Prep for upcoming malware scanner.
|
467 |
-
|
468 |
-
#### [Full Changelog](https://icwp.io/shieldwporgfullchangelog)
|
1 |
+
=== Shield Security: Protection with Smarter Automation ===
|
2 |
Contributors: onedollarplugin, paultgoodchild
|
3 |
+
Donate link: https://shsec.io/bw
|
4 |
License: GPLv3
|
5 |
License URI: http://www.gnu.org/licenses/gpl.html
|
6 |
Tags: scan, malware, firewall, two factor authentication, login protection
|
8 |
Requires PHP: 5.4.0
|
9 |
Recommended PHP: 7.0
|
10 |
Tested up to: 5.3
|
11 |
+
Stable tag: 8.4.4
|
12 |
|
13 |
Smarter security protection from hackers through automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
|
14 |
|
18 |
|
19 |
Shield - highest average 5* rating for any WordPress security plugin (2019/05). [See what people are saying here](https://wordpress.org/support/plugin/wp-simple-firewall/reviews/?filter=5).
|
20 |
|
21 |
+
#### It's 2020 - Don't settle for just another security plugin. Get *smarter* security.
|
22 |
|
23 |
You don't need another 100 email notifications.
|
24 |
|
107 |
### Dedicated Premium Support
|
108 |
|
109 |
The Shield Security team prioritises email technical support over the WordPress.org forums.
|
110 |
+
Individual, dedicated technical support is only available to customers who have [purchased Shield Pro](https://shsec.io/ab).
|
111 |
|
112 |
+
Discover all the perks turning your security Pro at [our Shield Security store](https://shsec.io/ab).
|
113 |
|
114 |
= Our Mission =
|
115 |
|
136 |
* Exclusive membership to a private security group where you can learn more about WordPress security.
|
137 |
|
138 |
= Super Admin Security Protection =
|
139 |
+
The **only** WordPress security plugin with a WordPress-independent security key to protect itself. [more info](https://shsec.io/wpsf05)
|
140 |
|
141 |
= Audit Trail Activity Monitor =
|
142 |
With the Audit Trail you can review all major actions that have taken place on your WordPress site, by all users.
|
143 |
|
144 |
= Firewall Protection =
|
145 |
+
Blocks all web requests to the site that violate the firewall security rules! [more info](https://shsec.io/wpsf06)
|
146 |
|
147 |
= Brute Force Login Guard and Two-Factor Authentication =
|
148 |
+
Provides effective security against Brute Force Hacking and email based Two-Factor Authenticated login. [more info](https://shsec.io/wpsf07)
|
149 |
|
150 |
= Comment SPAM (Full replacement and upgrade from Akismet) =
|
151 |
+
Blocks **ALL** automatic Bot-SPAM, and catches Human Comments SPAM without sending data to 3rd parties or charging subscription fees. [more info](https://shsec.io/wpsf08)
|
152 |
|
153 |
= FABLE - Fully Automatic Black Listing Engine =
|
154 |
No more manual IP Black lists. This plugin handles the blocking of IP addresses for hosts that are naughty.
|
172 |
|
173 |
Three core security features provide layers to protect the WordPress Login system.
|
174 |
|
175 |
+
1. [Email-based 2-Factor Login Authentication](https://shsec.io/2v) based on IP address! (prevents brute force login attacks)
|
176 |
+
1. [Login Cooldown Interval](https://shsec.io/2t) - WordPress will only process 1 login per interval in seconds (prevents brute force login attacks)
|
177 |
+
1. [GASP Anti-Bot Login Form Protection](https://shsec.io/2u) - Adds 2 protection checks for all WordPress login attempts (prevents brute force login attacks using Bots)
|
178 |
|
179 |
These options alone will protect and secure your WordPress sites from nearly all forms of Brute Force login attacks.
|
180 |
|
227 |
|
228 |
== Frequently Asked Questions ==
|
229 |
|
230 |
+
Please see the dedicated [help centre](https://shsec.io/firewallhelp) for details on features and some FAQs.
|
231 |
|
232 |
= How does the Shield compare with other WordPress Security Plugins? =
|
233 |
|
318 |
of 60 seconds, only 1 login attempt will be processed every 60 seconds. If you login incorrectly, you wont be able to attempt another
|
319 |
login for a further 60 seconds.
|
320 |
|
321 |
+
More Info: https://shsec.io/2t
|
322 |
|
323 |
= How does the GASP Login Guard work? =
|
324 |
|
325 |
+
This is best [described on the blog](https://shsec.io/2u)
|
326 |
|
327 |
= How does the 2-factor authentication work? =
|
328 |
|
329 |
+
[2-Factor Authentication is best described here](https://shsec.io/2v).
|
330 |
|
331 |
= I'm getting an update message although I have auto update enabled? =
|
332 |
|
368 |
|
369 |
You will always be able to use Shield Security and its free features in-full.
|
370 |
|
371 |
+
[Go Pro for just $1/month](https://shsec.io/aa).
|
372 |
+
|
373 |
+
= 8.4.4 - Current Release =
|
374 |
+
*Released: 6th December, 2019* - [Release Notes](https://shsec.io/g5)
|
375 |
+
|
376 |
+
* **(v.4)** IMPROVED: Discovered serious conflict with SiteGround Optimizer plugin. Provided admin notice and automatic fixing.
|
377 |
+
* **(v.4)** FIXED: Protected against spurious error log notices when comparing hashes with "nothing".
|
378 |
+
|
379 |
+
= 8.4 - Series =
|
380 |
+
*Released: 29th November, 2019* - [Release Notes](https://shsec.io/g5)
|
381 |
+
|
382 |
+
* **(v.3)** FIXED: Reduce chances of fatal error occurring during upgrade.
|
383 |
+
* **(v.0)** ADDED: Charts of important events on Overview page highlight effectiveness of Shield.
|
384 |
+
* **(v.0)** ADDED: Support for whitelisting IPv6 ranges.
|
385 |
+
* **(v.0)** ADDED: Allow Audit Trail logging for Shield's Bot Detection features for all free installations.
|
386 |
+
* **(v.0)** IMPROVED: Malware scanner false-positive lookups now use further intelligence from API.
|
387 |
+
* **(v.0)** IMPROVED: Refactor Comment SPAM implementation away from inline-Javascript.
|
388 |
+
* **(v.0)** IMPROVED: Consolidate Events/Statistics database table to significantly reduce DB size.
|
389 |
+
* **(v.0)** CLEANED: Significant clean-out of old, deprecated, retired code.
|
390 |
+
|
391 |
+
#### [Full Shield Security Changelog](https://shsec.io/shieldwporgfullchangelog)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resources/css/chartist.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.ct-double-octave:after,.ct-major-eleventh:after,.ct-major-second:after,.ct-major-seventh:after,.ct-major-sixth:after,.ct-major-tenth:after,.ct-major-third:after,.ct-major-twelfth:after,.ct-minor-second:after,.ct-minor-seventh:after,.ct-minor-sixth:after,.ct-minor-third:after,.ct-octave:after,.ct-perfect-fifth:after,.ct-perfect-fourth:after,.ct-square:after{content:"";clear:both}.ct-label{fill:rgba(0,0,0,.4);color:rgba(0,0,0,.4);font-size:.75rem;line-height:1}.ct-grid-background,.ct-line{fill:none}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.ct-chart-donut .ct-label,.ct-chart-pie .ct-label{dominant-baseline:central}.ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-vertical.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-donut-solid,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-donut-solid,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-donut-solid,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-donut-solid,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-donut-solid,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-donut-solid,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-donut-solid,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-donut-solid,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-donut-solid,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-donut-solid,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-donut-solid,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-donut-solid,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-donut-solid,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-donut-solid,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-donut-solid,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-square:after{display:table}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-minor-second:after{display:table}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-major-second:after{display:table}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-minor-third:after{display:table}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-major-third:after{display:table}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-perfect-fourth:after{display:table}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{display:table}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{display:table}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-golden-section:after{content:"";display:table;clear:both}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-major-sixth:after{display:table}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-minor-seventh:after{display:table}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{display:table}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-octave:after{display:table}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-major-tenth:after{display:table}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-major-eleventh:after{display:table}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{display:table}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-double-octave:after{display:table}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0}
|
1 |
+
.ct-double-octave:after,.ct-golden-section:after,.ct-major-eleventh:after,.ct-major-second:after,.ct-major-seventh:after,.ct-major-sixth:after,.ct-major-tenth:after,.ct-major-third:after,.ct-major-twelfth:after,.ct-minor-second:after,.ct-minor-seventh:after,.ct-minor-sixth:after,.ct-minor-third:after,.ct-octave:after,.ct-perfect-fifth:after,.ct-perfect-fourth:after,.ct-square:after{content:"";clear:both}.ct-label{fill:rgba(0,0,0,.4);color:rgba(0,0,0,.4);font-size:.75rem;line-height:1}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.ct-chart-donut .ct-label,.ct-chart-pie .ct-label{dominant-baseline:central}.ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-vertical.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-grid-background{fill:none}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{fill:none;stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-donut-solid,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-donut-solid,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-donut-solid,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-donut-solid,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-donut-solid,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-donut-solid,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-donut-solid,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-donut-solid,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-donut-solid,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-donut-solid,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-donut-solid,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-donut-solid,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-donut-solid,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-donut-solid,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-donut-solid,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-square:after{display:table}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-minor-second:after{display:table}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-major-second:after{display:table}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-minor-third:after{display:table}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-major-third:after{display:table}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-perfect-fourth:after{display:table}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{display:table}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{display:table}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-golden-section:after{display:table}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-major-sixth:after{display:table}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-minor-seventh:after{display:table}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{display:table}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-octave:after{display:table}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-major-tenth:after{display:table}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-major-eleventh:after{display:table}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{display:table}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-double-octave:after{display:table}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0}
|
resources/css/plugin.css
CHANGED
@@ -934,14 +934,13 @@ td.cell_delete_note {
|
|
934 |
}
|
935 |
|
936 |
#SectionStats {
|
937 |
-
max-height: 300px;
|
938 |
overflow: auto;
|
939 |
}
|
940 |
.stat.card {
|
941 |
}
|
942 |
.stat.card .card-header {
|
943 |
font-size: smaller;
|
944 |
-
white-space: nowrap
|
945 |
}
|
946 |
.stat.card .card-body {
|
947 |
font-size: x-large;
|
934 |
}
|
935 |
|
936 |
#SectionStats {
|
|
|
937 |
overflow: auto;
|
938 |
}
|
939 |
.stat.card {
|
940 |
}
|
941 |
.stat.card .card-header {
|
942 |
font-size: smaller;
|
943 |
+
/*white-space: nowrap;*/
|
944 |
}
|
945 |
.stat.card .card-body {
|
946 |
font-size: x-large;
|
resources/js/chartist.min.js
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
-
/* Chartist.js 0.11.
|
2 |
* Copyright © 2019 Gion Kunz
|
3 |
* Free to use under either the WTFPL license or the MIT license.
|
4 |
* https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-WTFPL
|
5 |
* https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-MIT
|
6 |
*/
|
7 |
|
8 |
-
!function(a,b){"function"==typeof define&&define.amd?define("Chartist",[],function(){return a.Chartist=b()}):"object"==typeof module&&module.exports?module.exports=b():a.Chartist=b()}(this,function(){var a={version:"0.11.3"};return function(a,b){"use strict";var c=a.window,d=a.document;b.namespaces={svg:"http://www.w3.org/2000/svg",xmlns:"http://www.w3.org/2000/xmlns/",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",ct:"http://gionkunz.github.com/chartist-js/ct"},b.noop=function(a){return a},b.alphaNumerate=function(a){return String.fromCharCode(97+a%26)},b.extend=function(a){var c,d,e;for(a=a||{},c=1;c<arguments.length;c++){d=arguments[c];for(var f in d)e=d[f],"object"!=typeof e||null===e||e instanceof Array?a[f]=e:a[f]=b.extend(a[f],e)}return a},b.replaceAll=function(a,b,c){return a.replace(new RegExp(b,"g"),c)},b.ensureUnit=function(a,b){return"number"==typeof a&&(a+=b),a},b.quantity=function(a){if("string"==typeof a){var b=/^(\d+)\s*(.*)$/g.exec(a);return{value:+b[1],unit:b[2]||void 0}}return{value:a}},b.querySelector=function(a){return a instanceof Node?a:d.querySelector(a)},b.times=function(a){return Array.apply(null,new Array(a))},b.sum=function(a,b){return a+(b?b:0)},b.mapMultiply=function(a){return function(b){return b*a}},b.mapAdd=function(a){return function(b){return b+a}},b.serialMap=function(a,c){var d=[],e=Math.max.apply(null,a.map(function(a){return a.length}));return b.times(e).forEach(function(b,e){var f=a.map(function(a){return a[e]});d[e]=c.apply(null,f)}),d},b.roundWithPrecision=function(a,c){var d=Math.pow(10,c||b.precision);return Math.round(a*d)/d},b.precision=8,b.escapingMap={"&":"&","<":"<",">":">",'"':""","'":"'"},b.serialize=function(a){return null===a||void 0===a?a:("number"==typeof a?a=""+a:"object"==typeof a&&(a=JSON.stringify({data:a})),Object.keys(b.escapingMap).reduce(function(a,c){return b.replaceAll(a,c,b.escapingMap[c])},a))},b.deserialize=function(a){if("string"!=typeof a)return a;a=Object.keys(b.escapingMap).reduce(function(a,c){return b.replaceAll(a,b.escapingMap[c],c)},a);try{a=JSON.parse(a),a=void 0!==a.data?a.data:a}catch(c){}return a},b.createSvg=function(a,c,d,e){var f;return c=c||"100%",d=d||"100%",Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function(a){return a.getAttributeNS(b.namespaces.xmlns,"ct")}).forEach(function(b){a.removeChild(b)}),f=new b.Svg("svg").attr({width:c,height:d}).addClass(e),f._node.style.width=c,f._node.style.height=d,a.appendChild(f._node),f},b.normalizeData=function(a,c,d){var e,f={raw:a,normalized:{}};return f.normalized.series=b.getDataArray({series:a.series||[]},c,d),e=f.normalized.series.every(function(a){return a instanceof Array})?Math.max.apply(null,f.normalized.series.map(function(a){return a.length})):f.normalized.series.length,f.normalized.labels=(a.labels||[]).slice(),Array.prototype.push.apply(f.normalized.labels,b.times(Math.max(0,e-f.normalized.labels.length)).map(function(){return""})),c&&b.reverseData(f.normalized),f},b.safeHasProperty=function(a,b){return null!==a&&"object"==typeof a&&a.hasOwnProperty(b)},b.isDataHoleValue=function(a){return null===a||void 0===a||"number"==typeof a&&isNaN(a)},b.reverseData=function(a){a.labels.reverse(),a.series.reverse();for(var b=0;b<a.series.length;b++)"object"==typeof a.series[b]&&void 0!==a.series[b].data?a.series[b].data.reverse():a.series[b]instanceof Array&&a.series[b].reverse()},b.getDataArray=function(a,c,d){function e(a){if(b.safeHasProperty(a,"value"))return e(a.value);if(b.safeHasProperty(a,"data"))return e(a.data);if(a instanceof Array)return a.map(e);if(!b.isDataHoleValue(a)){if(d){var c={};return"string"==typeof d?c[d]=b.getNumberOrUndefined(a):c.y=b.getNumberOrUndefined(a),c.x=a.hasOwnProperty("x")?b.getNumberOrUndefined(a.x):c.x,c.y=a.hasOwnProperty("y")?b.getNumberOrUndefined(a.y):c.y,c}return b.getNumberOrUndefined(a)}}return a.series.map(e)},b.normalizePadding=function(a,b){return b=b||0,"number"==typeof a?{top:a,right:a,bottom:a,left:a}:{top:"number"==typeof a.top?a.top:b,right:"number"==typeof a.right?a.right:b,bottom:"number"==typeof a.bottom?a.bottom:b,left:"number"==typeof a.left?a.left:b}},b.getMetaData=function(a,b){var c=a.data?a.data[b]:a[b];return c?c.meta:void 0},b.orderOfMagnitude=function(a){return Math.floor(Math.log(Math.abs(a))/Math.LN10)},b.projectLength=function(a,b,c){return b/c.range*a},b.getAvailableHeight=function(a,c){return Math.max((b.quantity(c.height).value||a.height())-(c.chartPadding.top+c.chartPadding.bottom)-c.axisX.offset,0)},b.getHighLow=function(a,c,d){function e(a){if(void 0!==a)if(a instanceof Array)for(var b=0;b<a.length;b++)e(a[b]);else{var c=d?+a[d]:+a;g&&c>f.high&&(f.high=c),h&&c<f.low&&(f.low=c)}}c=b.extend({},c,d?c["axis"+d.toUpperCase()]:{});var f={high:void 0===c.high?-Number.MAX_VALUE:+c.high,low:void 0===c.low?Number.MAX_VALUE:+c.low},g=void 0===c.high,h=void 0===c.low;return(g||h)&&e(a),(c.referenceValue||0===c.referenceValue)&&(f.high=Math.max(c.referenceValue,f.high),f.low=Math.min(c.referenceValue,f.low)),f.high<=f.low&&(0===f.low?f.high=1:f.low<0?f.high=0:f.high>0?f.low=0:(f.high=1,f.low=0)),f},b.isNumeric=function(a){return null!==a&&isFinite(a)},b.isFalseyButZero=function(a){return!a&&0!==a},b.getNumberOrUndefined=function(a){return b.isNumeric(a)?+a:void 0},b.isMultiValue=function(a){return"object"==typeof a&&("x"in a||"y"in a)},b.getMultiValue=function(a,c){return b.isMultiValue(a)?b.getNumberOrUndefined(a[c||"y"]):b.getNumberOrUndefined(a)},b.rho=function(a){function b(a,c){return a%c===0?c:b(c,a%c)}function c(a){return a*a+1}if(1===a)return a;var d,e=2,f=2;if(a%2===0)return 2;do e=c(e)%a,f=c(c(f))%a,d=b(Math.abs(e-f),a);while(1===d);return d},b.getBounds=function(a,c,d,e){function f(a,b){return a===(a+=b)&&(a*=1+(b>0?o:-o)),a}var g,h,i,j=0,k={high:c.high,low:c.low};k.valueRange=k.high-k.low,k.oom=b.orderOfMagnitude(k.valueRange),k.step=Math.pow(10,k.oom),k.min=Math.floor(k.low/k.step)*k.step,k.max=Math.ceil(k.high/k.step)*k.step,k.range=k.max-k.min,k.numberOfSteps=Math.round(k.range/k.step);var l=b.projectLength(a,k.step,k),m=l<d,n=e?b.rho(k.range):0;if(e&&b.projectLength(a,1,k)>=d)k.step=1;else if(e&&n<k.step&&b.projectLength(a,n,k)>=d)k.step=n;else for(;;){if(m&&b.projectLength(a,k.step,k)<=d)k.step*=2;else{if(m||!(b.projectLength(a,k.step/2,k)>=d))break;if(k.step/=2,e&&k.step%1!==0){k.step*=2;break}}if(j++>1e3)throw new Error("Exceeded maximum number of iterations while optimizing scale step!")}var o=2.221e-16;for(k.step=Math.max(k.step,o),h=k.min,i=k.max;h+k.step<=k.low;)h=f(h,k.step);for(;i-k.step>=k.high;)i=f(i,-k.step);k.min=h,k.max=i,k.range=k.max-k.min;var p=[];for(g=k.min;g<=k.max;g=f(g,k.step)){var q=b.roundWithPrecision(g);q!==p[p.length-1]&&p.push(q)}return k.values=p,k},b.polarToCartesian=function(a,b,c,d){var e=(d-90)*Math.PI/180;return{x:a+c*Math.cos(e),y:b+c*Math.sin(e)}},b.createChartRect=function(a,c,d){var e=!(!c.axisX&&!c.axisY),f=e?c.axisY.offset:0,g=e?c.axisX.offset:0,h=a.width()||b.quantity(c.width).value||0,i=a.height()||b.quantity(c.height).value||0,j=b.normalizePadding(c.chartPadding,d);h=Math.max(h,f+j.left+j.right),i=Math.max(i,g+j.top+j.bottom);var k={padding:j,width:function(){return this.x2-this.x1},height:function(){return this.y1-this.y2}};return e?("start"===c.axisX.position?(k.y2=j.top+g,k.y1=Math.max(i-j.bottom,k.y2+1)):(k.y2=j.top,k.y1=Math.max(i-j.bottom-g,k.y2+1)),"start"===c.axisY.position?(k.x1=j.left+f,k.x2=Math.max(h-j.right,k.x1+1)):(k.x1=j.left,k.x2=Math.max(h-j.right-f,k.x1+1))):(k.x1=j.left,k.x2=Math.max(h-j.right,k.x1+1),k.y2=j.top,k.y1=Math.max(i-j.bottom,k.y2+1)),k},b.createGrid=function(a,c,d,e,f,g,h,i){var j={};j[d.units.pos+"1"]=a,j[d.units.pos+"2"]=a,j[d.counterUnits.pos+"1"]=e,j[d.counterUnits.pos+"2"]=e+f;var k=g.elem("line",j,h.join(" "));i.emit("draw",b.extend({type:"grid",axis:d,index:c,group:g,element:k},j))},b.createGridBackground=function(a,b,c,d){var e=a.elem("rect",{x:b.x1,y:b.y2,width:b.width(),height:b.height()},c,!0);d.emit("draw",{type:"gridBackground",group:a,element:e})},b.createLabel=function(a,c,e,f,g,h,i,j,k,l,m){var n,o={};if(o[g.units.pos]=a+i[g.units.pos],o[g.counterUnits.pos]=i[g.counterUnits.pos],o[g.units.len]=c,o[g.counterUnits.len]=Math.max(0,h-10),l){var p=d.createElement("span");p.className=k.join(" "),p.setAttribute("xmlns",b.namespaces.xhtml),p.innerText=f[e],p.style[g.units.len]=Math.round(o[g.units.len])+"px",p.style[g.counterUnits.len]=Math.round(o[g.counterUnits.len])+"px",n=j.foreignObject(p,b.extend({style:"overflow: visible;"},o))}else n=j.elem("text",o,k.join(" ")).text(f[e]);m.emit("draw",b.extend({type:"label",axis:g,index:e,group:j,element:n,text:f[e]},o))},b.getSeriesOption=function(a,b,c){if(a.name&&b.series&&b.series[a.name]){var d=b.series[a.name];return d.hasOwnProperty(c)?d[c]:b[c]}return b[c]},b.optionsProvider=function(a,d,e){function f(a){var f=h;if(h=b.extend({},j),d)for(i=0;i<d.length;i++){var g=c.matchMedia(d[i][0]);g.matches&&(h=b.extend(h,d[i][1]))}e&&a&&e.emit("optionsChanged",{previousOptions:f,currentOptions:h})}function g(){k.forEach(function(a){a.removeListener(f)})}var h,i,j=b.extend({},a),k=[];if(!c.matchMedia)throw"window.matchMedia not found! Make sure you're using a polyfill.";if(d)for(i=0;i<d.length;i++){var l=c.matchMedia(d[i][0]);l.addListener(f),k.push(l)}return f(),{removeMediaQueryListeners:g,getCurrentOptions:function(){return b.extend({},h)}}},b.splitIntoSegments=function(a,c,d){var e={increasingX:!1,fillHoles:!1};d=b.extend({},e,d);for(var f=[],g=!0,h=0;h<a.length;h+=2)void 0===b.getMultiValue(c[h/2].value)?d.fillHoles||(g=!0):(d.increasingX&&h>=2&&a[h]<=a[h-2]&&(g=!0),g&&(f.push({pathCoordinates:[],valueData:[]}),g=!1),f[f.length-1].pathCoordinates.push(a[h],a[h+1]),f[f.length-1].valueData.push(c[h/2]));return f}}(this,a),function(a,b){"use strict";b.Interpolation={},b.Interpolation.none=function(a){var c={fillHoles:!1};return a=b.extend({},c,a),function(c,d){for(var e=new b.Svg.Path,f=!0,g=0;g<c.length;g+=2){var h=c[g],i=c[g+1],j=d[g/2];void 0!==b.getMultiValue(j.value)?(f?e.move(h,i,!1,j):e.line(h,i,!1,j),f=!1):a.fillHoles||(f=!0)}return e}},b.Interpolation.simple=function(a){var c={divisor:2,fillHoles:!1};a=b.extend({},c,a);var d=1/Math.max(1,a.divisor);return function(c,e){for(var f,g,h,i=new b.Svg.Path,j=0;j<c.length;j+=2){var k=c[j],l=c[j+1],m=(k-f)*d,n=e[j/2];void 0!==n.value?(void 0===h?i.move(k,l,!1,n):i.curve(f+m,g,k-m,l,k,l,!1,n),f=k,g=l,h=n):a.fillHoles||(f=k=h=void 0)}return i}},b.Interpolation.cardinal=function(a){var c={tension:1,fillHoles:!1};a=b.extend({},c,a);var d=Math.min(1,Math.max(0,a.tension)),e=1-d;return function f(c,g){var h=b.splitIntoSegments(c,g,{fillHoles:a.fillHoles});if(h.length){if(h.length>1){var i=[];return h.forEach(function(a){i.push(f(a.pathCoordinates,a.valueData))}),b.Svg.Path.join(i)}if(c=h[0].pathCoordinates,g=h[0].valueData,c.length<=4)return b.Interpolation.none()(c,g);for(var j,k=(new b.Svg.Path).move(c[0],c[1],!1,g[0]),l=0,m=c.length;m-2*!j>l;l+=2){var n=[{x:+c[l-2],y:+c[l-1]},{x:+c[l],y:+c[l+1]},{x:+c[l+2],y:+c[l+3]},{x:+c[l+4],y:+c[l+5]}];j?l?m-4===l?n[3]={x:+c[0],y:+c[1]}:m-2===l&&(n[2]={x:+c[0],y:+c[1]},n[3]={x:+c[2],y:+c[3]}):n[0]={x:+c[m-2],y:+c[m-1]}:m-4===l?n[3]=n[2]:l||(n[0]={x:+c[l],y:+c[l+1]}),k.curve(d*(-n[0].x+6*n[1].x+n[2].x)/6+e*n[2].x,d*(-n[0].y+6*n[1].y+n[2].y)/6+e*n[2].y,d*(n[1].x+6*n[2].x-n[3].x)/6+e*n[2].x,d*(n[1].y+6*n[2].y-n[3].y)/6+e*n[2].y,n[2].x,n[2].y,!1,g[(l+2)/2])}return k}return b.Interpolation.none()([])}},b.Interpolation.monotoneCubic=function(a){var c={fillHoles:!1};return a=b.extend({},c,a),function d(c,e){var f=b.splitIntoSegments(c,e,{fillHoles:a.fillHoles,increasingX:!0});if(f.length){if(f.length>1){var g=[];return f.forEach(function(a){g.push(d(a.pathCoordinates,a.valueData))}),b.Svg.Path.join(g)}if(c=f[0].pathCoordinates,e=f[0].valueData,c.length<=4)return b.Interpolation.none()(c,e);var h,i,j=[],k=[],l=c.length/2,m=[],n=[],o=[],p=[];for(h=0;h<l;h++)j[h]=c[2*h],k[h]=c[2*h+1];for(h=0;h<l-1;h++)o[h]=k[h+1]-k[h],p[h]=j[h+1]-j[h],n[h]=o[h]/p[h];for(m[0]=n[0],m[l-1]=n[l-2],h=1;h<l-1;h++)0===n[h]||0===n[h-1]||n[h-1]>0!=n[h]>0?m[h]=0:(m[h]=3*(p[h-1]+p[h])/((2*p[h]+p[h-1])/n[h-1]+(p[h]+2*p[h-1])/n[h]),isFinite(m[h])||(m[h]=0));for(i=(new b.Svg.Path).move(j[0],k[0],!1,e[0]),h=0;h<l-1;h++)i.curve(j[h]+p[h]/3,k[h]+m[h]*p[h]/3,j[h+1]-p[h]/3,k[h+1]-m[h+1]*p[h]/3,j[h+1],k[h+1],!1,e[h+1]);return i}return b.Interpolation.none()([])}},b.Interpolation.step=function(a){var c={postpone:!0,fillHoles:!1};return a=b.extend({},c,a),function(c,d){for(var e,f,g,h=new b.Svg.Path,i=0;i<c.length;i+=2){var j=c[i],k=c[i+1],l=d[i/2];void 0!==l.value?(void 0===g?h.move(j,k,!1,l):(a.postpone?h.line(j,f,!1,g):h.line(e,k,!1,l),h.line(j,k,!1,l)),e=j,f=k,g=l):a.fillHoles||(e=f=g=void 0)}return h}}}(this,a),function(a,b){"use strict";b.EventEmitter=function(){function a(a,b){d[a]=d[a]||[],d[a].push(b)}function b(a,b){d[a]&&(b?(d[a].splice(d[a].indexOf(b),1),0===d[a].length&&delete d[a]):delete d[a])}function c(a,b){d[a]&&d[a].forEach(function(a){a(b)}),d["*"]&&d["*"].forEach(function(c){c(a,b)})}var d=[];return{addEventHandler:a,removeEventHandler:b,emit:c}}}(this,a),function(a,b){"use strict";function c(a){var b=[];if(a.length)for(var c=0;c<a.length;c++)b.push(a[c]);return b}function d(a,c){var d=c||this.prototype||b.Class,e=Object.create(d);b.Class.cloneDefinitions(e,a);var f=function(){var a,c=e.constructor||function(){};return a=this===b?Object.create(e):this,c.apply(a,Array.prototype.slice.call(arguments,0)),a};return f.prototype=e,f["super"]=d,f.extend=this.extend,f}function e(){var a=c(arguments),b=a[0];return a.splice(1,a.length-1).forEach(function(a){Object.getOwnPropertyNames(a).forEach(function(c){delete b[c],Object.defineProperty(b,c,Object.getOwnPropertyDescriptor(a,c))})}),b}b.Class={extend:d,cloneDefinitions:e}}(this,a),function(a,b){"use strict";function c(a,c,d){return a&&(this.data=a||{},this.data.labels=this.data.labels||[],this.data.series=this.data.series||[],this.eventEmitter.emit("data",{type:"update",data:this.data})),c&&(this.options=b.extend({},d?this.options:this.defaultOptions,c),this.initializeTimeoutId||(this.optionsProvider.removeMediaQueryListeners(),this.optionsProvider=b.optionsProvider(this.options,this.responsiveOptions,this.eventEmitter))),this.initializeTimeoutId||this.createChart(this.optionsProvider.getCurrentOptions()),this}function d(){return this.initializeTimeoutId?i.clearTimeout(this.initializeTimeoutId):(i.removeEventListener("resize",this.resizeListener),this.optionsProvider.removeMediaQueryListeners()),this}function e(a,b){return this.eventEmitter.addEventHandler(a,b),this}function f(a,b){return this.eventEmitter.removeEventHandler(a,b),this}function g(){i.addEventListener("resize",this.resizeListener),this.optionsProvider=b.optionsProvider(this.options,this.responsiveOptions,this.eventEmitter),this.eventEmitter.addEventHandler("optionsChanged",function(){this.update()}.bind(this)),this.options.plugins&&this.options.plugins.forEach(function(a){a instanceof Array?a[0](this,a[1]):a(this)}.bind(this)),this.eventEmitter.emit("data",{type:"initial",data:this.data}),this.createChart(this.optionsProvider.getCurrentOptions()),this.initializeTimeoutId=void 0}function h(a,c,d,e,f){this.container=b.querySelector(a),this.data=c||{},this.data.labels=this.data.labels||[],this.data.series=this.data.series||[],this.defaultOptions=d,this.options=e,this.responsiveOptions=f,this.eventEmitter=b.EventEmitter(),this.supportsForeignObject=b.Svg.isSupported("Extensibility"),this.supportsAnimations=b.Svg.isSupported("AnimationEventsAttribute"),this.resizeListener=function(){this.update()}.bind(this),this.container&&(this.container.__chartist__&&this.container.__chartist__.detach(),this.container.__chartist__=this),this.initializeTimeoutId=setTimeout(g.bind(this),0)}var i=a.window;b.Base=b.Class.extend({constructor:h,optionsProvider:void 0,container:void 0,svg:void 0,eventEmitter:void 0,createChart:function(){throw new Error("Base chart type can't be instantiated!")},update:c,detach:d,on:e,off:f,version:b.version,supportsForeignObject:!1})}(this,a),function(a,b){"use strict";function c(a,c,d,e,f){a instanceof Element?this._node=a:(this._node=y.createElementNS(b.namespaces.svg,a),"svg"===a&&this.attr({"xmlns:ct":b.namespaces.ct})),c&&this.attr(c),d&&this.addClass(d),e&&(f&&e._node.firstChild?e._node.insertBefore(this._node,e._node.firstChild):e._node.appendChild(this._node))}function d(a,c){return"string"==typeof a?c?this._node.getAttributeNS(c,a):this._node.getAttribute(a):(Object.keys(a).forEach(function(c){if(void 0!==a[c])if(c.indexOf(":")!==-1){var d=c.split(":");this._node.setAttributeNS(b.namespaces[d[0]],c,a[c])}else this._node.setAttribute(c,a[c])}.bind(this)),this)}function e(a,c,d,e){return new b.Svg(a,c,d,this,e)}function f(){return this._node.parentNode instanceof SVGElement?new b.Svg(this._node.parentNode):null}function g(){for(var a=this._node;"svg"!==a.nodeName;)a=a.parentNode;return new b.Svg(a)}function h(a){var c=this._node.querySelector(a);return c?new b.Svg(c):null}function i(a){var c=this._node.querySelectorAll(a);return c.length?new b.Svg.List(c):null}function j(){return this._node}function k(a,c,d,e){if("string"==typeof a){var f=y.createElement("div");f.innerHTML=a,a=f.firstChild}a.setAttribute("xmlns",b.namespaces.xmlns);var g=this.elem("foreignObject",c,d,e);return g._node.appendChild(a),g}function l(a){return this._node.appendChild(y.createTextNode(a)),this}function m(){for(;this._node.firstChild;)this._node.removeChild(this._node.firstChild);return this}function n(){return this._node.parentNode.removeChild(this._node),this.parent()}function o(a){return this._node.parentNode.replaceChild(a._node,this._node),a}function p(a,b){return b&&this._node.firstChild?this._node.insertBefore(a._node,this._node.firstChild):this._node.appendChild(a._node),this}function q(){return this._node.getAttribute("class")?this._node.getAttribute("class").trim().split(/\s+/):[]}function r(a){return this._node.setAttribute("class",this.classes(this._node).concat(a.trim().split(/\s+/)).filter(function(a,b,c){return c.indexOf(a)===b}).join(" ")),this}function s(a){var b=a.trim().split(/\s+/);return this._node.setAttribute("class",this.classes(this._node).filter(function(a){return b.indexOf(a)===-1}).join(" ")),this}function t(){return this._node.setAttribute("class",""),this}function u(){return this._node.getBoundingClientRect().height}function v(){return this._node.getBoundingClientRect().width}function w(a,c,d){return void 0===c&&(c=!0),Object.keys(a).forEach(function(e){function f(a,c){var f,g,h,i={};a.easing&&(h=a.easing instanceof Array?a.easing:b.Svg.Easing[a.easing],delete a.easing),a.begin=b.ensureUnit(a.begin,"ms"),a.dur=b.ensureUnit(a.dur,"ms"),h&&(a.calcMode="spline",a.keySplines=h.join(" "),a.keyTimes="0;1"),c&&(a.fill="freeze",i[e]=a.from,this.attr(i),g=b.quantity(a.begin||0).value,a.begin="indefinite"),f=this.elem("animate",b.extend({attributeName:e},a)),c&&setTimeout(function(){try{f._node.beginElement()}catch(b){i[e]=a.to,this.attr(i),f.remove()}}.bind(this),g),d&&f._node.addEventListener("beginEvent",function(){d.emit("animationBegin",{element:this,animate:f._node,params:a})}.bind(this)),f._node.addEventListener("endEvent",function(){d&&d.emit("animationEnd",{element:this,animate:f._node,params:a}),c&&(i[e]=a.to,this.attr(i),f.remove())}.bind(this))}a[e]instanceof Array?a[e].forEach(function(a){f.bind(this)(a,!1)}.bind(this)):f.bind(this)(a[e],c)}.bind(this)),this}function x(a){var c=this;this.svgElements=[];for(var d=0;d<a.length;d++)this.svgElements.push(new b.Svg(a[d]));Object.keys(b.Svg.prototype).filter(function(a){return["constructor","parent","querySelector","querySelectorAll","replace","append","classes","height","width"].indexOf(a)===-1}).forEach(function(a){c[a]=function(){var d=Array.prototype.slice.call(arguments,0);return c.svgElements.forEach(function(c){b.Svg.prototype[a].apply(c,d)}),c}})}var y=a.document;b.Svg=b.Class.extend({constructor:c,attr:d,elem:e,parent:f,root:g,querySelector:h,querySelectorAll:i,getNode:j,foreignObject:k,text:l,empty:m,remove:n,replace:o,append:p,classes:q,addClass:r,removeClass:s,removeAllClasses:t,height:u,width:v,animate:w}),b.Svg.isSupported=function(a){return y.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#"+a,"1.1")};var z={easeInSine:[.47,0,.745,.715],easeOutSine:[.39,.575,.565,1],easeInOutSine:[.445,.05,.55,.95],easeInQuad:[.55,.085,.68,.53],easeOutQuad:[.25,.46,.45,.94],easeInOutQuad:[.455,.03,.515,.955],easeInCubic:[.55,.055,.675,.19],easeOutCubic:[.215,.61,.355,1],easeInOutCubic:[.645,.045,.355,1],easeInQuart:[.895,.03,.685,.22],easeOutQuart:[.165,.84,.44,1],easeInOutQuart:[.77,0,.175,1],easeInQuint:[.755,.05,.855,.06],easeOutQuint:[.23,1,.32,1],easeInOutQuint:[.86,0,.07,1],easeInExpo:[.95,.05,.795,.035],easeOutExpo:[.19,1,.22,1],easeInOutExpo:[1,0,0,1],easeInCirc:[.6,.04,.98,.335],easeOutCirc:[.075,.82,.165,1],easeInOutCirc:[.785,.135,.15,.86],easeInBack:[.6,-.28,.735,.045],easeOutBack:[.175,.885,.32,1.275],easeInOutBack:[.68,-.55,.265,1.55]};b.Svg.Easing=z,b.Svg.List=b.Class.extend({constructor:x})}(this,a),function(a,b){"use strict";function c(a,c,d,e,f,g){var h=b.extend({command:f?a.toLowerCase():a.toUpperCase()},c,g?{data:g}:{});d.splice(e,0,h)}function d(a,b){a.forEach(function(c,d){t[c.command.toLowerCase()].forEach(function(e,f){b(c,e,d,f,a)})})}function e(a,c){this.pathElements=[],this.pos=0,this.close=a,this.options=b.extend({},u,c)}function f(a){return void 0!==a?(this.pos=Math.max(0,Math.min(this.pathElements.length,a)),this):this.pos}function g(a){return this.pathElements.splice(this.pos,a),this}function h(a,b,d,e){return c("M",{x:+a,y:+b},this.pathElements,this.pos++,d,e),this}function i(a,b,d,e){return c("L",{x:+a,y:+b},this.pathElements,this.pos++,d,e),this}function j(a,b,d,e,f,g,h,i){return c("C",{x1:+a,y1:+b,x2:+d,y2:+e,x:+f,y:+g},this.pathElements,this.pos++,h,i),this}function k(a,b,d,e,f,g,h,i,j){return c("A",{rx:+a,ry:+b,xAr:+d,lAf:+e,sf:+f,x:+g,y:+h},this.pathElements,this.pos++,i,j),this}function l(a){var c=a.replace(/([A-Za-z])([0-9])/g,"$1 $2").replace(/([0-9])([A-Za-z])/g,"$1 $2").split(/[\s,]+/).reduce(function(a,b){return b.match(/[A-Za-z]/)&&a.push([]),a[a.length-1].push(b),a},[]);"Z"===c[c.length-1][0].toUpperCase()&&c.pop();var d=c.map(function(a){var c=a.shift(),d=t[c.toLowerCase()];return b.extend({command:c},d.reduce(function(b,c,d){return b[c]=+a[d],b},{}))}),e=[this.pos,0];return Array.prototype.push.apply(e,d),Array.prototype.splice.apply(this.pathElements,e),this.pos+=d.length,this}function m(){var a=Math.pow(10,this.options.accuracy);return this.pathElements.reduce(function(b,c){var d=t[c.command.toLowerCase()].map(function(b){return this.options.accuracy?Math.round(c[b]*a)/a:c[b]}.bind(this));return b+c.command+d.join(",")}.bind(this),"")+(this.close?"Z":"")}function n(a,b){return d(this.pathElements,function(c,d){c[d]*="x"===d[0]?a:b}),this}function o(a,b){return d(this.pathElements,function(c,d){c[d]+="x"===d[0]?a:b}),this}function p(a){return d(this.pathElements,function(b,c,d,e,f){var g=a(b,c,d,e,f);(g||0===g)&&(b[c]=g)}),this}function q(a){var c=new b.Svg.Path(a||this.close);return c.pos=this.pos,c.pathElements=this.pathElements.slice().map(function(a){return b.extend({},a)}),c.options=b.extend({},this.options),c}function r(a){var c=[new b.Svg.Path];return this.pathElements.forEach(function(d){d.command===a.toUpperCase()&&0!==c[c.length-1].pathElements.length&&c.push(new b.Svg.Path),c[c.length-1].pathElements.push(d)}),c}function s(a,c,d){for(var e=new b.Svg.Path(c,d),f=0;f<a.length;f++)for(var g=a[f],h=0;h<g.pathElements.length;h++)e.pathElements.push(g.pathElements[h]);return e}var t={m:["x","y"],l:["x","y"],c:["x1","y1","x2","y2","x","y"],a:["rx","ry","xAr","lAf","sf","x","y"]},u={accuracy:3};b.Svg.Path=b.Class.extend({constructor:e,position:f,remove:g,move:h,line:i,curve:j,arc:k,scale:n,translate:o,transform:p,parse:l,stringify:m,clone:q,splitByCommand:r}),b.Svg.Path.elementDescriptions=t,b.Svg.Path.join=s}(this,a),function(a,b){"use strict";function c(a,b,c,d){this.units=a,this.counterUnits=a===e.x?e.y:e.x,this.chartRect=b,this.axisLength=b[a.rectEnd]-b[a.rectStart],this.gridOffset=b[a.rectOffset],this.ticks=c,this.options=d}function d(a,c,d,e,f){var g=e["axis"+this.units.pos.toUpperCase()],h=this.ticks.map(this.projectValue.bind(this)),i=this.ticks.map(g.labelInterpolationFnc);h.forEach(function(j,k){var l,m={x:0,y:0};l=h[k+1]?h[k+1]-j:Math.max(this.axisLength-j,30),b.isFalseyButZero(i[k])&&""!==i[k]||("x"===this.units.pos?(j=this.chartRect.x1+j,m.x=e.axisX.labelOffset.x,"start"===e.axisX.position?m.y=this.chartRect.padding.top+e.axisX.labelOffset.y+(d?5:20):m.y=this.chartRect.y1+e.axisX.labelOffset.y+(d?5:20)):(j=this.chartRect.y1-j,m.y=e.axisY.labelOffset.y-(d?l:0),"start"===e.axisY.position?m.x=d?this.chartRect.padding.left+e.axisY.labelOffset.x:this.chartRect.x1-10:m.x=this.chartRect.x2+e.axisY.labelOffset.x+10),g.showGrid&&b.createGrid(j,k,this,this.gridOffset,this.chartRect[this.counterUnits.len](),a,[e.classNames.grid,e.classNames[this.units.dir]],f),g.showLabel&&b.createLabel(j,l,k,i,this,g.offset,m,c,[e.classNames.label,e.classNames[this.units.dir],"start"===g.position?e.classNames[g.position]:e.classNames.end],d,f))}.bind(this))}var e=(a.window,a.document,{x:{pos:"x",len:"width",dir:"horizontal",rectStart:"x1",rectEnd:"x2",rectOffset:"y2"},y:{pos:"y",len:"height",dir:"vertical",rectStart:"y2",rectEnd:"y1",rectOffset:"x1"}});b.Axis=b.Class.extend({constructor:c,createGridAndLabels:d,projectValue:function(a,b,c){throw new Error("Base axis can't be instantiated!")}}),b.Axis.units=e}(this,a),function(a,b){"use strict";function c(a,c,d,e){var f=e.highLow||b.getHighLow(c,e,a.pos);this.bounds=b.getBounds(d[a.rectEnd]-d[a.rectStart],f,e.scaleMinSpace||20,e.onlyInteger),this.range={min:this.bounds.min,max:this.bounds.max},b.AutoScaleAxis["super"].constructor.call(this,a,d,this.bounds.values,e)}function d(a){return this.axisLength*(+b.getMultiValue(a,this.units.pos)-this.bounds.min)/this.bounds.range}a.window,a.document;b.AutoScaleAxis=b.Axis.extend({constructor:c,projectValue:d})}(this,a),function(a,b){"use strict";function c(a,c,d,e){var f=e.highLow||b.getHighLow(c,e,a.pos);this.divisor=e.divisor||1,this.ticks=e.ticks||b.times(this.divisor).map(function(a,b){return f.low+(f.high-f.low)/this.divisor*b}.bind(this)),this.ticks.sort(function(a,b){return a-b}),this.range={min:f.low,max:f.high},b.FixedScaleAxis["super"].constructor.call(this,a,d,this.ticks,e),this.stepLength=this.axisLength/this.divisor}function d(a){return this.axisLength*(+b.getMultiValue(a,this.units.pos)-this.range.min)/(this.range.max-this.range.min)}a.window,a.document;b.FixedScaleAxis=b.Axis.extend({constructor:c,projectValue:d})}(this,a),function(a,b){"use strict";function c(a,c,d,e){b.StepAxis["super"].constructor.call(this,a,d,e.ticks,e);var f=Math.max(1,e.ticks.length-(e.stretch?1:0));this.stepLength=this.axisLength/f}function d(a,b){return this.stepLength*b}a.window,a.document;b.StepAxis=b.Axis.extend({constructor:c,projectValue:d})}(this,a),function(a,b){"use strict";function c(a){var c=b.normalizeData(this.data,a.reverseData,!0);this.svg=b.createSvg(this.container,a.width,a.height,a.classNames.chart);var d,f,g=this.svg.elem("g").addClass(a.classNames.gridGroup),h=this.svg.elem("g"),i=this.svg.elem("g").addClass(a.classNames.labelGroup),j=b.createChartRect(this.svg,a,e.padding);d=void 0===a.axisX.type?new b.StepAxis(b.Axis.units.x,c.normalized.series,j,b.extend({},a.axisX,{ticks:c.normalized.labels,stretch:a.fullWidth})):a.axisX.type.call(b,b.Axis.units.x,c.normalized.series,j,a.axisX),f=void 0===a.axisY.type?new b.AutoScaleAxis(b.Axis.units.y,c.normalized.series,j,b.extend({},a.axisY,{high:b.isNumeric(a.high)?a.high:a.axisY.high,low:b.isNumeric(a.low)?a.low:a.axisY.low})):a.axisY.type.call(b,b.Axis.units.y,c.normalized.series,j,a.axisY),d.createGridAndLabels(g,i,this.supportsForeignObject,a,this.eventEmitter),f.createGridAndLabels(g,i,this.supportsForeignObject,a,this.eventEmitter),a.showGridBackground&&b.createGridBackground(g,j,a.classNames.gridBackground,this.eventEmitter),c.raw.series.forEach(function(e,g){var i=h.elem("g");i.attr({"ct:series-name":e.name,"ct:meta":b.serialize(e.meta)}),i.addClass([a.classNames.series,e.className||a.classNames.series+"-"+b.alphaNumerate(g)].join(" "));var k=[],l=[];c.normalized.series[g].forEach(function(a,h){var i={x:j.x1+d.projectValue(a,h,c.normalized.series[g]),y:j.y1-f.projectValue(a,h,c.normalized.series[g])};k.push(i.x,i.y),l.push({value:a,valueIndex:h,meta:b.getMetaData(e,h)})}.bind(this));var m={lineSmooth:b.getSeriesOption(e,a,"lineSmooth"),showPoint:b.getSeriesOption(e,a,"showPoint"),showLine:b.getSeriesOption(e,a,"showLine"),showArea:b.getSeriesOption(e,a,"showArea"),areaBase:b.getSeriesOption(e,a,"areaBase")},n="function"==typeof m.lineSmooth?m.lineSmooth:m.lineSmooth?b.Interpolation.monotoneCubic():b.Interpolation.none(),o=n(k,l);if(m.showPoint&&o.pathElements.forEach(function(c){var h=i.elem("line",{x1:c.x,y1:c.y,x2:c.x+.01,y2:c.y},a.classNames.point).attr({"ct:value":[c.data.value.x,c.data.value.y].filter(b.isNumeric).join(","),"ct:meta":b.serialize(c.data.meta)});this.eventEmitter.emit("draw",{type:"point",value:c.data.value,index:c.data.valueIndex,meta:c.data.meta,series:e,seriesIndex:g,axisX:d,axisY:f,group:i,element:h,x:c.x,y:c.y})}.bind(this)),m.showLine){var p=i.elem("path",{d:o.stringify()},a.classNames.line,!0);this.eventEmitter.emit("draw",{type:"line",values:c.normalized.series[g],path:o.clone(),chartRect:j,index:g,series:e,seriesIndex:g,seriesMeta:e.meta,axisX:d,axisY:f,group:i,element:p})}if(m.showArea&&f.range){var q=Math.max(Math.min(m.areaBase,f.range.max),f.range.min),r=j.y1-f.projectValue(q);o.splitByCommand("M").filter(function(a){return a.pathElements.length>1}).map(function(a){var b=a.pathElements[0],c=a.pathElements[a.pathElements.length-1];return a.clone(!0).position(0).remove(1).move(b.x,r).line(b.x,b.y).position(a.pathElements.length+1).line(c.x,r)}).forEach(function(b){var h=i.elem("path",{d:b.stringify()},a.classNames.area,!0);this.eventEmitter.emit("draw",{type:"area",values:c.normalized.series[g],path:b.clone(),series:e,seriesIndex:g,axisX:d,axisY:f,chartRect:j,index:g,group:i,element:h})}.bind(this))}}.bind(this)),this.eventEmitter.emit("created",{bounds:f.bounds,chartRect:j,axisX:d,axisY:f,svg:this.svg,options:a})}function d(a,c,d,f){b.Line["super"].constructor.call(this,a,c,e,b.extend({},e,d),f)}var e=(a.window,a.document,{axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:b.noop,type:void 0},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:b.noop,type:void 0,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,showLine:!0,showPoint:!0,showArea:!1,areaBase:0,lineSmooth:!0,showGridBackground:!1,low:void 0,high:void 0,chartPadding:{top:15,right:15,bottom:5,left:10},fullWidth:!1,reverseData:!1,classNames:{chart:"ct-chart-line",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",line:"ct-line",point:"ct-point",area:"ct-area",grid:"ct-grid",gridGroup:"ct-grids",gridBackground:"ct-grid-background",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}});b.Line=b.Base.extend({constructor:d,createChart:c})}(this,a),function(a,b){"use strict";function c(a){var c,d;a.distributeSeries?(c=b.normalizeData(this.data,a.reverseData,a.horizontalBars?"x":"y"),c.normalized.series=c.normalized.series.map(function(a){return[a]})):c=b.normalizeData(this.data,a.reverseData,a.horizontalBars?"x":"y"),this.svg=b.createSvg(this.container,a.width,a.height,a.classNames.chart+(a.horizontalBars?" "+a.classNames.horizontalBars:""));var f=this.svg.elem("g").addClass(a.classNames.gridGroup),g=this.svg.elem("g"),h=this.svg.elem("g").addClass(a.classNames.labelGroup);if(a.stackBars&&0!==c.normalized.series.length){var i=b.serialMap(c.normalized.series,function(){
|
9 |
-
return Array.prototype.slice.call(arguments).map(function(a){return a}).reduce(function(a,b){return{x:a.x+(b&&b.x)||0,y:a.y+(b&&b.y)||0}},{x:0,y:0})});d=b.getHighLow([i],a,a.horizontalBars?"x":"y")}else d=b.getHighLow(c.normalized.series,a,a.horizontalBars?"x":"y");d.high=+a.high||(0===a.high?0:d.high),d.low=+a.low||(0===a.low?0:d.low);var j,k,l,m,n,o=b.createChartRect(this.svg,a,e.padding);k=a.distributeSeries&&a.stackBars?c.normalized.labels.slice(0,1):c.normalized.labels,a.horizontalBars?(j=m=void 0===a.axisX.type?new b.AutoScaleAxis(b.Axis.units.x,c.normalized.series,o,b.extend({},a.axisX,{highLow:d,referenceValue:0})):a.axisX.type.call(b,b.Axis.units.x,c.normalized.series,o,b.extend({},a.axisX,{highLow:d,referenceValue:0})),l=n=void 0===a.axisY.type?new b.StepAxis(b.Axis.units.y,c.normalized.series,o,{ticks:k}):a.axisY.type.call(b,b.Axis.units.y,c.normalized.series,o,a.axisY)):(l=m=void 0===a.axisX.type?new b.StepAxis(b.Axis.units.x,c.normalized.series,o,{ticks:k}):a.axisX.type.call(b,b.Axis.units.x,c.normalized.series,o,a.axisX),j=n=void 0===a.axisY.type?new b.AutoScaleAxis(b.Axis.units.y,c.normalized.series,o,b.extend({},a.axisY,{highLow:d,referenceValue:0})):a.axisY.type.call(b,b.Axis.units.y,c.normalized.series,o,b.extend({},a.axisY,{highLow:d,referenceValue:0})));var p=a.horizontalBars?o.x1+j.projectValue(0):o.y1-j.projectValue(0),q=[];l.createGridAndLabels(f,h,this.supportsForeignObject,a,this.eventEmitter),j.createGridAndLabels(f,h,this.supportsForeignObject,a,this.eventEmitter),a.showGridBackground&&b.createGridBackground(f,o,a.classNames.gridBackground,this.eventEmitter),c.raw.series.forEach(function(d,e){var f,h,i=e-(c.raw.series.length-1)/2;f=a.distributeSeries&&!a.stackBars?l.axisLength/c.normalized.series.length/2:a.distributeSeries&&a.stackBars?l.axisLength/2:l.axisLength/c.normalized.series[e].length/2,h=g.elem("g"),h.attr({"ct:series-name":d.name,"ct:meta":b.serialize(d.meta)}),h.addClass([a.classNames.series,d.className||a.classNames.series+"-"+b.alphaNumerate(e)].join(" ")),c.normalized.series[e].forEach(function(g,k){var r,s,t,u;if(u=a.distributeSeries&&!a.stackBars?e:a.distributeSeries&&a.stackBars?0:k,r=a.horizontalBars?{x:o.x1+j.projectValue(g&&g.x?g.x:0,k,c.normalized.series[e]),y:o.y1-l.projectValue(g&&g.y?g.y:0,u,c.normalized.series[e])}:{x:o.x1+l.projectValue(g&&g.x?g.x:0,u,c.normalized.series[e]),y:o.y1-j.projectValue(g&&g.y?g.y:0,k,c.normalized.series[e])},l instanceof b.StepAxis&&(l.options.stretch||(r[l.units.pos]+=f*(a.horizontalBars?-1:1)),r[l.units.pos]+=a.stackBars||a.distributeSeries?0:i*a.seriesBarDistance*(a.horizontalBars?-1:1)),t=q[k]||p,q[k]=t-(p-r[l.counterUnits.pos]),void 0!==g){var v={};v[l.units.pos+"1"]=r[l.units.pos],v[l.units.pos+"2"]=r[l.units.pos],!a.stackBars||"accumulate"!==a.stackMode&&a.stackMode?(v[l.counterUnits.pos+"1"]=p,v[l.counterUnits.pos+"2"]=r[l.counterUnits.pos]):(v[l.counterUnits.pos+"1"]=t,v[l.counterUnits.pos+"2"]=q[k]),v.x1=Math.min(Math.max(v.x1,o.x1),o.x2),v.x2=Math.min(Math.max(v.x2,o.x1),o.x2),v.y1=Math.min(Math.max(v.y1,o.y2),o.y1),v.y2=Math.min(Math.max(v.y2,o.y2),o.y1);var w=b.getMetaData(d,k);s=h.elem("line",v,a.classNames.bar).attr({"ct:value":[g.x,g.y].filter(b.isNumeric).join(","),"ct:meta":b.serialize(w)}),this.eventEmitter.emit("draw",b.extend({type:"bar",value:g,index:k,meta:w,series:d,seriesIndex:e,axisX:m,axisY:n,chartRect:o,group:h,element:s},v))}}.bind(this))}.bind(this)),this.eventEmitter.emit("created",{bounds:j.bounds,chartRect:o,axisX:m,axisY:n,svg:this.svg,options:a})}function d(a,c,d,f){b.Bar["super"].constructor.call(this,a,c,e,b.extend({},e,d),f)}var e=(a.window,a.document,{axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:b.noop,scaleMinSpace:30,onlyInteger:!1},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:b.noop,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,high:void 0,low:void 0,referenceValue:0,chartPadding:{top:15,right:15,bottom:5,left:10},seriesBarDistance:15,stackBars:!1,stackMode:"accumulate",horizontalBars:!1,distributeSeries:!1,reverseData:!1,showGridBackground:!1,classNames:{chart:"ct-chart-bar",horizontalBars:"ct-horizontal-bars",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",bar:"ct-bar",grid:"ct-grid",gridGroup:"ct-grids",gridBackground:"ct-grid-background",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}});b.Bar=b.Base.extend({constructor:d,createChart:c})}(this,a),function(a,b){"use strict";function c(a,b,c){var d=b.x>a.x;return d&&"explode"===c||!d&&"implode"===c?"start":d&&"implode"===c||!d&&"explode"===c?"end":"middle"}function d(a){var d,e,g,h,i,j=b.normalizeData(this.data),k=[],l=a.startAngle;this.svg=b.createSvg(this.container,a.width,a.height,a.donut?a.classNames.chartDonut:a.classNames.chartPie),e=b.createChartRect(this.svg,a,f.padding),g=Math.min(e.width()/2,e.height()/2),i=a.total||j.normalized.series.reduce(function(a,b){return a+b},0);var m=b.quantity(a.donutWidth);"%"===m.unit&&(m.value*=g/100),g-=a.donut&&!a.donutSolid?m.value/2:0,h="outside"===a.labelPosition||a.donut&&!a.donutSolid?g:"center"===a.labelPosition?0:a.donutSolid?g-m.value/2:g/2,h+=a.labelOffset;var n={x:e.x1+e.width()/2,y:e.y2+e.height()/2},o=1===j.raw.series.filter(function(a){return a.hasOwnProperty("value")?0!==a.value:0!==a}).length;j.raw.series.forEach(function(a,b){k[b]=this.svg.elem("g",null,null)}.bind(this)),a.showLabel&&(d=this.svg.elem("g",null,null)),j.raw.series.forEach(function(e,f){if(0!==j.normalized.series[f]||!a.ignoreEmptyValues){k[f].attr({"ct:series-name":e.name}),k[f].addClass([a.classNames.series,e.className||a.classNames.series+"-"+b.alphaNumerate(f)].join(" "));var p=i>0?l+j.normalized.series[f]/i*360:0,q=Math.max(0,l-(0===f||o?0:.2));p-q>=359.99&&(p=q+359.99);var r,s,t,u=b.polarToCartesian(n.x,n.y,g,q),v=b.polarToCartesian(n.x,n.y,g,p),w=new b.Svg.Path(!a.donut||a.donutSolid).move(v.x,v.y).arc(g,g,0,p-l>180,0,u.x,u.y);a.donut?a.donutSolid&&(t=g-m.value,r=b.polarToCartesian(n.x,n.y,t,l-(0===f||o?0:.2)),s=b.polarToCartesian(n.x,n.y,t,p),w.line(r.x,r.y),w.arc(t,t,0,p-l>180,1,s.x,s.y)):w.line(n.x,n.y);var x=a.classNames.slicePie;a.donut&&(x=a.classNames.sliceDonut,a.donutSolid&&(x=a.classNames.sliceDonutSolid));var y=k[f].elem("path",{d:w.stringify()},x);if(y.attr({"ct:value":j.normalized.series[f],"ct:meta":b.serialize(e.meta)}),a.donut&&!a.donutSolid&&(y._node.style.strokeWidth=m.value+"px"),this.eventEmitter.emit("draw",{type:"slice",value:j.normalized.series[f],totalDataSum:i,index:f,meta:e.meta,series:e,group:k[f],element:y,path:w.clone(),center:n,radius:g,startAngle:l,endAngle:p}),a.showLabel){var z;z=1===j.raw.series.length?{x:n.x,y:n.y}:b.polarToCartesian(n.x,n.y,h,l+(p-l)/2);var A;A=j.normalized.labels&&!b.isFalseyButZero(j.normalized.labels[f])?j.normalized.labels[f]:j.normalized.series[f];var B=a.labelInterpolationFnc(A,f);if(B||0===B){var C=d.elem("text",{dx:z.x,dy:z.y,"text-anchor":c(n,z,a.labelDirection)},a.classNames.label).text(""+B);this.eventEmitter.emit("draw",{type:"label",index:f,group:d,element:C,text:""+B,x:z.x,y:z.y})}}l=p}}.bind(this)),this.eventEmitter.emit("created",{chartRect:e,svg:this.svg,options:a})}function e(a,c,d,e){b.Pie["super"].constructor.call(this,a,c,f,b.extend({},f,d),e)}var f=(a.window,a.document,{width:void 0,height:void 0,chartPadding:5,classNames:{chartPie:"ct-chart-pie",chartDonut:"ct-chart-donut",series:"ct-series",slicePie:"ct-slice-pie",sliceDonut:"ct-slice-donut",sliceDonutSolid:"ct-slice-donut-solid",label:"ct-label"},startAngle:0,total:void 0,donut:!1,donutSolid:!1,donutWidth:60,showLabel:!0,labelOffset:0,labelPosition:"inside",labelInterpolationFnc:b.noop,labelDirection:"neutral",reverseData:!1,ignoreEmptyValues:!1});b.Pie=b.Base.extend({constructor:e,createChart:d,determineAnchorPosition:c})}(this,a),a});
|
10 |
//# sourceMappingURL=chartist.min.js.map
|
1 |
+
/* Chartist.js 0.11.4
|
2 |
* Copyright © 2019 Gion Kunz
|
3 |
* Free to use under either the WTFPL license or the MIT license.
|
4 |
* https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-WTFPL
|
5 |
* https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-MIT
|
6 |
*/
|
7 |
|
8 |
+
!function(a,b){"function"==typeof define&&define.amd?define("Chartist",[],function(){return a.Chartist=b()}):"object"==typeof module&&module.exports?module.exports=b():a.Chartist=b()}(this,function(){var a={version:"0.11.4"};return function(a,b){"use strict";var c=a.window,d=a.document;b.namespaces={svg:"http://www.w3.org/2000/svg",xmlns:"http://www.w3.org/2000/xmlns/",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",ct:"http://gionkunz.github.com/chartist-js/ct"},b.noop=function(a){return a},b.alphaNumerate=function(a){return String.fromCharCode(97+a%26)},b.extend=function(a){var c,d,e;for(a=a||{},c=1;c<arguments.length;c++){d=arguments[c];for(var f in d)e=d[f],"object"!=typeof e||null===e||e instanceof Array?a[f]=e:a[f]=b.extend(a[f],e)}return a},b.replaceAll=function(a,b,c){return a.replace(new RegExp(b,"g"),c)},b.ensureUnit=function(a,b){return"number"==typeof a&&(a+=b),a},b.quantity=function(a){if("string"==typeof a){var b=/^(\d+)\s*(.*)$/g.exec(a);return{value:+b[1],unit:b[2]||void 0}}return{value:a}},b.querySelector=function(a){return a instanceof Node?a:d.querySelector(a)},b.times=function(a){return Array.apply(null,new Array(a))},b.sum=function(a,b){return a+(b?b:0)},b.mapMultiply=function(a){return function(b){return b*a}},b.mapAdd=function(a){return function(b){return b+a}},b.serialMap=function(a,c){var d=[],e=Math.max.apply(null,a.map(function(a){return a.length}));return b.times(e).forEach(function(b,e){var f=a.map(function(a){return a[e]});d[e]=c.apply(null,f)}),d},b.roundWithPrecision=function(a,c){var d=Math.pow(10,c||b.precision);return Math.round(a*d)/d},b.precision=8,b.escapingMap={"&":"&","<":"<",">":">",'"':""","'":"'"},b.serialize=function(a){return null===a||void 0===a?a:("number"==typeof a?a=""+a:"object"==typeof a&&(a=JSON.stringify({data:a})),Object.keys(b.escapingMap).reduce(function(a,c){return b.replaceAll(a,c,b.escapingMap[c])},a))},b.deserialize=function(a){if("string"!=typeof a)return a;a=Object.keys(b.escapingMap).reduce(function(a,c){return b.replaceAll(a,b.escapingMap[c],c)},a);try{a=JSON.parse(a),a=void 0!==a.data?a.data:a}catch(c){}return a},b.createSvg=function(a,c,d,e){var f;return c=c||"100%",d=d||"100%",Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function(a){return a.getAttributeNS(b.namespaces.xmlns,"ct")}).forEach(function(b){a.removeChild(b)}),f=new b.Svg("svg").attr({width:c,height:d}).addClass(e),f._node.style.width=c,f._node.style.height=d,a.appendChild(f._node),f},b.normalizeData=function(a,c,d){var e,f={raw:a,normalized:{}};return f.normalized.series=b.getDataArray({series:a.series||[]},c,d),e=f.normalized.series.every(function(a){return a instanceof Array})?Math.max.apply(null,f.normalized.series.map(function(a){return a.length})):f.normalized.series.length,f.normalized.labels=(a.labels||[]).slice(),Array.prototype.push.apply(f.normalized.labels,b.times(Math.max(0,e-f.normalized.labels.length)).map(function(){return""})),c&&b.reverseData(f.normalized),f},b.safeHasProperty=function(a,b){return null!==a&&"object"==typeof a&&a.hasOwnProperty(b)},b.isDataHoleValue=function(a){return null===a||void 0===a||"number"==typeof a&&isNaN(a)},b.reverseData=function(a){a.labels.reverse(),a.series.reverse();for(var b=0;b<a.series.length;b++)"object"==typeof a.series[b]&&void 0!==a.series[b].data?a.series[b].data.reverse():a.series[b]instanceof Array&&a.series[b].reverse()},b.getDataArray=function(a,c,d){function e(a){if(b.safeHasProperty(a,"value"))return e(a.value);if(b.safeHasProperty(a,"data"))return e(a.data);if(a instanceof Array)return a.map(e);if(!b.isDataHoleValue(a)){if(d){var c={};return"string"==typeof d?c[d]=b.getNumberOrUndefined(a):c.y=b.getNumberOrUndefined(a),c.x=a.hasOwnProperty("x")?b.getNumberOrUndefined(a.x):c.x,c.y=a.hasOwnProperty("y")?b.getNumberOrUndefined(a.y):c.y,c}return b.getNumberOrUndefined(a)}}return a.series.map(e)},b.normalizePadding=function(a,b){return b=b||0,"number"==typeof a?{top:a,right:a,bottom:a,left:a}:{top:"number"==typeof a.top?a.top:b,right:"number"==typeof a.right?a.right:b,bottom:"number"==typeof a.bottom?a.bottom:b,left:"number"==typeof a.left?a.left:b}},b.getMetaData=function(a,b){var c=a.data?a.data[b]:a[b];return c?c.meta:void 0},b.orderOfMagnitude=function(a){return Math.floor(Math.log(Math.abs(a))/Math.LN10)},b.projectLength=function(a,b,c){return b/c.range*a},b.getAvailableHeight=function(a,c){return Math.max((b.quantity(c.height).value||a.height())-(c.chartPadding.top+c.chartPadding.bottom)-c.axisX.offset,0)},b.getHighLow=function(a,c,d){function e(a){if(void 0!==a)if(a instanceof Array)for(var b=0;b<a.length;b++)e(a[b]);else{var c=d?+a[d]:+a;g&&c>f.high&&(f.high=c),h&&c<f.low&&(f.low=c)}}c=b.extend({},c,d?c["axis"+d.toUpperCase()]:{});var f={high:void 0===c.high?-Number.MAX_VALUE:+c.high,low:void 0===c.low?Number.MAX_VALUE:+c.low},g=void 0===c.high,h=void 0===c.low;return(g||h)&&e(a),(c.referenceValue||0===c.referenceValue)&&(f.high=Math.max(c.referenceValue,f.high),f.low=Math.min(c.referenceValue,f.low)),f.high<=f.low&&(0===f.low?f.high=1:f.low<0?f.high=0:f.high>0?f.low=0:(f.high=1,f.low=0)),f},b.isNumeric=function(a){return null!==a&&isFinite(a)},b.isFalseyButZero=function(a){return!a&&0!==a},b.getNumberOrUndefined=function(a){return b.isNumeric(a)?+a:void 0},b.isMultiValue=function(a){return"object"==typeof a&&("x"in a||"y"in a)},b.getMultiValue=function(a,c){return b.isMultiValue(a)?b.getNumberOrUndefined(a[c||"y"]):b.getNumberOrUndefined(a)},b.rho=function(a){function b(a,c){return a%c===0?c:b(c,a%c)}function c(a){return a*a+1}if(1===a)return a;var d,e=2,f=2;if(a%2===0)return 2;do e=c(e)%a,f=c(c(f))%a,d=b(Math.abs(e-f),a);while(1===d);return d},b.getBounds=function(a,c,d,e){function f(a,b){return a===(a+=b)&&(a*=1+(b>0?o:-o)),a}var g,h,i,j=0,k={high:c.high,low:c.low};k.valueRange=k.high-k.low,k.oom=b.orderOfMagnitude(k.valueRange),k.step=Math.pow(10,k.oom),k.min=Math.floor(k.low/k.step)*k.step,k.max=Math.ceil(k.high/k.step)*k.step,k.range=k.max-k.min,k.numberOfSteps=Math.round(k.range/k.step);var l=b.projectLength(a,k.step,k),m=l<d,n=e?b.rho(k.range):0;if(e&&b.projectLength(a,1,k)>=d)k.step=1;else if(e&&n<k.step&&b.projectLength(a,n,k)>=d)k.step=n;else for(;;){if(m&&b.projectLength(a,k.step,k)<=d)k.step*=2;else{if(m||!(b.projectLength(a,k.step/2,k)>=d))break;if(k.step/=2,e&&k.step%1!==0){k.step*=2;break}}if(j++>1e3)throw new Error("Exceeded maximum number of iterations while optimizing scale step!")}var o=2.221e-16;for(k.step=Math.max(k.step,o),h=k.min,i=k.max;h+k.step<=k.low;)h=f(h,k.step);for(;i-k.step>=k.high;)i=f(i,-k.step);k.min=h,k.max=i,k.range=k.max-k.min;var p=[];for(g=k.min;g<=k.max;g=f(g,k.step)){var q=b.roundWithPrecision(g);q!==p[p.length-1]&&p.push(q)}return k.values=p,k},b.polarToCartesian=function(a,b,c,d){var e=(d-90)*Math.PI/180;return{x:a+c*Math.cos(e),y:b+c*Math.sin(e)}},b.createChartRect=function(a,c,d){var e=!(!c.axisX&&!c.axisY),f=e?c.axisY.offset:0,g=e?c.axisX.offset:0,h=a.width()||b.quantity(c.width).value||0,i=a.height()||b.quantity(c.height).value||0,j=b.normalizePadding(c.chartPadding,d);h=Math.max(h,f+j.left+j.right),i=Math.max(i,g+j.top+j.bottom);var k={padding:j,width:function(){return this.x2-this.x1},height:function(){return this.y1-this.y2}};return e?("start"===c.axisX.position?(k.y2=j.top+g,k.y1=Math.max(i-j.bottom,k.y2+1)):(k.y2=j.top,k.y1=Math.max(i-j.bottom-g,k.y2+1)),"start"===c.axisY.position?(k.x1=j.left+f,k.x2=Math.max(h-j.right,k.x1+1)):(k.x1=j.left,k.x2=Math.max(h-j.right-f,k.x1+1))):(k.x1=j.left,k.x2=Math.max(h-j.right,k.x1+1),k.y2=j.top,k.y1=Math.max(i-j.bottom,k.y2+1)),k},b.createGrid=function(a,c,d,e,f,g,h,i){var j={};j[d.units.pos+"1"]=a,j[d.units.pos+"2"]=a,j[d.counterUnits.pos+"1"]=e,j[d.counterUnits.pos+"2"]=e+f;var k=g.elem("line",j,h.join(" "));i.emit("draw",b.extend({type:"grid",axis:d,index:c,group:g,element:k},j))},b.createGridBackground=function(a,b,c,d){var e=a.elem("rect",{x:b.x1,y:b.y2,width:b.width(),height:b.height()},c,!0);d.emit("draw",{type:"gridBackground",group:a,element:e})},b.createLabel=function(a,c,e,f,g,h,i,j,k,l,m){var n,o={};if(o[g.units.pos]=a+i[g.units.pos],o[g.counterUnits.pos]=i[g.counterUnits.pos],o[g.units.len]=c,o[g.counterUnits.len]=Math.max(0,h-10),l){var p=d.createElement("span");p.className=k.join(" "),p.setAttribute("xmlns",b.namespaces.xhtml),p.innerText=f[e],p.style[g.units.len]=Math.round(o[g.units.len])+"px",p.style[g.counterUnits.len]=Math.round(o[g.counterUnits.len])+"px",n=j.foreignObject(p,b.extend({style:"overflow: visible;"},o))}else n=j.elem("text",o,k.join(" ")).text(f[e]);m.emit("draw",b.extend({type:"label",axis:g,index:e,group:j,element:n,text:f[e]},o))},b.getSeriesOption=function(a,b,c){if(a.name&&b.series&&b.series[a.name]){var d=b.series[a.name];return d.hasOwnProperty(c)?d[c]:b[c]}return b[c]},b.optionsProvider=function(a,d,e){function f(a){var f=h;if(h=b.extend({},j),d)for(i=0;i<d.length;i++){var g=c.matchMedia(d[i][0]);g.matches&&(h=b.extend(h,d[i][1]))}e&&a&&e.emit("optionsChanged",{previousOptions:f,currentOptions:h})}function g(){k.forEach(function(a){a.removeListener(f)})}var h,i,j=b.extend({},a),k=[];if(!c.matchMedia)throw"window.matchMedia not found! Make sure you're using a polyfill.";if(d)for(i=0;i<d.length;i++){var l=c.matchMedia(d[i][0]);l.addListener(f),k.push(l)}return f(),{removeMediaQueryListeners:g,getCurrentOptions:function(){return b.extend({},h)}}},b.splitIntoSegments=function(a,c,d){var e={increasingX:!1,fillHoles:!1};d=b.extend({},e,d);for(var f=[],g=!0,h=0;h<a.length;h+=2)void 0===b.getMultiValue(c[h/2].value)?d.fillHoles||(g=!0):(d.increasingX&&h>=2&&a[h]<=a[h-2]&&(g=!0),g&&(f.push({pathCoordinates:[],valueData:[]}),g=!1),f[f.length-1].pathCoordinates.push(a[h],a[h+1]),f[f.length-1].valueData.push(c[h/2]));return f}}(this||global,a),function(a,b){"use strict";b.Interpolation={},b.Interpolation.none=function(a){var c={fillHoles:!1};return a=b.extend({},c,a),function(c,d){for(var e=new b.Svg.Path,f=!0,g=0;g<c.length;g+=2){var h=c[g],i=c[g+1],j=d[g/2];void 0!==b.getMultiValue(j.value)?(f?e.move(h,i,!1,j):e.line(h,i,!1,j),f=!1):a.fillHoles||(f=!0)}return e}},b.Interpolation.simple=function(a){var c={divisor:2,fillHoles:!1};a=b.extend({},c,a);var d=1/Math.max(1,a.divisor);return function(c,e){for(var f,g,h,i=new b.Svg.Path,j=0;j<c.length;j+=2){var k=c[j],l=c[j+1],m=(k-f)*d,n=e[j/2];void 0!==n.value?(void 0===h?i.move(k,l,!1,n):i.curve(f+m,g,k-m,l,k,l,!1,n),f=k,g=l,h=n):a.fillHoles||(f=k=h=void 0)}return i}},b.Interpolation.cardinal=function(a){var c={tension:1,fillHoles:!1};a=b.extend({},c,a);var d=Math.min(1,Math.max(0,a.tension)),e=1-d;return function f(c,g){var h=b.splitIntoSegments(c,g,{fillHoles:a.fillHoles});if(h.length){if(h.length>1){var i=[];return h.forEach(function(a){i.push(f(a.pathCoordinates,a.valueData))}),b.Svg.Path.join(i)}if(c=h[0].pathCoordinates,g=h[0].valueData,c.length<=4)return b.Interpolation.none()(c,g);for(var j,k=(new b.Svg.Path).move(c[0],c[1],!1,g[0]),l=0,m=c.length;m-2*!j>l;l+=2){var n=[{x:+c[l-2],y:+c[l-1]},{x:+c[l],y:+c[l+1]},{x:+c[l+2],y:+c[l+3]},{x:+c[l+4],y:+c[l+5]}];j?l?m-4===l?n[3]={x:+c[0],y:+c[1]}:m-2===l&&(n[2]={x:+c[0],y:+c[1]},n[3]={x:+c[2],y:+c[3]}):n[0]={x:+c[m-2],y:+c[m-1]}:m-4===l?n[3]=n[2]:l||(n[0]={x:+c[l],y:+c[l+1]}),k.curve(d*(-n[0].x+6*n[1].x+n[2].x)/6+e*n[2].x,d*(-n[0].y+6*n[1].y+n[2].y)/6+e*n[2].y,d*(n[1].x+6*n[2].x-n[3].x)/6+e*n[2].x,d*(n[1].y+6*n[2].y-n[3].y)/6+e*n[2].y,n[2].x,n[2].y,!1,g[(l+2)/2])}return k}return b.Interpolation.none()([])}},b.Interpolation.monotoneCubic=function(a){var c={fillHoles:!1};return a=b.extend({},c,a),function d(c,e){var f=b.splitIntoSegments(c,e,{fillHoles:a.fillHoles,increasingX:!0});if(f.length){if(f.length>1){var g=[];return f.forEach(function(a){g.push(d(a.pathCoordinates,a.valueData))}),b.Svg.Path.join(g)}if(c=f[0].pathCoordinates,e=f[0].valueData,c.length<=4)return b.Interpolation.none()(c,e);var h,i,j=[],k=[],l=c.length/2,m=[],n=[],o=[],p=[];for(h=0;h<l;h++)j[h]=c[2*h],k[h]=c[2*h+1];for(h=0;h<l-1;h++)o[h]=k[h+1]-k[h],p[h]=j[h+1]-j[h],n[h]=o[h]/p[h];for(m[0]=n[0],m[l-1]=n[l-2],h=1;h<l-1;h++)0===n[h]||0===n[h-1]||n[h-1]>0!=n[h]>0?m[h]=0:(m[h]=3*(p[h-1]+p[h])/((2*p[h]+p[h-1])/n[h-1]+(p[h]+2*p[h-1])/n[h]),isFinite(m[h])||(m[h]=0));for(i=(new b.Svg.Path).move(j[0],k[0],!1,e[0]),h=0;h<l-1;h++)i.curve(j[h]+p[h]/3,k[h]+m[h]*p[h]/3,j[h+1]-p[h]/3,k[h+1]-m[h+1]*p[h]/3,j[h+1],k[h+1],!1,e[h+1]);return i}return b.Interpolation.none()([])}},b.Interpolation.step=function(a){var c={postpone:!0,fillHoles:!1};return a=b.extend({},c,a),function(c,d){for(var e,f,g,h=new b.Svg.Path,i=0;i<c.length;i+=2){var j=c[i],k=c[i+1],l=d[i/2];void 0!==l.value?(void 0===g?h.move(j,k,!1,l):(a.postpone?h.line(j,f,!1,g):h.line(e,k,!1,l),h.line(j,k,!1,l)),e=j,f=k,g=l):a.fillHoles||(e=f=g=void 0)}return h}}}(this||global,a),function(a,b){"use strict";b.EventEmitter=function(){function a(a,b){d[a]=d[a]||[],d[a].push(b)}function b(a,b){d[a]&&(b?(d[a].splice(d[a].indexOf(b),1),0===d[a].length&&delete d[a]):delete d[a])}function c(a,b){d[a]&&d[a].forEach(function(a){a(b)}),d["*"]&&d["*"].forEach(function(c){c(a,b)})}var d=[];return{addEventHandler:a,removeEventHandler:b,emit:c}}}(this||global,a),function(a,b){"use strict";function c(a){var b=[];if(a.length)for(var c=0;c<a.length;c++)b.push(a[c]);return b}function d(a,c){var d=c||this.prototype||b.Class,e=Object.create(d);b.Class.cloneDefinitions(e,a);var f=function(){var a,c=e.constructor||function(){};return a=this===b?Object.create(e):this,c.apply(a,Array.prototype.slice.call(arguments,0)),a};return f.prototype=e,f["super"]=d,f.extend=this.extend,f}function e(){var a=c(arguments),b=a[0];return a.splice(1,a.length-1).forEach(function(a){Object.getOwnPropertyNames(a).forEach(function(c){delete b[c],Object.defineProperty(b,c,Object.getOwnPropertyDescriptor(a,c))})}),b}b.Class={extend:d,cloneDefinitions:e}}(this||global,a),function(a,b){"use strict";function c(a,c,d){return a&&(this.data=a||{},this.data.labels=this.data.labels||[],this.data.series=this.data.series||[],this.eventEmitter.emit("data",{type:"update",data:this.data})),c&&(this.options=b.extend({},d?this.options:this.defaultOptions,c),this.initializeTimeoutId||(this.optionsProvider.removeMediaQueryListeners(),this.optionsProvider=b.optionsProvider(this.options,this.responsiveOptions,this.eventEmitter))),this.initializeTimeoutId||this.createChart(this.optionsProvider.getCurrentOptions()),this}function d(){return this.initializeTimeoutId?i.clearTimeout(this.initializeTimeoutId):(i.removeEventListener("resize",this.resizeListener),this.optionsProvider.removeMediaQueryListeners()),this}function e(a,b){return this.eventEmitter.addEventHandler(a,b),this}function f(a,b){return this.eventEmitter.removeEventHandler(a,b),this}function g(){i.addEventListener("resize",this.resizeListener),this.optionsProvider=b.optionsProvider(this.options,this.responsiveOptions,this.eventEmitter),this.eventEmitter.addEventHandler("optionsChanged",function(){this.update()}.bind(this)),this.options.plugins&&this.options.plugins.forEach(function(a){a instanceof Array?a[0](this,a[1]):a(this)}.bind(this)),this.eventEmitter.emit("data",{type:"initial",data:this.data}),this.createChart(this.optionsProvider.getCurrentOptions()),this.initializeTimeoutId=void 0}function h(a,c,d,e,f){this.container=b.querySelector(a),this.data=c||{},this.data.labels=this.data.labels||[],this.data.series=this.data.series||[],this.defaultOptions=d,this.options=e,this.responsiveOptions=f,this.eventEmitter=b.EventEmitter(),this.supportsForeignObject=b.Svg.isSupported("Extensibility"),this.supportsAnimations=b.Svg.isSupported("AnimationEventsAttribute"),this.resizeListener=function(){this.update()}.bind(this),this.container&&(this.container.__chartist__&&this.container.__chartist__.detach(),this.container.__chartist__=this),this.initializeTimeoutId=setTimeout(g.bind(this),0)}var i=a.window;b.Base=b.Class.extend({constructor:h,optionsProvider:void 0,container:void 0,svg:void 0,eventEmitter:void 0,createChart:function(){throw new Error("Base chart type can't be instantiated!")},update:c,detach:d,on:e,off:f,version:b.version,supportsForeignObject:!1})}(this||global,a),function(a,b){"use strict";function c(a,c,d,e,f){a instanceof Element?this._node=a:(this._node=y.createElementNS(b.namespaces.svg,a),"svg"===a&&this.attr({"xmlns:ct":b.namespaces.ct})),c&&this.attr(c),d&&this.addClass(d),e&&(f&&e._node.firstChild?e._node.insertBefore(this._node,e._node.firstChild):e._node.appendChild(this._node))}function d(a,c){return"string"==typeof a?c?this._node.getAttributeNS(c,a):this._node.getAttribute(a):(Object.keys(a).forEach(function(c){if(void 0!==a[c])if(c.indexOf(":")!==-1){var d=c.split(":");this._node.setAttributeNS(b.namespaces[d[0]],c,a[c])}else this._node.setAttribute(c,a[c])}.bind(this)),this)}function e(a,c,d,e){return new b.Svg(a,c,d,this,e)}function f(){return this._node.parentNode instanceof SVGElement?new b.Svg(this._node.parentNode):null}function g(){for(var a=this._node;"svg"!==a.nodeName;)a=a.parentNode;return new b.Svg(a)}function h(a){var c=this._node.querySelector(a);return c?new b.Svg(c):null}function i(a){var c=this._node.querySelectorAll(a);return c.length?new b.Svg.List(c):null}function j(){return this._node}function k(a,c,d,e){if("string"==typeof a){var f=y.createElement("div");f.innerHTML=a,a=f.firstChild}a.setAttribute("xmlns",b.namespaces.xmlns);var g=this.elem("foreignObject",c,d,e);return g._node.appendChild(a),g}function l(a){return this._node.appendChild(y.createTextNode(a)),this}function m(){for(;this._node.firstChild;)this._node.removeChild(this._node.firstChild);return this}function n(){return this._node.parentNode.removeChild(this._node),this.parent()}function o(a){return this._node.parentNode.replaceChild(a._node,this._node),a}function p(a,b){return b&&this._node.firstChild?this._node.insertBefore(a._node,this._node.firstChild):this._node.appendChild(a._node),this}function q(){return this._node.getAttribute("class")?this._node.getAttribute("class").trim().split(/\s+/):[]}function r(a){return this._node.setAttribute("class",this.classes(this._node).concat(a.trim().split(/\s+/)).filter(function(a,b,c){return c.indexOf(a)===b}).join(" ")),this}function s(a){var b=a.trim().split(/\s+/);return this._node.setAttribute("class",this.classes(this._node).filter(function(a){return b.indexOf(a)===-1}).join(" ")),this}function t(){return this._node.setAttribute("class",""),this}function u(){return this._node.getBoundingClientRect().height}function v(){return this._node.getBoundingClientRect().width}function w(a,c,d){return void 0===c&&(c=!0),Object.keys(a).forEach(function(e){function f(a,c){var f,g,h,i={};a.easing&&(h=a.easing instanceof Array?a.easing:b.Svg.Easing[a.easing],delete a.easing),a.begin=b.ensureUnit(a.begin,"ms"),a.dur=b.ensureUnit(a.dur,"ms"),h&&(a.calcMode="spline",a.keySplines=h.join(" "),a.keyTimes="0;1"),c&&(a.fill="freeze",i[e]=a.from,this.attr(i),g=b.quantity(a.begin||0).value,a.begin="indefinite"),f=this.elem("animate",b.extend({attributeName:e},a)),c&&setTimeout(function(){try{f._node.beginElement()}catch(b){i[e]=a.to,this.attr(i),f.remove()}}.bind(this),g),d&&f._node.addEventListener("beginEvent",function(){d.emit("animationBegin",{element:this,animate:f._node,params:a})}.bind(this)),f._node.addEventListener("endEvent",function(){d&&d.emit("animationEnd",{element:this,animate:f._node,params:a}),c&&(i[e]=a.to,this.attr(i),f.remove())}.bind(this))}a[e]instanceof Array?a[e].forEach(function(a){f.bind(this)(a,!1)}.bind(this)):f.bind(this)(a[e],c)}.bind(this)),this}function x(a){var c=this;this.svgElements=[];for(var d=0;d<a.length;d++)this.svgElements.push(new b.Svg(a[d]));Object.keys(b.Svg.prototype).filter(function(a){return["constructor","parent","querySelector","querySelectorAll","replace","append","classes","height","width"].indexOf(a)===-1}).forEach(function(a){c[a]=function(){var d=Array.prototype.slice.call(arguments,0);return c.svgElements.forEach(function(c){b.Svg.prototype[a].apply(c,d)}),c}})}var y=a.document;b.Svg=b.Class.extend({constructor:c,attr:d,elem:e,parent:f,root:g,querySelector:h,querySelectorAll:i,getNode:j,foreignObject:k,text:l,empty:m,remove:n,replace:o,append:p,classes:q,addClass:r,removeClass:s,removeAllClasses:t,height:u,width:v,animate:w}),b.Svg.isSupported=function(a){return y.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#"+a,"1.1")};var z={easeInSine:[.47,0,.745,.715],easeOutSine:[.39,.575,.565,1],easeInOutSine:[.445,.05,.55,.95],easeInQuad:[.55,.085,.68,.53],easeOutQuad:[.25,.46,.45,.94],easeInOutQuad:[.455,.03,.515,.955],easeInCubic:[.55,.055,.675,.19],easeOutCubic:[.215,.61,.355,1],easeInOutCubic:[.645,.045,.355,1],easeInQuart:[.895,.03,.685,.22],easeOutQuart:[.165,.84,.44,1],easeInOutQuart:[.77,0,.175,1],easeInQuint:[.755,.05,.855,.06],easeOutQuint:[.23,1,.32,1],easeInOutQuint:[.86,0,.07,1],easeInExpo:[.95,.05,.795,.035],easeOutExpo:[.19,1,.22,1],easeInOutExpo:[1,0,0,1],easeInCirc:[.6,.04,.98,.335],easeOutCirc:[.075,.82,.165,1],easeInOutCirc:[.785,.135,.15,.86],easeInBack:[.6,-.28,.735,.045],easeOutBack:[.175,.885,.32,1.275],easeInOutBack:[.68,-.55,.265,1.55]};b.Svg.Easing=z,b.Svg.List=b.Class.extend({constructor:x})}(this||global,a),function(a,b){"use strict";function c(a,c,d,e,f,g){var h=b.extend({command:f?a.toLowerCase():a.toUpperCase()},c,g?{data:g}:{});d.splice(e,0,h)}function d(a,b){a.forEach(function(c,d){t[c.command.toLowerCase()].forEach(function(e,f){b(c,e,d,f,a)})})}function e(a,c){this.pathElements=[],this.pos=0,this.close=a,this.options=b.extend({},u,c)}function f(a){return void 0!==a?(this.pos=Math.max(0,Math.min(this.pathElements.length,a)),this):this.pos}function g(a){return this.pathElements.splice(this.pos,a),this}function h(a,b,d,e){return c("M",{x:+a,y:+b},this.pathElements,this.pos++,d,e),this}function i(a,b,d,e){return c("L",{x:+a,y:+b},this.pathElements,this.pos++,d,e),this}function j(a,b,d,e,f,g,h,i){return c("C",{x1:+a,y1:+b,x2:+d,y2:+e,x:+f,y:+g},this.pathElements,this.pos++,h,i),this}function k(a,b,d,e,f,g,h,i,j){return c("A",{rx:+a,ry:+b,xAr:+d,lAf:+e,sf:+f,x:+g,y:+h},this.pathElements,this.pos++,i,j),this}function l(a){var c=a.replace(/([A-Za-z])([0-9])/g,"$1 $2").replace(/([0-9])([A-Za-z])/g,"$1 $2").split(/[\s,]+/).reduce(function(a,b){return b.match(/[A-Za-z]/)&&a.push([]),a[a.length-1].push(b),a},[]);"Z"===c[c.length-1][0].toUpperCase()&&c.pop();var d=c.map(function(a){var c=a.shift(),d=t[c.toLowerCase()];return b.extend({command:c},d.reduce(function(b,c,d){return b[c]=+a[d],b},{}))}),e=[this.pos,0];return Array.prototype.push.apply(e,d),Array.prototype.splice.apply(this.pathElements,e),this.pos+=d.length,this}function m(){var a=Math.pow(10,this.options.accuracy);return this.pathElements.reduce(function(b,c){var d=t[c.command.toLowerCase()].map(function(b){return this.options.accuracy?Math.round(c[b]*a)/a:c[b]}.bind(this));return b+c.command+d.join(",")}.bind(this),"")+(this.close?"Z":"")}function n(a,b){return d(this.pathElements,function(c,d){c[d]*="x"===d[0]?a:b}),this}function o(a,b){return d(this.pathElements,function(c,d){c[d]+="x"===d[0]?a:b}),this}function p(a){return d(this.pathElements,function(b,c,d,e,f){var g=a(b,c,d,e,f);(g||0===g)&&(b[c]=g)}),this}function q(a){var c=new b.Svg.Path(a||this.close);return c.pos=this.pos,c.pathElements=this.pathElements.slice().map(function(a){return b.extend({},a)}),c.options=b.extend({},this.options),c}function r(a){var c=[new b.Svg.Path];return this.pathElements.forEach(function(d){d.command===a.toUpperCase()&&0!==c[c.length-1].pathElements.length&&c.push(new b.Svg.Path),c[c.length-1].pathElements.push(d)}),c}function s(a,c,d){for(var e=new b.Svg.Path(c,d),f=0;f<a.length;f++)for(var g=a[f],h=0;h<g.pathElements.length;h++)e.pathElements.push(g.pathElements[h]);return e}var t={m:["x","y"],l:["x","y"],c:["x1","y1","x2","y2","x","y"],a:["rx","ry","xAr","lAf","sf","x","y"]},u={accuracy:3};b.Svg.Path=b.Class.extend({constructor:e,position:f,remove:g,move:h,line:i,curve:j,arc:k,scale:n,translate:o,transform:p,parse:l,stringify:m,clone:q,splitByCommand:r}),b.Svg.Path.elementDescriptions=t,b.Svg.Path.join=s}(this||global,a),function(a,b){"use strict";function c(a,b,c,d){this.units=a,this.counterUnits=a===e.x?e.y:e.x,this.chartRect=b,this.axisLength=b[a.rectEnd]-b[a.rectStart],this.gridOffset=b[a.rectOffset],this.ticks=c,this.options=d}function d(a,c,d,e,f){var g=e["axis"+this.units.pos.toUpperCase()],h=this.ticks.map(this.projectValue.bind(this)),i=this.ticks.map(g.labelInterpolationFnc);h.forEach(function(j,k){var l,m={x:0,y:0};l=h[k+1]?h[k+1]-j:Math.max(this.axisLength-j,30),b.isFalseyButZero(i[k])&&""!==i[k]||("x"===this.units.pos?(j=this.chartRect.x1+j,m.x=e.axisX.labelOffset.x,"start"===e.axisX.position?m.y=this.chartRect.padding.top+e.axisX.labelOffset.y+(d?5:20):m.y=this.chartRect.y1+e.axisX.labelOffset.y+(d?5:20)):(j=this.chartRect.y1-j,m.y=e.axisY.labelOffset.y-(d?l:0),"start"===e.axisY.position?m.x=d?this.chartRect.padding.left+e.axisY.labelOffset.x:this.chartRect.x1-10:m.x=this.chartRect.x2+e.axisY.labelOffset.x+10),g.showGrid&&b.createGrid(j,k,this,this.gridOffset,this.chartRect[this.counterUnits.len](),a,[e.classNames.grid,e.classNames[this.units.dir]],f),g.showLabel&&b.createLabel(j,l,k,i,this,g.offset,m,c,[e.classNames.label,e.classNames[this.units.dir],"start"===g.position?e.classNames[g.position]:e.classNames.end],d,f))}.bind(this))}var e=(a.window,a.document,{x:{pos:"x",len:"width",dir:"horizontal",rectStart:"x1",rectEnd:"x2",rectOffset:"y2"},y:{pos:"y",len:"height",dir:"vertical",rectStart:"y2",rectEnd:"y1",rectOffset:"x1"}});b.Axis=b.Class.extend({constructor:c,createGridAndLabels:d,projectValue:function(a,b,c){throw new Error("Base axis can't be instantiated!")}}),b.Axis.units=e}(this||global,a),function(a,b){"use strict";function c(a,c,d,e){var f=e.highLow||b.getHighLow(c,e,a.pos);this.bounds=b.getBounds(d[a.rectEnd]-d[a.rectStart],f,e.scaleMinSpace||20,e.onlyInteger),this.range={min:this.bounds.min,max:this.bounds.max},b.AutoScaleAxis["super"].constructor.call(this,a,d,this.bounds.values,e)}function d(a){return this.axisLength*(+b.getMultiValue(a,this.units.pos)-this.bounds.min)/this.bounds.range}a.window,a.document;b.AutoScaleAxis=b.Axis.extend({constructor:c,projectValue:d})}(this||global,a),function(a,b){"use strict";function c(a,c,d,e){var f=e.highLow||b.getHighLow(c,e,a.pos);this.divisor=e.divisor||1,this.ticks=e.ticks||b.times(this.divisor).map(function(a,b){return f.low+(f.high-f.low)/this.divisor*b}.bind(this)),this.ticks.sort(function(a,b){return a-b}),this.range={min:f.low,max:f.high},b.FixedScaleAxis["super"].constructor.call(this,a,d,this.ticks,e),this.stepLength=this.axisLength/this.divisor}function d(a){return this.axisLength*(+b.getMultiValue(a,this.units.pos)-this.range.min)/(this.range.max-this.range.min)}a.window,a.document;b.FixedScaleAxis=b.Axis.extend({constructor:c,projectValue:d})}(this||global,a),function(a,b){"use strict";function c(a,c,d,e){b.StepAxis["super"].constructor.call(this,a,d,e.ticks,e);var f=Math.max(1,e.ticks.length-(e.stretch?1:0));this.stepLength=this.axisLength/f}function d(a,b){return this.stepLength*b}a.window,a.document;b.StepAxis=b.Axis.extend({constructor:c,projectValue:d})}(this||global,a),function(a,b){"use strict";function c(a){var c=b.normalizeData(this.data,a.reverseData,!0);this.svg=b.createSvg(this.container,a.width,a.height,a.classNames.chart);var d,f,g=this.svg.elem("g").addClass(a.classNames.gridGroup),h=this.svg.elem("g"),i=this.svg.elem("g").addClass(a.classNames.labelGroup),j=b.createChartRect(this.svg,a,e.padding);d=void 0===a.axisX.type?new b.StepAxis(b.Axis.units.x,c.normalized.series,j,b.extend({},a.axisX,{ticks:c.normalized.labels,stretch:a.fullWidth})):a.axisX.type.call(b,b.Axis.units.x,c.normalized.series,j,a.axisX),f=void 0===a.axisY.type?new b.AutoScaleAxis(b.Axis.units.y,c.normalized.series,j,b.extend({},a.axisY,{high:b.isNumeric(a.high)?a.high:a.axisY.high,low:b.isNumeric(a.low)?a.low:a.axisY.low})):a.axisY.type.call(b,b.Axis.units.y,c.normalized.series,j,a.axisY),d.createGridAndLabels(g,i,this.supportsForeignObject,a,this.eventEmitter),f.createGridAndLabels(g,i,this.supportsForeignObject,a,this.eventEmitter),a.showGridBackground&&b.createGridBackground(g,j,a.classNames.gridBackground,this.eventEmitter),c.raw.series.forEach(function(e,g){var i=h.elem("g");i.attr({"ct:series-name":e.name,"ct:meta":b.serialize(e.meta)}),i.addClass([a.classNames.series,e.className||a.classNames.series+"-"+b.alphaNumerate(g)].join(" "));var k=[],l=[];c.normalized.series[g].forEach(function(a,h){var i={x:j.x1+d.projectValue(a,h,c.normalized.series[g]),y:j.y1-f.projectValue(a,h,c.normalized.series[g])};k.push(i.x,i.y),l.push({value:a,valueIndex:h,meta:b.getMetaData(e,h)})}.bind(this));var m={lineSmooth:b.getSeriesOption(e,a,"lineSmooth"),showPoint:b.getSeriesOption(e,a,"showPoint"),showLine:b.getSeriesOption(e,a,"showLine"),showArea:b.getSeriesOption(e,a,"showArea"),areaBase:b.getSeriesOption(e,a,"areaBase")},n="function"==typeof m.lineSmooth?m.lineSmooth:m.lineSmooth?b.Interpolation.monotoneCubic():b.Interpolation.none(),o=n(k,l);if(m.showPoint&&o.pathElements.forEach(function(c){var h=i.elem("line",{x1:c.x,y1:c.y,x2:c.x+.01,y2:c.y},a.classNames.point).attr({"ct:value":[c.data.value.x,c.data.value.y].filter(b.isNumeric).join(","),"ct:meta":b.serialize(c.data.meta)});this.eventEmitter.emit("draw",{type:"point",value:c.data.value,index:c.data.valueIndex,meta:c.data.meta,series:e,seriesIndex:g,axisX:d,axisY:f,group:i,element:h,x:c.x,y:c.y})}.bind(this)),m.showLine){var p=i.elem("path",{d:o.stringify()},a.classNames.line,!0);this.eventEmitter.emit("draw",{type:"line",values:c.normalized.series[g],path:o.clone(),chartRect:j,index:g,series:e,seriesIndex:g,seriesMeta:e.meta,axisX:d,axisY:f,group:i,element:p})}if(m.showArea&&f.range){var q=Math.max(Math.min(m.areaBase,f.range.max),f.range.min),r=j.y1-f.projectValue(q);o.splitByCommand("M").filter(function(a){return a.pathElements.length>1}).map(function(a){var b=a.pathElements[0],c=a.pathElements[a.pathElements.length-1];return a.clone(!0).position(0).remove(1).move(b.x,r).line(b.x,b.y).position(a.pathElements.length+1).line(c.x,r)}).forEach(function(b){var h=i.elem("path",{d:b.stringify()},a.classNames.area,!0);this.eventEmitter.emit("draw",{type:"area",values:c.normalized.series[g],path:b.clone(),series:e,seriesIndex:g,axisX:d,axisY:f,chartRect:j,index:g,group:i,element:h})}.bind(this))}}.bind(this)),this.eventEmitter.emit("created",{bounds:f.bounds,chartRect:j,axisX:d,axisY:f,svg:this.svg,options:a})}function d(a,c,d,f){b.Line["super"].constructor.call(this,a,c,e,b.extend({},e,d),f)}var e=(a.window,a.document,{axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:b.noop,type:void 0},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:b.noop,type:void 0,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,showLine:!0,showPoint:!0,showArea:!1,areaBase:0,lineSmooth:!0,showGridBackground:!1,low:void 0,high:void 0,chartPadding:{top:15,right:15,bottom:5,left:10},fullWidth:!1,reverseData:!1,classNames:{chart:"ct-chart-line",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",line:"ct-line",point:"ct-point",area:"ct-area",grid:"ct-grid",gridGroup:"ct-grids",gridBackground:"ct-grid-background",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}});b.Line=b.Base.extend({constructor:d,createChart:c})}(this||global,a),function(a,b){"use strict";function c(a){var c,d;a.distributeSeries?(c=b.normalizeData(this.data,a.reverseData,a.horizontalBars?"x":"y"),c.normalized.series=c.normalized.series.map(function(a){return[a]})):c=b.normalizeData(this.data,a.reverseData,a.horizontalBars?"x":"y"),this.svg=b.createSvg(this.container,a.width,a.height,a.classNames.chart+(a.horizontalBars?" "+a.classNames.horizontalBars:""));var f=this.svg.elem("g").addClass(a.classNames.gridGroup),g=this.svg.elem("g"),h=this.svg.elem("g").addClass(a.classNames.labelGroup);
|
9 |
+
if(a.stackBars&&0!==c.normalized.series.length){var i=b.serialMap(c.normalized.series,function(){return Array.prototype.slice.call(arguments).map(function(a){return a}).reduce(function(a,b){return{x:a.x+(b&&b.x)||0,y:a.y+(b&&b.y)||0}},{x:0,y:0})});d=b.getHighLow([i],a,a.horizontalBars?"x":"y")}else d=b.getHighLow(c.normalized.series,a,a.horizontalBars?"x":"y");d.high=+a.high||(0===a.high?0:d.high),d.low=+a.low||(0===a.low?0:d.low);var j,k,l,m,n,o=b.createChartRect(this.svg,a,e.padding);k=a.distributeSeries&&a.stackBars?c.normalized.labels.slice(0,1):c.normalized.labels,a.horizontalBars?(j=m=void 0===a.axisX.type?new b.AutoScaleAxis(b.Axis.units.x,c.normalized.series,o,b.extend({},a.axisX,{highLow:d,referenceValue:0})):a.axisX.type.call(b,b.Axis.units.x,c.normalized.series,o,b.extend({},a.axisX,{highLow:d,referenceValue:0})),l=n=void 0===a.axisY.type?new b.StepAxis(b.Axis.units.y,c.normalized.series,o,{ticks:k}):a.axisY.type.call(b,b.Axis.units.y,c.normalized.series,o,a.axisY)):(l=m=void 0===a.axisX.type?new b.StepAxis(b.Axis.units.x,c.normalized.series,o,{ticks:k}):a.axisX.type.call(b,b.Axis.units.x,c.normalized.series,o,a.axisX),j=n=void 0===a.axisY.type?new b.AutoScaleAxis(b.Axis.units.y,c.normalized.series,o,b.extend({},a.axisY,{highLow:d,referenceValue:0})):a.axisY.type.call(b,b.Axis.units.y,c.normalized.series,o,b.extend({},a.axisY,{highLow:d,referenceValue:0})));var p=a.horizontalBars?o.x1+j.projectValue(0):o.y1-j.projectValue(0),q=[];l.createGridAndLabels(f,h,this.supportsForeignObject,a,this.eventEmitter),j.createGridAndLabels(f,h,this.supportsForeignObject,a,this.eventEmitter),a.showGridBackground&&b.createGridBackground(f,o,a.classNames.gridBackground,this.eventEmitter),c.raw.series.forEach(function(d,e){var f,h,i=e-(c.raw.series.length-1)/2;f=a.distributeSeries&&!a.stackBars?l.axisLength/c.normalized.series.length/2:a.distributeSeries&&a.stackBars?l.axisLength/2:l.axisLength/c.normalized.series[e].length/2,h=g.elem("g"),h.attr({"ct:series-name":d.name,"ct:meta":b.serialize(d.meta)}),h.addClass([a.classNames.series,d.className||a.classNames.series+"-"+b.alphaNumerate(e)].join(" ")),c.normalized.series[e].forEach(function(g,k){var r,s,t,u;if(u=a.distributeSeries&&!a.stackBars?e:a.distributeSeries&&a.stackBars?0:k,r=a.horizontalBars?{x:o.x1+j.projectValue(g&&g.x?g.x:0,k,c.normalized.series[e]),y:o.y1-l.projectValue(g&&g.y?g.y:0,u,c.normalized.series[e])}:{x:o.x1+l.projectValue(g&&g.x?g.x:0,u,c.normalized.series[e]),y:o.y1-j.projectValue(g&&g.y?g.y:0,k,c.normalized.series[e])},l instanceof b.StepAxis&&(l.options.stretch||(r[l.units.pos]+=f*(a.horizontalBars?-1:1)),r[l.units.pos]+=a.stackBars||a.distributeSeries?0:i*a.seriesBarDistance*(a.horizontalBars?-1:1)),t=q[k]||p,q[k]=t-(p-r[l.counterUnits.pos]),void 0!==g){var v={};v[l.units.pos+"1"]=r[l.units.pos],v[l.units.pos+"2"]=r[l.units.pos],!a.stackBars||"accumulate"!==a.stackMode&&a.stackMode?(v[l.counterUnits.pos+"1"]=p,v[l.counterUnits.pos+"2"]=r[l.counterUnits.pos]):(v[l.counterUnits.pos+"1"]=t,v[l.counterUnits.pos+"2"]=q[k]),v.x1=Math.min(Math.max(v.x1,o.x1),o.x2),v.x2=Math.min(Math.max(v.x2,o.x1),o.x2),v.y1=Math.min(Math.max(v.y1,o.y2),o.y1),v.y2=Math.min(Math.max(v.y2,o.y2),o.y1);var w=b.getMetaData(d,k);s=h.elem("line",v,a.classNames.bar).attr({"ct:value":[g.x,g.y].filter(b.isNumeric).join(","),"ct:meta":b.serialize(w)}),this.eventEmitter.emit("draw",b.extend({type:"bar",value:g,index:k,meta:w,series:d,seriesIndex:e,axisX:m,axisY:n,chartRect:o,group:h,element:s},v))}}.bind(this))}.bind(this)),this.eventEmitter.emit("created",{bounds:j.bounds,chartRect:o,axisX:m,axisY:n,svg:this.svg,options:a})}function d(a,c,d,f){b.Bar["super"].constructor.call(this,a,c,e,b.extend({},e,d),f)}var e=(a.window,a.document,{axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:b.noop,scaleMinSpace:30,onlyInteger:!1},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:b.noop,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,high:void 0,low:void 0,referenceValue:0,chartPadding:{top:15,right:15,bottom:5,left:10},seriesBarDistance:15,stackBars:!1,stackMode:"accumulate",horizontalBars:!1,distributeSeries:!1,reverseData:!1,showGridBackground:!1,classNames:{chart:"ct-chart-bar",horizontalBars:"ct-horizontal-bars",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",bar:"ct-bar",grid:"ct-grid",gridGroup:"ct-grids",gridBackground:"ct-grid-background",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}});b.Bar=b.Base.extend({constructor:d,createChart:c})}(this||global,a),function(a,b){"use strict";function c(a,b,c){var d=b.x>a.x;return d&&"explode"===c||!d&&"implode"===c?"start":d&&"implode"===c||!d&&"explode"===c?"end":"middle"}function d(a){var d,e,g,h,i,j=b.normalizeData(this.data),k=[],l=a.startAngle;this.svg=b.createSvg(this.container,a.width,a.height,a.donut?a.classNames.chartDonut:a.classNames.chartPie),e=b.createChartRect(this.svg,a,f.padding),g=Math.min(e.width()/2,e.height()/2),i=a.total||j.normalized.series.reduce(function(a,b){return a+b},0);var m=b.quantity(a.donutWidth);"%"===m.unit&&(m.value*=g/100),g-=a.donut&&!a.donutSolid?m.value/2:0,h="outside"===a.labelPosition||a.donut&&!a.donutSolid?g:"center"===a.labelPosition?0:a.donutSolid?g-m.value/2:g/2,h+=a.labelOffset;var n={x:e.x1+e.width()/2,y:e.y2+e.height()/2},o=1===j.raw.series.filter(function(a){return a.hasOwnProperty("value")?0!==a.value:0!==a}).length;j.raw.series.forEach(function(a,b){k[b]=this.svg.elem("g",null,null)}.bind(this)),a.showLabel&&(d=this.svg.elem("g",null,null)),j.raw.series.forEach(function(e,f){if(0!==j.normalized.series[f]||!a.ignoreEmptyValues){k[f].attr({"ct:series-name":e.name}),k[f].addClass([a.classNames.series,e.className||a.classNames.series+"-"+b.alphaNumerate(f)].join(" "));var p=i>0?l+j.normalized.series[f]/i*360:0,q=Math.max(0,l-(0===f||o?0:.2));p-q>=359.99&&(p=q+359.99);var r,s,t,u=b.polarToCartesian(n.x,n.y,g,q),v=b.polarToCartesian(n.x,n.y,g,p),w=new b.Svg.Path(!a.donut||a.donutSolid).move(v.x,v.y).arc(g,g,0,p-l>180,0,u.x,u.y);a.donut?a.donutSolid&&(t=g-m.value,r=b.polarToCartesian(n.x,n.y,t,l-(0===f||o?0:.2)),s=b.polarToCartesian(n.x,n.y,t,p),w.line(r.x,r.y),w.arc(t,t,0,p-l>180,1,s.x,s.y)):w.line(n.x,n.y);var x=a.classNames.slicePie;a.donut&&(x=a.classNames.sliceDonut,a.donutSolid&&(x=a.classNames.sliceDonutSolid));var y=k[f].elem("path",{d:w.stringify()},x);if(y.attr({"ct:value":j.normalized.series[f],"ct:meta":b.serialize(e.meta)}),a.donut&&!a.donutSolid&&(y._node.style.strokeWidth=m.value+"px"),this.eventEmitter.emit("draw",{type:"slice",value:j.normalized.series[f],totalDataSum:i,index:f,meta:e.meta,series:e,group:k[f],element:y,path:w.clone(),center:n,radius:g,startAngle:l,endAngle:p}),a.showLabel){var z;z=1===j.raw.series.length?{x:n.x,y:n.y}:b.polarToCartesian(n.x,n.y,h,l+(p-l)/2);var A;A=j.normalized.labels&&!b.isFalseyButZero(j.normalized.labels[f])?j.normalized.labels[f]:j.normalized.series[f];var B=a.labelInterpolationFnc(A,f);if(B||0===B){var C=d.elem("text",{dx:z.x,dy:z.y,"text-anchor":c(n,z,a.labelDirection)},a.classNames.label).text(""+B);this.eventEmitter.emit("draw",{type:"label",index:f,group:d,element:C,text:""+B,x:z.x,y:z.y})}}l=p}}.bind(this)),this.eventEmitter.emit("created",{chartRect:e,svg:this.svg,options:a})}function e(a,c,d,e){b.Pie["super"].constructor.call(this,a,c,f,b.extend({},f,d),e)}var f=(a.window,a.document,{width:void 0,height:void 0,chartPadding:5,classNames:{chartPie:"ct-chart-pie",chartDonut:"ct-chart-donut",series:"ct-series",slicePie:"ct-slice-pie",sliceDonut:"ct-slice-donut",sliceDonutSolid:"ct-slice-donut-solid",label:"ct-label"},startAngle:0,total:void 0,donut:!1,donutSolid:!1,donutWidth:60,showLabel:!0,labelOffset:0,labelPosition:"inside",labelInterpolationFnc:b.noop,labelDirection:"neutral",reverseData:!1,ignoreEmptyValues:!1});b.Pie=b.Base.extend({constructor:e,createChart:d,determineAnchorPosition:c})}(this||global,a),a});
|
10 |
//# sourceMappingURL=chartist.min.js.map
|
resources/js/charts.js
CHANGED
@@ -70,11 +70,27 @@ jQuery.fn.icwpWpsfAjaxChart = function ( aOptions ) {
|
|
70 |
|
71 |
$oChartContainer.html('');
|
72 |
new Chartist.Line(
|
73 |
-
'.icwpAjaxContainerChart',
|
74 |
oResponse.data.chart.data,
|
75 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
axisY: {
|
|
|
77 |
onlyInteger: true,
|
|
|
78 |
labelInterpolationFnc: function ( value ) {
|
79 |
return value;
|
80 |
}
|
70 |
|
71 |
$oChartContainer.html('');
|
72 |
new Chartist.Line(
|
73 |
+
$oThis.selector+' .icwpAjaxContainerChart',
|
74 |
oResponse.data.chart.data,
|
75 |
{
|
76 |
+
height: '100px',
|
77 |
+
fullWidth: true,
|
78 |
+
showArea: false,
|
79 |
+
chartPadding: {
|
80 |
+
top: 10,
|
81 |
+
right: 10,
|
82 |
+
bottom: 10,
|
83 |
+
left: 10
|
84 |
+
},
|
85 |
+
axisX: {
|
86 |
+
offset: 5,
|
87 |
+
showLabel: false,
|
88 |
+
showGrid: false,
|
89 |
+
},
|
90 |
axisY: {
|
91 |
+
offset: 25,
|
92 |
onlyInteger: true,
|
93 |
+
showLabel: true,
|
94 |
labelInterpolationFnc: function ( value ) {
|
95 |
return value;
|
96 |
}
|
resources/js/global-plugin.js
CHANGED
@@ -172,7 +172,7 @@ if ( typeof icwp_wpsf_vars_hp !== 'undefined' ) {
|
|
172 |
jQuery.post( ajaxurl, $aData, function ( oResponse ) {
|
173 |
|
174 |
} ).always( function () {
|
175 |
-
location.reload(
|
176 |
bActivate = null;
|
177 |
}
|
178 |
);
|
172 |
jQuery.post( ajaxurl, $aData, function ( oResponse ) {
|
173 |
|
174 |
} ).always( function () {
|
175 |
+
location.reload();
|
176 |
bActivate = null;
|
177 |
}
|
178 |
);
|
resources/js/shield-comments.js
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/** @var shield_comments object */
|
2 |
+
if ( typeof shield_comments !== 'undefined' ) {
|
3 |
+
var iCWP_WPSF_ShieldCommentGuard = new function () {
|
4 |
+
|
5 |
+
var submitButton;
|
6 |
+
var origButtonValue;
|
7 |
+
var nTimerCounter;
|
8 |
+
var sCountdownTimer;
|
9 |
+
|
10 |
+
this.initialise = function () {
|
11 |
+
jQuery( document ).ready( function () {
|
12 |
+
insertPlaceHolder_Gasp( this );
|
13 |
+
} );
|
14 |
+
};
|
15 |
+
|
16 |
+
var reEnableButton = function () {
|
17 |
+
let nRemaining = shield_comments.vars.cooldown - nTimerCounter;
|
18 |
+
submitButton.value = shield_comments.strings.js_comment_wait.replace( "%s", nRemaining );
|
19 |
+
if ( nTimerCounter >= shield_comments.vars.cooldown ) {
|
20 |
+
submitButton.value = origButtonValue;
|
21 |
+
submitButton.disabled = false;
|
22 |
+
clearInterval( sCountdownTimer );
|
23 |
+
}
|
24 |
+
nTimerCounter++;
|
25 |
+
};
|
26 |
+
|
27 |
+
var assignElements = function ( shiep ) {
|
28 |
+
var maybecheckbox = document.getElementById( '_shieldcb_nombre' );
|
29 |
+
if ( typeof (maybecheckbox) === "undefined" || maybecheckbox === null ) {
|
30 |
+
var cbnombre = document.createElement( "input" );
|
31 |
+
cbnombre.type = "hidden";
|
32 |
+
cbnombre.id = "_shieldcb_nombre";
|
33 |
+
cbnombre.name = "cb_nombre";
|
34 |
+
cbnombre.value = shield_comments.vars.cbname;
|
35 |
+
shiep.appendChild( cbnombre );
|
36 |
+
|
37 |
+
document.body.style.cursor = 'wait';
|
38 |
+
submitButton.disabled = true;
|
39 |
+
|
40 |
+
var aAjaxVars = shield_comments.ajax.comment_token;
|
41 |
+
jQuery.post( aAjaxVars.ajaxurl, aAjaxVars,
|
42 |
+
function ( oResponse ) {
|
43 |
+
if ( typeof (oResponse) !== "undefined" && oResponse !== null ) {
|
44 |
+
if ( oResponse.success ) {
|
45 |
+
var inputBotts = document.createElement( "input" );
|
46 |
+
inputBotts.type = "hidden";
|
47 |
+
inputBotts.name = "botts";
|
48 |
+
inputBotts.value = aAjaxVars.ts;
|
49 |
+
var inputToken = document.createElement( "input" );
|
50 |
+
inputToken.type = "hidden";
|
51 |
+
inputToken.name = "comment_token";
|
52 |
+
inputToken.value = oResponse.data.token;
|
53 |
+
|
54 |
+
shiep.appendChild( inputBotts );
|
55 |
+
shiep.appendChild( inputToken );
|
56 |
+
}
|
57 |
+
}
|
58 |
+
}
|
59 |
+
).fail(
|
60 |
+
function () {
|
61 |
+
alert( 'There was a problem with the request. Please try reloading the page.' );
|
62 |
+
}
|
63 |
+
).always( function () {
|
64 |
+
submitButton.disabled = false;
|
65 |
+
document.body.style.cursor = 'default';
|
66 |
+
}
|
67 |
+
);
|
68 |
+
}
|
69 |
+
};
|
70 |
+
|
71 |
+
var reDisableButton = function () {
|
72 |
+
submitButton.value = shield_comments.strings.comment_reload;
|
73 |
+
submitButton.disabled = true;
|
74 |
+
};
|
75 |
+
|
76 |
+
var insertPlaceHolder_Gasp = function ( form ) {
|
77 |
+
var shiep = document.getElementById( shield_comments.vars.uniq );
|
78 |
+
if ( typeof (shiep) === "undefined" || shiep === null ) {
|
79 |
+
return;
|
80 |
+
}
|
81 |
+
|
82 |
+
var shieThe_cb = document.createElement( "input" );
|
83 |
+
shieThe_cb.type = "checkbox";
|
84 |
+
shieThe_cb.value = "Y";
|
85 |
+
shieThe_cb.name = shield_comments.vars.cbname;
|
86 |
+
shieThe_cb.id = '_' + shieThe_cb.name;
|
87 |
+
shieThe_cb.onchange = function () {
|
88 |
+
assignElements( shiep );
|
89 |
+
};
|
90 |
+
|
91 |
+
var shieThe_lab = document.createElement( "label" );
|
92 |
+
var shieThe_labspan = document.createElement( "span" );
|
93 |
+
shieThe_labspan.innerHTML = ' ' + shield_comments.strings.label;
|
94 |
+
|
95 |
+
shieThe_lab.appendChild( shieThe_cb );
|
96 |
+
shieThe_lab.appendChild( shieThe_labspan );
|
97 |
+
|
98 |
+
var shishoney = document.createElement( "input" );
|
99 |
+
shishoney.type = "hidden";
|
100 |
+
shishoney.name = "sugar_sweet_email";
|
101 |
+
|
102 |
+
shiep.appendChild( shishoney );
|
103 |
+
shiep.appendChild( shieThe_lab );
|
104 |
+
|
105 |
+
var comForm = shieThe_cb.form;
|
106 |
+
var subbuttonList = comForm.querySelectorAll( 'input[type="submit"]' );
|
107 |
+
|
108 |
+
if ( typeof (subbuttonList) !== "undefined" ) {
|
109 |
+
|
110 |
+
submitButton = subbuttonList[ 0 ];
|
111 |
+
|
112 |
+
if ( typeof (submitButton) !== "undefined" ) {
|
113 |
+
|
114 |
+
if ( shield_comments.vars.cooldown > 0 ) {
|
115 |
+
submitButton.disabled = true;
|
116 |
+
origButtonValue = submitButton.value;
|
117 |
+
nTimerCounter = 0;
|
118 |
+
reEnableButton();
|
119 |
+
sCountdownTimer = setInterval( reEnableButton, 1000 );
|
120 |
+
}
|
121 |
+
if ( shield_comments.vars.expires > 0 ) {
|
122 |
+
setTimeout( reDisableButton, (1000 * shield_comments.vars.expires - 1000) );
|
123 |
+
}
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
shieThe_cb.form.onsubmit = function () {
|
128 |
+
if ( shieThe_cb.checked !== true ) {
|
129 |
+
alert( shield_comments.strings.alert );
|
130 |
+
return false;
|
131 |
+
}
|
132 |
+
return true;
|
133 |
+
};
|
134 |
+
};
|
135 |
+
}();
|
136 |
+
iCWP_WPSF_ShieldCommentGuard.initialise();
|
137 |
+
}
|
src/common/icwp-data.php
CHANGED
@@ -135,7 +135,7 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
|
|
135 |
* @return string
|
136 |
*/
|
137 |
public function urlStripSchema( $sUrl ) {
|
138 |
-
return preg_replace( '#^((http|https):)
|
139 |
}
|
140 |
|
141 |
/**
|
@@ -458,7 +458,7 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
|
|
458 |
* @deprecated
|
459 |
*/
|
460 |
public function cookie( $sKey, $mDefault = null, $bTrim = true ) {
|
461 |
-
return
|
462 |
}
|
463 |
|
464 |
/**
|
@@ -468,7 +468,7 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
|
|
468 |
* @deprecated
|
469 |
*/
|
470 |
public function env( $sKey, $mDefault = null ) {
|
471 |
-
return
|
472 |
}
|
473 |
|
474 |
/**
|
@@ -479,7 +479,7 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
|
|
479 |
* @deprecated
|
480 |
*/
|
481 |
public function post( $sKey, $mDefault = null, $bTrim = true ) {
|
482 |
-
return
|
483 |
}
|
484 |
|
485 |
/**
|
@@ -490,7 +490,7 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
|
|
490 |
* @deprecated
|
491 |
*/
|
492 |
public function query( $sKey, $mDefault = null, $bTrim = true ) {
|
493 |
-
return
|
494 |
}
|
495 |
|
496 |
/**
|
135 |
* @return string
|
136 |
*/
|
137 |
public function urlStripSchema( $sUrl ) {
|
138 |
+
return preg_replace( '#^((http|https):)?//#i', '', $sUrl );
|
139 |
}
|
140 |
|
141 |
/**
|
458 |
* @deprecated
|
459 |
*/
|
460 |
public function cookie( $sKey, $mDefault = null, $bTrim = true ) {
|
461 |
+
return \FernleafSystems\Wordpress\Services\Services::Request()->cookie( $sKey, $mDefault );
|
462 |
}
|
463 |
|
464 |
/**
|
468 |
* @deprecated
|
469 |
*/
|
470 |
public function env( $sKey, $mDefault = null ) {
|
471 |
+
return \FernleafSystems\Wordpress\Services\Services::Request()->env( $sKey, $mDefault );
|
472 |
}
|
473 |
|
474 |
/**
|
479 |
* @deprecated
|
480 |
*/
|
481 |
public function post( $sKey, $mDefault = null, $bTrim = true ) {
|
482 |
+
return \FernleafSystems\Wordpress\Services\Services::Request()->post( $sKey, $mDefault );
|
483 |
}
|
484 |
|
485 |
/**
|
490 |
* @deprecated
|
491 |
*/
|
492 |
public function query( $sKey, $mDefault = null, $bTrim = true ) {
|
493 |
+
return \FernleafSystems\Wordpress\Services\Services::Request()->query( $sKey, $mDefault );
|
494 |
}
|
495 |
|
496 |
/**
|
src/common/icwp-edd.php
DELETED
@@ -1,172 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO;
|
4 |
-
use FernleafSystems\Wordpress\Services\Services;
|
5 |
-
|
6 |
-
class ICWP_WPSF_Edd {
|
7 |
-
|
8 |
-
/**
|
9 |
-
* @var ICWP_WPSF_Edd
|
10 |
-
*/
|
11 |
-
protected static $oInstance = null;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var array
|
15 |
-
*/
|
16 |
-
private $aAdditionalRequestParams;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* @return ICWP_WPSF_Edd
|
20 |
-
*/
|
21 |
-
public static function GetInstance() {
|
22 |
-
if ( is_null( self::$oInstance ) ) {
|
23 |
-
self::$oInstance = new self();
|
24 |
-
}
|
25 |
-
return self::$oInstance;
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* A simple outgoing POST request to see that we can communicate with the ODP servers
|
30 |
-
* @param string $sStoreUrl
|
31 |
-
* @return string
|
32 |
-
*/
|
33 |
-
public function ping( $sStoreUrl ) {
|
34 |
-
$sStoreUrl = add_query_arg( [ 'license_ping' => 'Y' ], $sStoreUrl );
|
35 |
-
$aParams = [
|
36 |
-
'body' => [
|
37 |
-
'ping' => 'pong',
|
38 |
-
'license' => 'abcdefghi',
|
39 |
-
'item_id' => '123',
|
40 |
-
'url' => Services::WpGeneral()->getWpUrl()
|
41 |
-
]
|
42 |
-
];
|
43 |
-
|
44 |
-
$oHttpReq = Services::HttpRequest();
|
45 |
-
if ( $oHttpReq->post( $sStoreUrl, $aParams ) ) {
|
46 |
-
$aResult = @json_decode( $oHttpReq->lastResponse->body, true );
|
47 |
-
$sResult = ( isset( $aResult[ 'success' ] ) && $aResult[ 'success' ] ) ? 'success' : 'unknown failure';
|
48 |
-
}
|
49 |
-
else {
|
50 |
-
$sResult = $oHttpReq->lastError->get_error_message();
|
51 |
-
}
|
52 |
-
return $sResult;
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* @param string $sStoreUrl
|
57 |
-
* @param string $sKey
|
58 |
-
* @param string $sItemId
|
59 |
-
* @return \FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO
|
60 |
-
*/
|
61 |
-
public function activateLicense( $sStoreUrl, $sKey, $sItemId ) {
|
62 |
-
return $this->commonLicenseAction( 'activate_license', $sStoreUrl, $sKey, $sItemId );
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* @param string $sStoreUrl
|
67 |
-
* @param string $sItemId
|
68 |
-
* @return \FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO
|
69 |
-
*/
|
70 |
-
public function activateLicenseKeyless( $sStoreUrl, $sItemId ) {
|
71 |
-
return $this->activateLicense( $sStoreUrl, '', $sItemId );
|
72 |
-
}
|
73 |
-
|
74 |
-
/**
|
75 |
-
* @param string $sStoreUrl
|
76 |
-
* @param string $sKey
|
77 |
-
* @param string $sItemId
|
78 |
-
* @return \FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO|null
|
79 |
-
*/
|
80 |
-
public function checkLicense( $sStoreUrl, $sKey, $sItemId ) {
|
81 |
-
return $this->commonLicenseAction( 'check_license', $sStoreUrl, $sKey, $sItemId );
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* @param string $sStoreUrl
|
86 |
-
* @param string $sKey
|
87 |
-
* @param string $sItemId
|
88 |
-
* @return \FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO
|
89 |
-
*/
|
90 |
-
public function deactivateLicense( $sStoreUrl, $sKey, $sItemId ) {
|
91 |
-
return $this->commonLicenseAction( 'deactivate_license', $sStoreUrl, $sKey, $sItemId );
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* @param string $sAction
|
96 |
-
* @param string $sStoreUrl
|
97 |
-
* @param string $sKey
|
98 |
-
* @param string $sItemId
|
99 |
-
* @return EddLicenseVO
|
100 |
-
*/
|
101 |
-
private function commonLicenseAction( $sAction, $sStoreUrl, $sKey, $sItemId ) {
|
102 |
-
$oWp = Services::WpGeneral();
|
103 |
-
$aLicenseLookupParams = [
|
104 |
-
'timeout' => 60,
|
105 |
-
'body' => array_merge(
|
106 |
-
[
|
107 |
-
'edd_action' => $sAction,
|
108 |
-
'license' => $sKey,
|
109 |
-
'item_id' => $sItemId,
|
110 |
-
'url' => $oWp->getHomeUrl(),
|
111 |
-
'alt_url' => $oWp->getWpUrl()
|
112 |
-
],
|
113 |
-
$this->getRequestParams()
|
114 |
-
)
|
115 |
-
];
|
116 |
-
|
117 |
-
return ( new EddLicenseVO() )
|
118 |
-
->applyFromArray( $this->sendReq( $sStoreUrl, $aLicenseLookupParams, false ) )
|
119 |
-
->setLastRequestAt( Services::Request()->ts() );
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* first attempts GET, then POST if the GET is successful but the data is not right
|
124 |
-
* @param string $sUrl
|
125 |
-
* @param array $aArgs
|
126 |
-
* @param bool $bAsPost
|
127 |
-
* @return array
|
128 |
-
*/
|
129 |
-
private function sendReq( $sUrl, $aArgs, $bAsPost = false ) {
|
130 |
-
$aResponse = [];
|
131 |
-
$oHttpReq = Services::HttpRequest();
|
132 |
-
|
133 |
-
if ( $bAsPost ) {
|
134 |
-
if ( $oHttpReq->post( $sUrl, $aArgs ) ) {
|
135 |
-
$aResponse = empty( $oHttpReq->lastResponse->body ) ? [] : @json_decode( $oHttpReq->lastResponse->body, true );
|
136 |
-
}
|
137 |
-
return $aResponse;
|
138 |
-
}
|
139 |
-
else if ( $oHttpReq->get( $sUrl, $aArgs ) ) {
|
140 |
-
$aResponse = empty( $oHttpReq->lastResponse->body ) ? [] : @json_decode( $oHttpReq->lastResponse->body, true );
|
141 |
-
if ( empty( $aResponse ) ) {
|
142 |
-
$aResponse = $this->sendReq( $sUrl, $aArgs, true );
|
143 |
-
}
|
144 |
-
}
|
145 |
-
|
146 |
-
return $aResponse;
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* @param array $aData
|
151 |
-
* @return \FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO
|
152 |
-
*/
|
153 |
-
public function getLicenseVoFromData( $aData ) {
|
154 |
-
return ( new \FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO() )->applyFromArray( $aData );
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* @return array
|
159 |
-
*/
|
160 |
-
public function getRequestParams() {
|
161 |
-
return is_array( $this->aAdditionalRequestParams ) ? $this->aAdditionalRequestParams : [];
|
162 |
-
}
|
163 |
-
|
164 |
-
/**
|
165 |
-
* @param array $aParams
|
166 |
-
* @return $this
|
167 |
-
*/
|
168 |
-
public function setRequestParams( $aParams = [] ) {
|
169 |
-
$this->aAdditionalRequestParams = is_array( $aParams ) ? $aParams : [];
|
170 |
-
return $this;
|
171 |
-
}
|
172 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-foundation.php
CHANGED
@@ -1,14 +1,13 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
3 |
class ICWP_WPSF_Foundation {
|
4 |
|
5 |
const DEFAULT_SERVICE_PREFIX = 'icwp_wpsf_';
|
6 |
|
7 |
-
/**
|
8 |
-
* @var array
|
9 |
-
*/
|
10 |
-
private static $aDic;
|
11 |
-
|
12 |
/**
|
13 |
* @param string $sSuffix
|
14 |
* @return string
|
@@ -16,238 +15,4 @@ class ICWP_WPSF_Foundation {
|
|
16 |
protected function prefix( $sSuffix ) {
|
17 |
return self::DEFAULT_SERVICE_PREFIX.$sSuffix;
|
18 |
}
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @return ICWP_WPSF_DataProcessor
|
22 |
-
*/
|
23 |
-
static public function loadDP() {
|
24 |
-
$sKey = 'icwp-data';
|
25 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
26 |
-
self::setService( $sKey, ICWP_WPSF_DataProcessor::GetInstance() );
|
27 |
-
}
|
28 |
-
return self::getService( $sKey );
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* @return ICWP_WPSF_WpFilesystem
|
33 |
-
*/
|
34 |
-
static public function loadFS() {
|
35 |
-
$sKey = 'icwp-wpfilesystem';
|
36 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
37 |
-
self::setService( $sKey, ICWP_WPSF_WpFilesystem::GetInstance() );
|
38 |
-
}
|
39 |
-
return self::getService( $sKey );
|
40 |
-
}
|
41 |
-
|
42 |
-
/**
|
43 |
-
* @return ICWP_WPSF_WpFunctions
|
44 |
-
*/
|
45 |
-
static public function loadWp() {
|
46 |
-
$sKey = 'icwp-wpfunctions';
|
47 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
48 |
-
self::setService( $sKey, ICWP_WPSF_WpFunctions::GetInstance() );
|
49 |
-
}
|
50 |
-
return self::getService( $sKey );
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* @return ICWP_WPSF_WpFunctions_Plugins
|
55 |
-
* @deprecated
|
56 |
-
*/
|
57 |
-
public function loadWpPlugins() {
|
58 |
-
$sKey = 'icwp-wpfunctions-plugins';
|
59 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
60 |
-
self::setService( $sKey, ICWP_WPSF_WpFunctions_Plugins::GetInstance() );
|
61 |
-
}
|
62 |
-
return self::getService( $sKey );
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* @return ICWP_WPSF_WpFunctions_Themes
|
67 |
-
* @deprecated
|
68 |
-
*/
|
69 |
-
public function loadWpThemes() {
|
70 |
-
$sKey = 'icwp-wpfunctions-themes';
|
71 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
72 |
-
self::setService( $sKey, ICWP_WPSF_WpFunctions_Themes::GetInstance() );
|
73 |
-
}
|
74 |
-
return self::getService( $sKey );
|
75 |
-
}
|
76 |
-
|
77 |
-
/**
|
78 |
-
* @return ICWP_WPSF_WpCron
|
79 |
-
* @deprecated
|
80 |
-
*/
|
81 |
-
static public function loadWpCronProcessor() {
|
82 |
-
$sKey = 'icwp-wpcron';
|
83 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
84 |
-
self::setService( $sKey, ICWP_WPSF_WpCron::GetInstance() );
|
85 |
-
}
|
86 |
-
return self::getService( $sKey );
|
87 |
-
}
|
88 |
-
|
89 |
-
/**
|
90 |
-
* @return ICWP_WPSF_WpUpgrades
|
91 |
-
* @deprecated
|
92 |
-
*/
|
93 |
-
static public function loadWpUpgrades() {
|
94 |
-
$sKey = 'icwp-wpupgrades';
|
95 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
96 |
-
self::setService( $sKey, ICWP_WPSF_WpUpgrades::GetInstance() );
|
97 |
-
}
|
98 |
-
return self::getService( $sKey );
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* @return ICWP_WPSF_WpDb
|
103 |
-
*/
|
104 |
-
static public function loadDbProcessor() {
|
105 |
-
$sKey = 'icwp-wpdb';
|
106 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
107 |
-
self::setService( $sKey, ICWP_WPSF_WpDb::GetInstance() );
|
108 |
-
}
|
109 |
-
return self::getService( $sKey );
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* @return ICWP_WPSF_Request
|
114 |
-
*/
|
115 |
-
public function loadRequest() {
|
116 |
-
$sKey = 'icwp-request';
|
117 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
118 |
-
self::setService( $sKey, ICWP_WPSF_Request::GetInstance() );
|
119 |
-
}
|
120 |
-
return self::getService( $sKey );
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* @return ICWP_WPSF_ServiceProviders
|
125 |
-
*/
|
126 |
-
public function loadServiceProviders() {
|
127 |
-
$sKey = 'icwp-serviceproviders';
|
128 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
129 |
-
self::setService( $sKey, ICWP_WPSF_ServiceProviders::GetInstance() );
|
130 |
-
}
|
131 |
-
return self::getService( $sKey );
|
132 |
-
}
|
133 |
-
|
134 |
-
/**
|
135 |
-
* @return ICWP_WPSF_WpIncludes
|
136 |
-
* @deprecated
|
137 |
-
*/
|
138 |
-
static public function loadWpIncludes() {
|
139 |
-
$sKey = 'icwp-wpincludes';
|
140 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
141 |
-
self::setService( $sKey, ICWP_WPSF_WpIncludes::GetInstance() );
|
142 |
-
}
|
143 |
-
return self::getService( $sKey );
|
144 |
-
}
|
145 |
-
|
146 |
-
/**
|
147 |
-
* @param string $sTemplatePath
|
148 |
-
* @return ICWP_WPSF_Render
|
149 |
-
*/
|
150 |
-
static public function loadRenderer( $sTemplatePath = '' ) {
|
151 |
-
$sKey = 'icwp-render';
|
152 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
153 |
-
self::setService( $sKey, ICWP_WPSF_Render::GetInstance() );
|
154 |
-
}
|
155 |
-
|
156 |
-
/** @var ICWP_WPSF_Render $oR */
|
157 |
-
$oR = self::getService( $sKey );
|
158 |
-
if ( !empty( $sTemplatePath ) ) {
|
159 |
-
$oR->setTemplateRoot( $sTemplatePath );
|
160 |
-
}
|
161 |
-
return ( clone $oR );
|
162 |
-
}
|
163 |
-
|
164 |
-
/**
|
165 |
-
* @return ICWP_WPSF_WpAdminNotices
|
166 |
-
*/
|
167 |
-
static public function loadWpNotices() {
|
168 |
-
$sKey = 'wp-admin-notices';
|
169 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
170 |
-
self::setService( $sKey, ICWP_WPSF_WpAdminNotices::GetInstance() );
|
171 |
-
}
|
172 |
-
return self::getService( $sKey );
|
173 |
-
}
|
174 |
-
|
175 |
-
/**
|
176 |
-
* @return ICWP_WPSF_WpUsers
|
177 |
-
*/
|
178 |
-
static public function loadWpUsers() {
|
179 |
-
$sKey = 'wp-users';
|
180 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
181 |
-
self::setService( $sKey, ICWP_WPSF_WpUsers::GetInstance() );
|
182 |
-
}
|
183 |
-
return self::getService( $sKey );
|
184 |
-
}
|
185 |
-
|
186 |
-
/**
|
187 |
-
* @return ICWP_WPSF_WpComments
|
188 |
-
*/
|
189 |
-
static public function loadWpComments() {
|
190 |
-
$sKey = 'wp-comments';
|
191 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
192 |
-
self::setService( $sKey, ICWP_WPSF_WpComments::GetInstance() );
|
193 |
-
}
|
194 |
-
return self::getService( $sKey );
|
195 |
-
}
|
196 |
-
|
197 |
-
/**
|
198 |
-
* @return ICWP_WPSF_Edd
|
199 |
-
*/
|
200 |
-
static public function loadEdd() {
|
201 |
-
$sKey = 'icwp-edd';
|
202 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
203 |
-
self::setService( $sKey, ICWP_WPSF_Edd::GetInstance() );
|
204 |
-
}
|
205 |
-
return self::getService( $sKey );
|
206 |
-
}
|
207 |
-
|
208 |
-
/**
|
209 |
-
* @return array
|
210 |
-
*/
|
211 |
-
static private function getDic() {
|
212 |
-
if ( !is_array( self::$aDic ) ) {
|
213 |
-
self::$aDic = [];
|
214 |
-
}
|
215 |
-
return self::$aDic;
|
216 |
-
}
|
217 |
-
|
218 |
-
/**
|
219 |
-
* @param string $sService
|
220 |
-
* @return mixed
|
221 |
-
*/
|
222 |
-
static private function getService( $sService ) {
|
223 |
-
$aDic = self::getDic();
|
224 |
-
return $aDic[ $sService ];
|
225 |
-
}
|
226 |
-
|
227 |
-
/**
|
228 |
-
* @param string $sService
|
229 |
-
* @return bool
|
230 |
-
*/
|
231 |
-
static private function isServiceReady( $sService ) {
|
232 |
-
$aDic = self::getDic();
|
233 |
-
return !empty( $aDic[ $sService ] );
|
234 |
-
}
|
235 |
-
|
236 |
-
/**
|
237 |
-
* @param string $sServiceKey
|
238 |
-
* @param mixed $oService
|
239 |
-
*/
|
240 |
-
static private function setService( $sServiceKey, $oService ) {
|
241 |
-
$aDic = self::getDic();
|
242 |
-
$aDic[ $sServiceKey ] = $oService;
|
243 |
-
self::$aDic = $aDic;
|
244 |
-
}
|
245 |
-
|
246 |
-
/**
|
247 |
-
* @return ICWP_WPSF_WpAdminNotices
|
248 |
-
* @deprecated
|
249 |
-
*/
|
250 |
-
static public function loadAdminNoticesProcessor() {
|
251 |
-
return self::loadWpNotices();
|
252 |
-
}
|
253 |
}
|
1 |
<?php
|
2 |
|
3 |
+
/**
|
4 |
+
* Class ICWP_WPSF_Foundation
|
5 |
+
* @deprecated 8.4
|
6 |
+
*/
|
7 |
class ICWP_WPSF_Foundation {
|
8 |
|
9 |
const DEFAULT_SERVICE_PREFIX = 'icwp_wpsf_';
|
10 |
|
|
|
|
|
|
|
|
|
|
|
11 |
/**
|
12 |
* @param string $sSuffix
|
13 |
* @return string
|
15 |
protected function prefix( $sSuffix ) {
|
16 |
return self::DEFAULT_SERVICE_PREFIX.$sSuffix;
|
17 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
}
|
src/common/icwp-optionsvo.php
DELETED
@@ -1,991 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Services\Services;
|
4 |
-
|
5 |
-
class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @var array
|
9 |
-
*/
|
10 |
-
protected $aOptionsValues;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var array
|
14 |
-
*/
|
15 |
-
protected $aOld;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var array
|
19 |
-
*/
|
20 |
-
protected $aRawOptionsConfigData;
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @var boolean
|
24 |
-
*/
|
25 |
-
protected $bNeedSave;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @var boolean
|
29 |
-
*/
|
30 |
-
protected $bRebuildFromFile = false;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @var string
|
34 |
-
*/
|
35 |
-
protected $aOptionsKeys;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* @var string
|
39 |
-
*/
|
40 |
-
protected $sOptionsStorageKey;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* by default we load from saved
|
44 |
-
* @var string
|
45 |
-
*/
|
46 |
-
protected $bLoadFromSaved = true;
|
47 |
-
|
48 |
-
/**
|
49 |
-
* @var string
|
50 |
-
*/
|
51 |
-
protected $sPathToConfig;
|
52 |
-
|
53 |
-
/**
|
54 |
-
*/
|
55 |
-
public function __construct() {
|
56 |
-
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* @return bool
|
60 |
-
*/
|
61 |
-
public function cleanTransientStorage() {
|
62 |
-
return $this->loadWp()->deleteTransient( $this->getSpecTransientStorageKey() );
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* @param bool $bDeleteFirst Used primarily with plugin reset
|
67 |
-
* @param bool $bIsPremiumLicensed
|
68 |
-
* @return bool
|
69 |
-
*/
|
70 |
-
public function doOptionsSave( $bDeleteFirst = false, $bIsPremiumLicensed = false ) {
|
71 |
-
if ( !$this->getNeedSave() ) {
|
72 |
-
return true;
|
73 |
-
}
|
74 |
-
$this->cleanOptions();
|
75 |
-
if ( !$bIsPremiumLicensed ) {
|
76 |
-
$this->resetPremiumOptsToDefault();
|
77 |
-
}
|
78 |
-
$this->setNeedSave( false );
|
79 |
-
if ( $bDeleteFirst ) {
|
80 |
-
$this->loadWp()->deleteOption( $this->getOptionsStorageKey() );
|
81 |
-
}
|
82 |
-
return $this->loadWp()->updateOption( $this->getOptionsStorageKey(), $this->getAllOptionsValues() );
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* @return bool
|
87 |
-
*/
|
88 |
-
public function doOptionsDelete() {
|
89 |
-
$oWp = $this->loadWp();
|
90 |
-
$oWp->deleteTransient( $this->getSpecTransientStorageKey() );
|
91 |
-
return $oWp->deleteOption( $this->getOptionsStorageKey() );
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* @return array
|
96 |
-
*/
|
97 |
-
public function getAllOptionsValues() {
|
98 |
-
return $this->getStoredOptions();
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* @return string
|
103 |
-
*/
|
104 |
-
public function getSlug() {
|
105 |
-
return $this->getFeatureProperty( 'slug' );
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Returns an array of all the transferable options and their values
|
110 |
-
* @return array
|
111 |
-
*/
|
112 |
-
public function getTransferableOptions() {
|
113 |
-
$aTransferable = [];
|
114 |
-
|
115 |
-
foreach ( $this->getRawData_AllOptions() as $nKey => $aOptionData ) {
|
116 |
-
if ( !isset( $aOptionData[ 'transferable' ] ) || $aOptionData[ 'transferable' ] === true ) {
|
117 |
-
$aTransferable[ $aOptionData[ 'key' ] ] = $this->getOpt( $aOptionData[ 'key' ] );
|
118 |
-
}
|
119 |
-
}
|
120 |
-
return $aTransferable;
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Returns an array of all the options with the values for "sensitive" options masked out.
|
125 |
-
* @return array
|
126 |
-
*/
|
127 |
-
public function getOptionsMaskSensitive() {
|
128 |
-
|
129 |
-
$aOptions = $this->getAllOptionsValues();
|
130 |
-
foreach ( $this->getOptionsKeys() as $sKey ) {
|
131 |
-
if ( !isset( $aOptions[ $sKey ] ) ) {
|
132 |
-
$aOptions[ $sKey ] = $this->getOptDefault( $sKey );
|
133 |
-
}
|
134 |
-
}
|
135 |
-
foreach ( $this->getRawData_AllOptions() as $nKey => $aOptionData ) {
|
136 |
-
if ( isset( $aOptionData[ 'sensitive' ] ) && $aOptionData[ 'sensitive' ] === true ) {
|
137 |
-
unset( $aOptions[ $aOptionData[ 'key' ] ] );
|
138 |
-
}
|
139 |
-
}
|
140 |
-
return $aOptions;
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* @param $sProperty
|
145 |
-
* @return null|mixed
|
146 |
-
*/
|
147 |
-
public function getFeatureProperty( $sProperty ) {
|
148 |
-
$aRawConfig = $this->getRawData_FullFeatureConfig();
|
149 |
-
return ( isset( $aRawConfig[ 'properties' ] ) && isset( $aRawConfig[ 'properties' ][ $sProperty ] ) ) ? $aRawConfig[ 'properties' ][ $sProperty ] : null;
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* @param string
|
154 |
-
* @return null|array
|
155 |
-
*/
|
156 |
-
public function getFeatureDefinition( $sDefinition ) {
|
157 |
-
$aRawConfig = $this->getRawData_FullFeatureConfig();
|
158 |
-
return ( isset( $aRawConfig[ 'definitions' ] ) && isset( $aRawConfig[ 'definitions' ][ $sDefinition ] ) ) ? $aRawConfig[ 'definitions' ][ $sDefinition ] : null;
|
159 |
-
}
|
160 |
-
|
161 |
-
/**
|
162 |
-
* @param string $sReq
|
163 |
-
* @return null|mixed
|
164 |
-
*/
|
165 |
-
public function getFeatureRequirement( $sReq ) {
|
166 |
-
$aReqs = $this->getRawData_Requirements();
|
167 |
-
return ( is_array( $aReqs ) && isset( $aReqs[ $sReq ] ) ) ? $aReqs[ $sReq ] : null;
|
168 |
-
}
|
169 |
-
|
170 |
-
/**
|
171 |
-
* @return array
|
172 |
-
*/
|
173 |
-
public function getAdminNotices() {
|
174 |
-
$aRawConfig = $this->getRawData_FullFeatureConfig();
|
175 |
-
return ( isset( $aRawConfig[ 'admin_notices' ] ) && is_array( $aRawConfig[ 'admin_notices' ] ) ) ? $aRawConfig[ 'admin_notices' ] : [];
|
176 |
-
}
|
177 |
-
|
178 |
-
/**
|
179 |
-
* @return string
|
180 |
-
*/
|
181 |
-
public function getFeatureTagline() {
|
182 |
-
return $this->getFeatureProperty( 'tagline' );
|
183 |
-
}
|
184 |
-
|
185 |
-
/**
|
186 |
-
* @return boolean
|
187 |
-
*/
|
188 |
-
public function getIfLoadOptionsFromStorage() {
|
189 |
-
return $this->bLoadFromSaved;
|
190 |
-
}
|
191 |
-
|
192 |
-
/**
|
193 |
-
* Determines whether the given option key is a valid option
|
194 |
-
* @param string
|
195 |
-
* @return boolean
|
196 |
-
*/
|
197 |
-
public function isValidOptionKey( $sOptionKey ) {
|
198 |
-
return in_array( $sOptionKey, $this->getOptionsKeys() );
|
199 |
-
}
|
200 |
-
|
201 |
-
/**
|
202 |
-
* @return array[]
|
203 |
-
*/
|
204 |
-
public function getHiddenOptions() {
|
205 |
-
|
206 |
-
$aOptionsData = [];
|
207 |
-
|
208 |
-
foreach ( $this->getRawData_OptionsSections() as $nPosition => $aRawSection ) {
|
209 |
-
|
210 |
-
// if hidden isn't specified we skip
|
211 |
-
if ( !isset( $aRawSection[ 'hidden' ] ) || !$aRawSection[ 'hidden' ] ) {
|
212 |
-
continue;
|
213 |
-
}
|
214 |
-
foreach ( $this->getRawData_AllOptions() as $aRawOption ) {
|
215 |
-
|
216 |
-
if ( $aRawOption[ 'section' ] != $aRawSection[ 'slug' ] ) {
|
217 |
-
continue;
|
218 |
-
}
|
219 |
-
$aOptionsData[ $aRawOption[ 'key' ] ] = $this->getOpt( $aRawOption[ 'key' ] );
|
220 |
-
}
|
221 |
-
}
|
222 |
-
return $aOptionsData;
|
223 |
-
}
|
224 |
-
|
225 |
-
/**
|
226 |
-
* @param string $sSlug
|
227 |
-
* @return array|null
|
228 |
-
*/
|
229 |
-
public function getSection( $sSlug ) {
|
230 |
-
$aSections = $this->getSections();
|
231 |
-
return isset( $aSections[ $sSlug ] ) ? $aSections[ $sSlug ] : null;
|
232 |
-
}
|
233 |
-
|
234 |
-
/**
|
235 |
-
* @param bool $bIncludeHidden
|
236 |
-
* @return array[]
|
237 |
-
*/
|
238 |
-
public function getSections( $bIncludeHidden = false ) {
|
239 |
-
$aSections = [];
|
240 |
-
foreach ( $this->getRawData_OptionsSections() as $aRawSection ) {
|
241 |
-
if ( $bIncludeHidden || !isset( $aRawSection[ 'hidden' ] ) || !$aRawSection[ 'hidden' ] ) {
|
242 |
-
$aSections[ $aRawSection[ 'slug' ] ] = $aRawSection;
|
243 |
-
}
|
244 |
-
}
|
245 |
-
return $aSections;
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* @return array
|
250 |
-
*/
|
251 |
-
public function getPrimarySection() {
|
252 |
-
$aSec = [];
|
253 |
-
foreach ( $this->getSections() as $aS ) {
|
254 |
-
if ( isset( $aS[ 'primary' ] ) && $aS[ 'primary' ] ) {
|
255 |
-
$aSec = $aS;
|
256 |
-
break;
|
257 |
-
}
|
258 |
-
}
|
259 |
-
return $aSec;
|
260 |
-
}
|
261 |
-
|
262 |
-
/**
|
263 |
-
* @param string $sSlug
|
264 |
-
* @return array
|
265 |
-
*/
|
266 |
-
public function getSection_Requirements( $sSlug ) {
|
267 |
-
$aSection = $this->getSection( $sSlug );
|
268 |
-
$aReqs = ( is_array( $aSection ) && isset( $aSection[ 'reqs' ] ) ) ? $aSection[ 'reqs' ] : [];
|
269 |
-
return array_merge(
|
270 |
-
[
|
271 |
-
'php_min' => '5.2.4',
|
272 |
-
'wp_min' => '3.5.0',
|
273 |
-
],
|
274 |
-
$aReqs
|
275 |
-
);
|
276 |
-
}
|
277 |
-
|
278 |
-
/**
|
279 |
-
* @param string $sSlug
|
280 |
-
* @return array|null
|
281 |
-
*/
|
282 |
-
public function getSectionHelpVideo( $sSlug ) {
|
283 |
-
$aSection = $this->getSection( $sSlug );
|
284 |
-
return ( is_array( $aSection ) && isset( $aSection[ 'help_video' ] ) ) ? $aSection[ 'help_video' ] : null;
|
285 |
-
}
|
286 |
-
|
287 |
-
/**
|
288 |
-
* @param string $sSectionSlug
|
289 |
-
* @return bool
|
290 |
-
*/
|
291 |
-
public function isSectionReqsMet( $sSectionSlug ) {
|
292 |
-
$aReqs = $this->getSection_Requirements( $sSectionSlug );
|
293 |
-
$bMet = Services::Data()->getPhpVersionIsAtLeast( $aReqs[ 'php_min' ] )
|
294 |
-
&& Services::WpGeneral()->getWordpressIsAtLeastVersion( $aReqs[ 'wp_min' ] );
|
295 |
-
return $bMet;
|
296 |
-
}
|
297 |
-
|
298 |
-
/**
|
299 |
-
* @param string $sOptKey
|
300 |
-
* @return bool
|
301 |
-
*/
|
302 |
-
public function isOptReqsMet( $sOptKey ) {
|
303 |
-
return $this->isSectionReqsMet( $this->getOptProperty( $sOptKey, 'section' ) );
|
304 |
-
}
|
305 |
-
|
306 |
-
/**
|
307 |
-
* @return string[]
|
308 |
-
*/
|
309 |
-
public function getVisibleOptionsKeys() {
|
310 |
-
$aKeys = [];
|
311 |
-
|
312 |
-
foreach ( $this->getRawData_AllOptions() as $aOptionDef ) {
|
313 |
-
if ( isset( $aOptionDef[ 'hidden' ] ) && $aOptionDef[ 'hidden' ] ) {
|
314 |
-
continue;
|
315 |
-
}
|
316 |
-
$aSection = $this->getSection( $aOptionDef[ 'section' ] );
|
317 |
-
if ( empty( $aSection ) || ( isset( $aSection[ 'hidden' ] ) && $aSection[ 'hidden' ] ) ) {
|
318 |
-
continue;
|
319 |
-
}
|
320 |
-
|
321 |
-
$aKeys[] = $aOptionDef[ 'key' ];
|
322 |
-
}
|
323 |
-
|
324 |
-
return $aKeys;
|
325 |
-
}
|
326 |
-
|
327 |
-
/**
|
328 |
-
* @return array
|
329 |
-
*/
|
330 |
-
public function getOptionsForPluginUse() {
|
331 |
-
|
332 |
-
$aOptionsData = [];
|
333 |
-
|
334 |
-
foreach ( $this->getRawData_OptionsSections() as $aRawSection ) {
|
335 |
-
|
336 |
-
if ( isset( $aRawSection[ 'hidden' ] ) && $aRawSection[ 'hidden' ] ) {
|
337 |
-
continue;
|
338 |
-
}
|
339 |
-
|
340 |
-
$aRawSection = array_merge(
|
341 |
-
[
|
342 |
-
'primary' => false,
|
343 |
-
'options' => $this->getOptionsForSection( $aRawSection[ 'slug' ] ),
|
344 |
-
'help_video_id' => ''
|
345 |
-
],
|
346 |
-
$aRawSection
|
347 |
-
);
|
348 |
-
|
349 |
-
if ( !empty( $aRawSection[ 'options' ] ) ) {
|
350 |
-
$aOptionsData[] = $aRawSection;
|
351 |
-
}
|
352 |
-
}
|
353 |
-
|
354 |
-
return $aOptionsData;
|
355 |
-
}
|
356 |
-
|
357 |
-
/**
|
358 |
-
* @param string $sSectionSlug
|
359 |
-
* @return array[]
|
360 |
-
*/
|
361 |
-
protected function getOptionsForSection( $sSectionSlug ) {
|
362 |
-
|
363 |
-
$aAllOptions = [];
|
364 |
-
foreach ( $this->getRawData_AllOptions() as $aOptionDef ) {
|
365 |
-
|
366 |
-
if ( ( $aOptionDef[ 'section' ] != $sSectionSlug ) || ( isset( $aOptionDef[ 'hidden' ] ) && $aOptionDef[ 'hidden' ] ) ) {
|
367 |
-
continue;
|
368 |
-
}
|
369 |
-
|
370 |
-
if ( isset( $aOptionDef[ 'hidden' ] ) && $aOptionDef[ 'hidden' ] ) {
|
371 |
-
continue;
|
372 |
-
}
|
373 |
-
|
374 |
-
$aOptionDef = array_merge(
|
375 |
-
[
|
376 |
-
'link_info' => '',
|
377 |
-
'link_blog' => '',
|
378 |
-
'help_video_id' => '',
|
379 |
-
'value_options' => []
|
380 |
-
],
|
381 |
-
$aOptionDef
|
382 |
-
);
|
383 |
-
$aOptionDef[ 'value' ] = $this->getOpt( $aOptionDef[ 'key' ] );
|
384 |
-
|
385 |
-
if ( in_array( $aOptionDef[ 'type' ], [ 'select', 'multiple_select' ] ) ) {
|
386 |
-
$aNewValueOptions = [];
|
387 |
-
foreach ( $aOptionDef[ 'value_options' ] as $aValueOptions ) {
|
388 |
-
$aNewValueOptions[ $aValueOptions[ 'value_key' ] ] = __( $aValueOptions[ 'text' ], 'wp-simple-firewall' );
|
389 |
-
}
|
390 |
-
$aOptionDef[ 'value_options' ] = $aNewValueOptions;
|
391 |
-
}
|
392 |
-
|
393 |
-
$aAllOptions[] = $aOptionDef;
|
394 |
-
}
|
395 |
-
return $aAllOptions;
|
396 |
-
}
|
397 |
-
|
398 |
-
/**
|
399 |
-
* @return array
|
400 |
-
*/
|
401 |
-
public function getAdditionalMenuItems() {
|
402 |
-
return $this->getRawData_MenuItems();
|
403 |
-
}
|
404 |
-
|
405 |
-
/**
|
406 |
-
* @return string
|
407 |
-
*/
|
408 |
-
public function getNeedSave() {
|
409 |
-
return $this->bNeedSave;
|
410 |
-
}
|
411 |
-
|
412 |
-
/**
|
413 |
-
* @param string $sKey
|
414 |
-
* @return mixed|null
|
415 |
-
*/
|
416 |
-
public function getOldValue( $sKey ) {
|
417 |
-
return $this->isOptChanged( $sKey ) ? $this->aOld[ $sKey ] : null;
|
418 |
-
}
|
419 |
-
|
420 |
-
/**
|
421 |
-
* @param string $sOptionKey
|
422 |
-
* @param mixed $mDefault
|
423 |
-
* @return mixed
|
424 |
-
*/
|
425 |
-
public function getOpt( $sOptionKey, $mDefault = false ) {
|
426 |
-
$aOptionsValues = $this->getAllOptionsValues();
|
427 |
-
if ( !isset( $aOptionsValues[ $sOptionKey ] ) && $this->isValidOptionKey( $sOptionKey ) ) {
|
428 |
-
$this->setOpt( $sOptionKey, $this->getOptDefault( $sOptionKey, $mDefault ) );
|
429 |
-
}
|
430 |
-
return isset( $this->aOptionsValues[ $sOptionKey ] ) ? $this->aOptionsValues[ $sOptionKey ] : $mDefault;
|
431 |
-
}
|
432 |
-
|
433 |
-
/**
|
434 |
-
* @param string $sOptionKey
|
435 |
-
* @param mixed $mDefault
|
436 |
-
* @return mixed|null
|
437 |
-
*/
|
438 |
-
public function getOptDefault( $sOptionKey, $mDefault = null ) {
|
439 |
-
foreach ( $this->getRawData_AllOptions() as $aOption ) {
|
440 |
-
if ( $aOption[ 'key' ] == $sOptionKey ) {
|
441 |
-
if ( isset( $aOption[ 'default' ] ) ) {
|
442 |
-
$mDefault = $aOption[ 'default' ];
|
443 |
-
break;
|
444 |
-
}
|
445 |
-
if ( isset( $aOption[ 'value' ] ) ) {
|
446 |
-
$mDefault = $aOption[ 'value' ];
|
447 |
-
break;
|
448 |
-
}
|
449 |
-
}
|
450 |
-
}
|
451 |
-
return $mDefault;
|
452 |
-
}
|
453 |
-
|
454 |
-
/**
|
455 |
-
* @param string $sOptionKey
|
456 |
-
* @return array
|
457 |
-
*/
|
458 |
-
public function getOptDefinition( $sOptionKey ) {
|
459 |
-
$aDef = [];
|
460 |
-
foreach ( $this->getRawData_AllOptions() as $aOption ) {
|
461 |
-
if ( $aOption[ 'key' ] == $sOptionKey ) {
|
462 |
-
$aDef = $aOption;
|
463 |
-
break;
|
464 |
-
}
|
465 |
-
}
|
466 |
-
return $aDef;
|
467 |
-
}
|
468 |
-
|
469 |
-
/**
|
470 |
-
* @param $sKey
|
471 |
-
* @param mixed $mValueToTest
|
472 |
-
* @param boolean $bStrict
|
473 |
-
* @return bool
|
474 |
-
*/
|
475 |
-
public function getOptIs( $sKey, $mValueToTest, $bStrict = false ) {
|
476 |
-
$mOptionValue = $this->getOpt( $sKey );
|
477 |
-
return $bStrict ? $mOptionValue === $mValueToTest : $mOptionValue == $mValueToTest;
|
478 |
-
}
|
479 |
-
|
480 |
-
/**
|
481 |
-
* @param string $sKey
|
482 |
-
* @return string|null
|
483 |
-
*/
|
484 |
-
public function getOptionType( $sKey ) {
|
485 |
-
$aDef = $this->getRawData_SingleOption( $sKey );
|
486 |
-
if ( !empty( $aDef ) && isset( $aDef[ 'type' ] ) ) {
|
487 |
-
return $aDef[ 'type' ];
|
488 |
-
}
|
489 |
-
return null;
|
490 |
-
}
|
491 |
-
|
492 |
-
/**
|
493 |
-
* @return array
|
494 |
-
*/
|
495 |
-
public function getOptionsKeys() {
|
496 |
-
if ( !isset( $this->aOptionsKeys ) ) {
|
497 |
-
$this->aOptionsKeys = [];
|
498 |
-
foreach ( $this->getRawData_AllOptions() as $aOption ) {
|
499 |
-
$this->aOptionsKeys[] = $aOption[ 'key' ];
|
500 |
-
}
|
501 |
-
$this->aOptionsKeys = array_merge( $this->aOptionsKeys, $this->getCommonStandardOptions() );
|
502 |
-
}
|
503 |
-
return $this->aOptionsKeys;
|
504 |
-
}
|
505 |
-
|
506 |
-
/**
|
507 |
-
* @return string
|
508 |
-
*/
|
509 |
-
public function getPathToConfig() {
|
510 |
-
return $this->sPathToConfig;
|
511 |
-
}
|
512 |
-
|
513 |
-
/**
|
514 |
-
* @return string
|
515 |
-
*/
|
516 |
-
protected function getConfigModTime() {
|
517 |
-
return Services::WpFs()->getModifiedTime( $this->getPathToConfig() );
|
518 |
-
}
|
519 |
-
|
520 |
-
/**
|
521 |
-
* @return string
|
522 |
-
*/
|
523 |
-
public function getOptionsStorageKey() {
|
524 |
-
return $this->sOptionsStorageKey;
|
525 |
-
}
|
526 |
-
|
527 |
-
/**
|
528 |
-
* @param string $sOptKey
|
529 |
-
* @param string $sProperty
|
530 |
-
* @return mixed|null
|
531 |
-
*/
|
532 |
-
public function getOptProperty( $sOptKey, $sProperty ) {
|
533 |
-
$aOpt = $this->getRawData_SingleOption( $sOptKey );
|
534 |
-
return ( is_array( $aOpt ) && isset( $aOpt[ $sProperty ] ) ) ? $aOpt[ $sProperty ] : null;
|
535 |
-
}
|
536 |
-
|
537 |
-
/**
|
538 |
-
* @return array
|
539 |
-
*/
|
540 |
-
public function getStoredOptions() {
|
541 |
-
try {
|
542 |
-
return $this->loadOptionsValuesFromStorage();
|
543 |
-
}
|
544 |
-
catch ( Exception $oE ) {
|
545 |
-
return [];
|
546 |
-
}
|
547 |
-
}
|
548 |
-
|
549 |
-
/**
|
550 |
-
* @return array
|
551 |
-
*/
|
552 |
-
public function getRawData_FullFeatureConfig() {
|
553 |
-
if ( empty( $this->aRawOptionsConfigData ) ) {
|
554 |
-
$this->aRawOptionsConfigData = $this->readConfiguration();
|
555 |
-
}
|
556 |
-
return $this->aRawOptionsConfigData;
|
557 |
-
}
|
558 |
-
|
559 |
-
/**
|
560 |
-
* Return the section of the Raw config that is the "options" key only.
|
561 |
-
* @return array
|
562 |
-
*/
|
563 |
-
protected function getRawData_AllOptions() {
|
564 |
-
$aRaw = $this->getRawData_FullFeatureConfig();
|
565 |
-
return ( isset( $aRaw[ 'options' ] ) && is_array( $aRaw[ 'options' ] ) ) ? $aRaw[ 'options' ] : [];
|
566 |
-
}
|
567 |
-
|
568 |
-
/**
|
569 |
-
* Return the section of the Raw config that is the "options" key only.
|
570 |
-
* @return array
|
571 |
-
*/
|
572 |
-
protected function getRawData_OptionsSections() {
|
573 |
-
$aAllRawOptions = $this->getRawData_FullFeatureConfig();
|
574 |
-
return isset( $aAllRawOptions[ 'sections' ] ) ? $aAllRawOptions[ 'sections' ] : [];
|
575 |
-
}
|
576 |
-
|
577 |
-
/**
|
578 |
-
* Return the section of the Raw config that is the "options" key only.
|
579 |
-
* @return array
|
580 |
-
*/
|
581 |
-
protected function getRawData_Requirements() {
|
582 |
-
$aAllRawOptions = $this->getRawData_FullFeatureConfig();
|
583 |
-
return isset( $aAllRawOptions[ 'requirements' ] ) ? $aAllRawOptions[ 'requirements' ] : [];
|
584 |
-
}
|
585 |
-
|
586 |
-
/**
|
587 |
-
* Return the section of the Raw config that is the "options" key only.
|
588 |
-
* @return array
|
589 |
-
*/
|
590 |
-
protected function getRawData_MenuItems() {
|
591 |
-
$aAllRawOptions = $this->getRawData_FullFeatureConfig();
|
592 |
-
return isset( $aAllRawOptions[ 'menu_items' ] ) ? $aAllRawOptions[ 'menu_items' ] : [];
|
593 |
-
}
|
594 |
-
|
595 |
-
/**
|
596 |
-
* Return the section of the Raw config that is the "options" key only.
|
597 |
-
* @param string $sOptionKey
|
598 |
-
* @return array
|
599 |
-
*/
|
600 |
-
public function getRawData_SingleOption( $sOptionKey ) {
|
601 |
-
foreach ( $this->getRawData_AllOptions() as $aOption ) {
|
602 |
-
if ( isset( $aOption[ 'key' ] ) && ( $sOptionKey == $aOption[ 'key' ] ) ) {
|
603 |
-
return $aOption;
|
604 |
-
}
|
605 |
-
}
|
606 |
-
return null;
|
607 |
-
}
|
608 |
-
|
609 |
-
/**
|
610 |
-
* @return boolean
|
611 |
-
*/
|
612 |
-
public function getRebuildFromFile() {
|
613 |
-
return $this->bRebuildFromFile;
|
614 |
-
}
|
615 |
-
|
616 |
-
/**
|
617 |
-
* @param string $sKey
|
618 |
-
* @return string
|
619 |
-
*/
|
620 |
-
public function getSelectOptionValueText( $sKey ) {
|
621 |
-
$sText = '';
|
622 |
-
foreach ( $this->getOptDefinition( $sKey )[ 'value_options' ] as $aOpt ) {
|
623 |
-
if ( $aOpt[ 'value_key' ] == $this->getOpt( $sKey ) ) {
|
624 |
-
$sText = $aOpt[ 'text' ];
|
625 |
-
break;
|
626 |
-
}
|
627 |
-
}
|
628 |
-
return $sText;
|
629 |
-
}
|
630 |
-
|
631 |
-
/**
|
632 |
-
* @return bool
|
633 |
-
*/
|
634 |
-
public function isAccessRestricted() {
|
635 |
-
$bAccessRestricted = $this->getFeatureProperty( 'access_restricted' );
|
636 |
-
return is_null( $bAccessRestricted ) ? true : (bool)$bAccessRestricted;
|
637 |
-
}
|
638 |
-
|
639 |
-
/**
|
640 |
-
* @return bool
|
641 |
-
*/
|
642 |
-
public function isModulePremium() {
|
643 |
-
return (bool)$this->getFeatureProperty( 'premium' );
|
644 |
-
}
|
645 |
-
|
646 |
-
/**
|
647 |
-
* @return bool
|
648 |
-
*/
|
649 |
-
public function isModuleRunIfWhitelisted() {
|
650 |
-
$bState = $this->getFeatureProperty( 'run_if_whitelisted' );
|
651 |
-
return is_null( $bState ) ? true : (bool)$bState;
|
652 |
-
}
|
653 |
-
|
654 |
-
/**
|
655 |
-
* @return bool
|
656 |
-
*/
|
657 |
-
public function isModuleRunUnderWpCli() {
|
658 |
-
$bState = $this->getFeatureProperty( 'run_if_wpcli' );
|
659 |
-
return is_null( $bState ) ? true : (bool)$bState;
|
660 |
-
}
|
661 |
-
|
662 |
-
/**
|
663 |
-
* @return bool
|
664 |
-
*/
|
665 |
-
public function isModuleRunIfVerifiedBot() {
|
666 |
-
return (bool)$this->getFeatureProperty( 'run_if_verified_bot' );
|
667 |
-
}
|
668 |
-
|
669 |
-
/**
|
670 |
-
* @param string $sKey
|
671 |
-
* @return bool
|
672 |
-
*/
|
673 |
-
public function isOptChanged( $sKey ) {
|
674 |
-
return is_array( $this->aOld ) && isset( $this->aOld[ $sKey ] );
|
675 |
-
}
|
676 |
-
|
677 |
-
/**
|
678 |
-
* @param string $sOptionKey
|
679 |
-
* @return bool true if premium is set and true, false otherwise.
|
680 |
-
*/
|
681 |
-
public function isOptPremium( $sOptionKey ) {
|
682 |
-
return (bool)$this->getOptProperty( $sOptionKey, 'premium' );
|
683 |
-
}
|
684 |
-
|
685 |
-
/**
|
686 |
-
* @param string $sOptionKey
|
687 |
-
* @return boolean
|
688 |
-
*/
|
689 |
-
public function resetOptToDefault( $sOptionKey ) {
|
690 |
-
return $this->setOpt( $sOptionKey, $this->getOptDefault( $sOptionKey ) );
|
691 |
-
}
|
692 |
-
|
693 |
-
/**
|
694 |
-
* Will traverse each premium option and set it to the default.
|
695 |
-
*/
|
696 |
-
public function resetPremiumOptsToDefault() {
|
697 |
-
foreach ( $this->getRawData_AllOptions() as $aOption ) {
|
698 |
-
if ( isset( $aOption[ 'premium' ] ) && $aOption[ 'premium' ] ) {
|
699 |
-
$this->resetOptToDefault( $aOption[ 'key' ] );
|
700 |
-
}
|
701 |
-
}
|
702 |
-
}
|
703 |
-
|
704 |
-
/**
|
705 |
-
* @param string $sKey
|
706 |
-
* @return $this
|
707 |
-
*/
|
708 |
-
public function setOptionsStorageKey( $sKey ) {
|
709 |
-
$this->sOptionsStorageKey = $sKey;
|
710 |
-
return $this;
|
711 |
-
}
|
712 |
-
|
713 |
-
/**
|
714 |
-
* @param boolean $bLoadFromSaved
|
715 |
-
* @return $this
|
716 |
-
*/
|
717 |
-
public function setIfLoadOptionsFromStorage( $bLoadFromSaved ) {
|
718 |
-
$this->bLoadFromSaved = $bLoadFromSaved;
|
719 |
-
return $this;
|
720 |
-
}
|
721 |
-
|
722 |
-
/**
|
723 |
-
* @param boolean $bNeed
|
724 |
-
*/
|
725 |
-
public function setNeedSave( $bNeed ) {
|
726 |
-
$this->bNeedSave = $bNeed;
|
727 |
-
}
|
728 |
-
|
729 |
-
/**
|
730 |
-
* @param boolean $bRebuild
|
731 |
-
* @return $this
|
732 |
-
*/
|
733 |
-
public function setRebuildFromFile( $bRebuild ) {
|
734 |
-
$this->bRebuildFromFile = $bRebuild;
|
735 |
-
return $this;
|
736 |
-
}
|
737 |
-
|
738 |
-
/**
|
739 |
-
* @param array $aOptions
|
740 |
-
*/
|
741 |
-
public function setMultipleOptions( $aOptions ) {
|
742 |
-
if ( is_array( $aOptions ) ) {
|
743 |
-
foreach ( $aOptions as $sKey => $mValue ) {
|
744 |
-
$this->setOpt( $sKey, $mValue );
|
745 |
-
}
|
746 |
-
}
|
747 |
-
}
|
748 |
-
|
749 |
-
/**
|
750 |
-
* @param string $sOptKey
|
751 |
-
* @param mixed $mNewValue
|
752 |
-
* @return mixed
|
753 |
-
*/
|
754 |
-
public function setOpt( $sOptKey, $mNewValue ) {
|
755 |
-
|
756 |
-
// We can't use getOpt() to find the current value since we'll create an infinite loop
|
757 |
-
$aOptionsValues = $this->getAllOptionsValues();
|
758 |
-
$mCurrent = isset( $aOptionsValues[ $sOptKey ] ) ? $aOptionsValues[ $sOptKey ] : null;
|
759 |
-
|
760 |
-
$mNewValue = $this->ensureOptValueState( $sOptKey, $mNewValue );
|
761 |
-
|
762 |
-
// Here we try to ensure that values that are repeatedly changed properly reflect their changed
|
763 |
-
// states, as they may be reverted back to their original state and we "think" it's been changed.
|
764 |
-
$bValueIsDifferent = serialize( $mCurrent ) !== serialize( $mNewValue );
|
765 |
-
// basically if we're actually resetting back to the original value
|
766 |
-
$bIsResetting = $bValueIsDifferent && $this->isOptChanged( $sOptKey )
|
767 |
-
&& ( serialize( $this->getOldValue( $sOptKey ) ) === serialize( $mNewValue ) );
|
768 |
-
|
769 |
-
if ( $bValueIsDifferent && $this->verifyCanSet( $sOptKey, $mNewValue ) ) {
|
770 |
-
$this->setNeedSave( true );
|
771 |
-
|
772 |
-
//Load the config and do some pre-set verification where possible. This will slowly grow.
|
773 |
-
$aOption = $this->getRawData_SingleOption( $sOptKey );
|
774 |
-
if ( !empty( $aOption[ 'type' ] ) ) {
|
775 |
-
if ( $aOption[ 'type' ] == 'boolean' && !is_bool( $mNewValue ) ) {
|
776 |
-
return $this->resetOptToDefault( $sOptKey );
|
777 |
-
}
|
778 |
-
}
|
779 |
-
$this->setOldOptValue( $sOptKey, $mCurrent );
|
780 |
-
$this->aOptionsValues[ $sOptKey ] = $mNewValue;
|
781 |
-
}
|
782 |
-
|
783 |
-
if ( $bIsResetting ) {
|
784 |
-
unset( $this->aOld[ $sOptKey ] );
|
785 |
-
}
|
786 |
-
|
787 |
-
return true;
|
788 |
-
}
|
789 |
-
|
790 |
-
/**
|
791 |
-
* Ensures that set options values are of the correct type
|
792 |
-
* @param string $sOptKey
|
793 |
-
* @param mixed $mValue
|
794 |
-
* @return mixed
|
795 |
-
*/
|
796 |
-
private function ensureOptValueState( $sOptKey, $mValue ) {
|
797 |
-
switch ( $this->getOptionType( $sOptKey ) ) {
|
798 |
-
case 'integer':
|
799 |
-
$mValue = (int)$mValue;
|
800 |
-
break;
|
801 |
-
|
802 |
-
case 'text':
|
803 |
-
case 'email':
|
804 |
-
$mValue = (string)$mValue;
|
805 |
-
break;
|
806 |
-
}
|
807 |
-
return $mValue;
|
808 |
-
}
|
809 |
-
|
810 |
-
/**
|
811 |
-
* @param string $sOptKey
|
812 |
-
* @param mixed $mPotentialValue
|
813 |
-
* @return bool
|
814 |
-
*/
|
815 |
-
private function verifyCanSet( $sOptKey, $mPotentialValue ) {
|
816 |
-
$bValid = true;
|
817 |
-
|
818 |
-
switch ( $this->getOptionType( $sOptKey ) ) {
|
819 |
-
|
820 |
-
case 'integer':
|
821 |
-
$nMin = $this->getOptProperty( $sOptKey, 'min' );
|
822 |
-
if ( !is_null( $nMin ) ) {
|
823 |
-
$bValid = $mPotentialValue >= $nMin;
|
824 |
-
}
|
825 |
-
$nMax = $this->getOptProperty( $sOptKey, 'max' );
|
826 |
-
if ( !is_null( $nMax ) ) {
|
827 |
-
$bValid = $mPotentialValue <= $nMax;
|
828 |
-
}
|
829 |
-
break;
|
830 |
-
|
831 |
-
case 'email':
|
832 |
-
$bValid = empty( $mPotentialValue ) || Services::Data()->validEmail( $mPotentialValue );
|
833 |
-
break;
|
834 |
-
}
|
835 |
-
return $bValid;
|
836 |
-
}
|
837 |
-
|
838 |
-
/**
|
839 |
-
* @param string $sOptionKey
|
840 |
-
* @param mixed $mValue
|
841 |
-
* @return $this
|
842 |
-
*/
|
843 |
-
private function setOldOptValue( $sOptionKey, $mValue ) {
|
844 |
-
if ( !is_array( $this->aOld ) ) {
|
845 |
-
$this->aOld = [];
|
846 |
-
}
|
847 |
-
if ( !isset( $this->aOld[ $sOptionKey ] ) ) {
|
848 |
-
$this->aOld[ $sOptionKey ] = $mValue;
|
849 |
-
}
|
850 |
-
return $this;
|
851 |
-
}
|
852 |
-
|
853 |
-
/**
|
854 |
-
* @param string $sOptionKey
|
855 |
-
* @return mixed
|
856 |
-
*/
|
857 |
-
public function unsetOpt( $sOptionKey ) {
|
858 |
-
|
859 |
-
unset( $this->aOptionsValues[ $sOptionKey ] );
|
860 |
-
$this->setNeedSave( true );
|
861 |
-
return true;
|
862 |
-
}
|
863 |
-
|
864 |
-
/** PRIVATE STUFF */
|
865 |
-
|
866 |
-
/**
|
867 |
-
* @return array
|
868 |
-
*/
|
869 |
-
protected function getCommonStandardOptions() {
|
870 |
-
return [ 'help_video_options' ];
|
871 |
-
}
|
872 |
-
|
873 |
-
/**
|
874 |
-
*/
|
875 |
-
private function cleanOptions() {
|
876 |
-
if ( !empty( $this->aOptionsValues ) && is_array( $this->aOptionsValues ) ) {
|
877 |
-
$this->aOptionsValues = array_intersect_key(
|
878 |
-
$this->getAllOptionsValues(),
|
879 |
-
array_flip( $this->getOptionsKeys() )
|
880 |
-
);
|
881 |
-
}
|
882 |
-
}
|
883 |
-
|
884 |
-
/**
|
885 |
-
* @param bool $bReload
|
886 |
-
* @return array|mixed
|
887 |
-
* @throws Exception
|
888 |
-
*/
|
889 |
-
private function loadOptionsValuesFromStorage( $bReload = false ) {
|
890 |
-
|
891 |
-
if ( $bReload || empty( $this->aOptionsValues ) ) {
|
892 |
-
|
893 |
-
if ( $this->getIfLoadOptionsFromStorage() ) {
|
894 |
-
|
895 |
-
$sStorageKey = $this->getOptionsStorageKey();
|
896 |
-
if ( empty( $sStorageKey ) ) {
|
897 |
-
throw new Exception( 'Options Storage Key Is Empty' );
|
898 |
-
}
|
899 |
-
$this->aOptionsValues = $this->loadWp()->getOption( $sStorageKey, [] );
|
900 |
-
}
|
901 |
-
}
|
902 |
-
if ( !is_array( $this->aOptionsValues ) ) {
|
903 |
-
$this->aOptionsValues = [];
|
904 |
-
$this->setNeedSave( true );
|
905 |
-
}
|
906 |
-
return $this->aOptionsValues;
|
907 |
-
}
|
908 |
-
|
909 |
-
/**
|
910 |
-
* @return array
|
911 |
-
*/
|
912 |
-
private function readConfiguration() {
|
913 |
-
$oWp = $this->loadWp();
|
914 |
-
|
915 |
-
$sTransientKey = $this->getSpecTransientStorageKey();
|
916 |
-
$aConfig = $oWp->getTransient( $sTransientKey );
|
917 |
-
|
918 |
-
$bRebuild = $this->getRebuildFromFile() || empty( $aConfig );
|
919 |
-
if ( !$bRebuild && !empty( $aConfig ) && is_array( $aConfig ) ) {
|
920 |
-
|
921 |
-
if ( !isset( $aConfig[ 'meta_modts' ] ) ) {
|
922 |
-
$aConfig[ 'meta_modts' ] = 0;
|
923 |
-
}
|
924 |
-
$bRebuild = $this->getConfigModTime() > $aConfig[ 'meta_modts' ];
|
925 |
-
}
|
926 |
-
|
927 |
-
if ( $bRebuild ) {
|
928 |
-
try {
|
929 |
-
$aConfig = $this->readConfigurationJson();
|
930 |
-
}
|
931 |
-
catch ( Exception $oE ) {
|
932 |
-
if ( Services::WpGeneral()->isDebug() ) {
|
933 |
-
trigger_error( $oE->getMessage() );
|
934 |
-
}
|
935 |
-
$aConfig = [];
|
936 |
-
}
|
937 |
-
$aConfig[ 'meta_modts' ] = $this->getConfigModTime();
|
938 |
-
$oWp->setTransient( $sTransientKey, $aConfig, DAY_IN_SECONDS );
|
939 |
-
}
|
940 |
-
|
941 |
-
$this->setRebuildFromFile( $bRebuild );
|
942 |
-
return $aConfig;
|
943 |
-
}
|
944 |
-
|
945 |
-
/**
|
946 |
-
* @return array
|
947 |
-
* @throws Exception
|
948 |
-
*/
|
949 |
-
private function readConfigurationJson() {
|
950 |
-
$aConfig = json_decode( $this->readConfigurationFileContents(), true );
|
951 |
-
if ( empty( $aConfig ) ) {
|
952 |
-
throw new Exception( sprintf( 'Reading JSON configuration from file "%s" failed.', $this->getSlug() ) );
|
953 |
-
}
|
954 |
-
return $aConfig;
|
955 |
-
}
|
956 |
-
|
957 |
-
/**
|
958 |
-
* @return string
|
959 |
-
* @throws Exception
|
960 |
-
*/
|
961 |
-
private function readConfigurationFileContents() {
|
962 |
-
if ( !$this->getConfigFileExists() ) {
|
963 |
-
throw new Exception( sprintf( 'Configuration file "%s" does not exist.', $this->getPathToConfig() ) );
|
964 |
-
}
|
965 |
-
return Services::Data()->readFileContentsUsingInclude( $this->getPathToConfig() );
|
966 |
-
}
|
967 |
-
|
968 |
-
/**
|
969 |
-
* @return string
|
970 |
-
*/
|
971 |
-
private function getSpecTransientStorageKey() {
|
972 |
-
return 'icwp_'.md5( $this->getPathToConfig() );
|
973 |
-
}
|
974 |
-
|
975 |
-
/**
|
976 |
-
* @return bool
|
977 |
-
*/
|
978 |
-
private function getConfigFileExists() {
|
979 |
-
$sPath = $this->getPathToConfig();
|
980 |
-
return !empty( $sPath ) && Services::WpFs()->isFile( $sPath );
|
981 |
-
}
|
982 |
-
|
983 |
-
/**
|
984 |
-
* @param string $sPathToConfig
|
985 |
-
* @return $this
|
986 |
-
*/
|
987 |
-
public function setPathToConfig( $sPathToConfig ) {
|
988 |
-
$this->sPathToConfig = $sPathToConfig;
|
989 |
-
return $this;
|
990 |
-
}
|
991 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-render.php
DELETED
@@ -1,316 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class ICWP_WPSF_Render extends ICWP_WPSF_Foundation {
|
4 |
-
|
5 |
-
const TEMPLATE_ENGINE_TWIG = 0;
|
6 |
-
const TEMPLATE_ENGINE_PHP = 1;
|
7 |
-
const TEMPLATE_ENGINE_HTML = 2;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* @var ICWP_WPSF_Render
|
11 |
-
*/
|
12 |
-
protected static $oInstance = null;
|
13 |
-
|
14 |
-
private function __construct() {
|
15 |
-
}
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @return ICWP_WPSF_Render
|
19 |
-
*/
|
20 |
-
public static function GetInstance() {
|
21 |
-
if ( is_null( self::$oInstance ) ) {
|
22 |
-
self::$oInstance = new self();
|
23 |
-
}
|
24 |
-
return self::$oInstance;
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @var array
|
29 |
-
*/
|
30 |
-
protected $aRenderVars;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @var string
|
34 |
-
*/
|
35 |
-
protected $sTemplateRootMain;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* @var string
|
39 |
-
*/
|
40 |
-
protected $aTemplateRoots;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* @var string
|
44 |
-
*/
|
45 |
-
protected $sTemplate;
|
46 |
-
|
47 |
-
/**
|
48 |
-
* @var int
|
49 |
-
*/
|
50 |
-
protected $nTemplateEngine;
|
51 |
-
|
52 |
-
/**
|
53 |
-
* @return string
|
54 |
-
* @throws \Exception
|
55 |
-
*/
|
56 |
-
public function render() {
|
57 |
-
|
58 |
-
switch ( $this->getTemplateEngine() ) {
|
59 |
-
|
60 |
-
case self::TEMPLATE_ENGINE_TWIG :
|
61 |
-
$sOutput = $this->renderTwig();
|
62 |
-
break;
|
63 |
-
|
64 |
-
case self::TEMPLATE_ENGINE_HTML :
|
65 |
-
$sOutput = $this->renderHtml();
|
66 |
-
break;
|
67 |
-
|
68 |
-
default:
|
69 |
-
$sOutput = $this->renderPhp();
|
70 |
-
break;
|
71 |
-
}
|
72 |
-
return $sOutput;
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* @return string
|
77 |
-
*/
|
78 |
-
private function renderHtml() {
|
79 |
-
ob_start();
|
80 |
-
@include( $this->getTemplateRootMain().ltrim( $this->getTemplate(), DIRECTORY_SEPARATOR ) );
|
81 |
-
return ob_get_clean();
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* @return string
|
86 |
-
*/
|
87 |
-
private function renderPhp() {
|
88 |
-
if ( count( $this->getRenderVars() ) > 0 ) {
|
89 |
-
extract( $this->getRenderVars() );
|
90 |
-
}
|
91 |
-
|
92 |
-
$sTemplate = $this->getTemplateRootMain().ltrim( $this->getTemplate(), DIRECTORY_SEPARATOR );
|
93 |
-
if ( $this->loadFS()->isFile( $sTemplate ) ) {
|
94 |
-
ob_start();
|
95 |
-
include( $sTemplate );
|
96 |
-
$sContents = ob_get_clean();
|
97 |
-
}
|
98 |
-
else {
|
99 |
-
$sContents = 'Error: Template file not found: '.$sTemplate;
|
100 |
-
}
|
101 |
-
|
102 |
-
return $sContents;
|
103 |
-
}
|
104 |
-
|
105 |
-
/**
|
106 |
-
* @return string
|
107 |
-
* @throws Exception
|
108 |
-
*/
|
109 |
-
private function renderTwig() {
|
110 |
-
return $this->getTwigEnvironment()->render( $this->getTemplate(), $this->getRenderVars() );
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
*/
|
115 |
-
public function display() {
|
116 |
-
echo $this->render();
|
117 |
-
return $this;
|
118 |
-
}
|
119 |
-
|
120 |
-
/**
|
121 |
-
* @return $this
|
122 |
-
*/
|
123 |
-
public function clearRenderVars() {
|
124 |
-
return $this->setRenderVars( [] );
|
125 |
-
}
|
126 |
-
|
127 |
-
/**
|
128 |
-
* @return \Twig\Environment|\Twig_Environment
|
129 |
-
*/
|
130 |
-
protected function getTwigEnvironment() {
|
131 |
-
$aConf = [
|
132 |
-
'debug' => true,
|
133 |
-
'strict_variables' => true,
|
134 |
-
];
|
135 |
-
if ( class_exists( 'Twig_Environment' ) ) {
|
136 |
-
$oEnv = new Twig_Environment( new Twig_Loader_Filesystem( $this->getTemplateRootMain() ), $aConf );
|
137 |
-
}
|
138 |
-
else {
|
139 |
-
$oEnv = new \Twig\Environment( new \Twig\Loader\FilesystemLoader( $this->getTemplateRootMain() ), $aConf );
|
140 |
-
}
|
141 |
-
return $oEnv;
|
142 |
-
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* @return string
|
146 |
-
*/
|
147 |
-
public function getTemplate() {
|
148 |
-
$this->sTemplate = \FernleafSystems\Wordpress\Services\Services::Data()
|
149 |
-
->addExtensionToFilePath( $this->sTemplate, $this->getEngineStub() );
|
150 |
-
return $this->sTemplate;
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* @return int
|
155 |
-
*/
|
156 |
-
public function getTemplateEngine() {
|
157 |
-
if ( !isset( $this->nTemplateEngine )
|
158 |
-
|| !in_array( $this->nTemplateEngine, [
|
159 |
-
self::TEMPLATE_ENGINE_TWIG,
|
160 |
-
self::TEMPLATE_ENGINE_PHP,
|
161 |
-
self::TEMPLATE_ENGINE_HTML
|
162 |
-
] ) ) {
|
163 |
-
$this->nTemplateEngine = self::TEMPLATE_ENGINE_PHP;
|
164 |
-
}
|
165 |
-
return $this->nTemplateEngine;
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* @param string $sTemplate
|
170 |
-
* @return string
|
171 |
-
*/
|
172 |
-
public function getTemplateExists( $sTemplate = '' ) {
|
173 |
-
$sFullPath = $this->getTemplateFullPath( $sTemplate );
|
174 |
-
return $this->loadFS()->exists( $sFullPath );
|
175 |
-
}
|
176 |
-
|
177 |
-
/**
|
178 |
-
* @param string $sTemplate
|
179 |
-
* @return string
|
180 |
-
*/
|
181 |
-
public function getTemplateFullPath( $sTemplate = '' ) {
|
182 |
-
if ( empty( $sTemplate ) ) {
|
183 |
-
$sTemplate = $this->getTemplate();
|
184 |
-
}
|
185 |
-
$sTemplate = \FernleafSystems\Wordpress\Services\Services::Data()
|
186 |
-
->addExtensionToFilePath( $sTemplate, $this->getEngineStub() );
|
187 |
-
return path_join( $this->getTemplateRootMain(), $sTemplate );
|
188 |
-
}
|
189 |
-
|
190 |
-
/**
|
191 |
-
* @return string
|
192 |
-
*/
|
193 |
-
public function getTemplateRootMain() {
|
194 |
-
$sPath = rtrim( $this->sTemplateRootMain, DIRECTORY_SEPARATOR );
|
195 |
-
$sStub = $this->getEngineStub();
|
196 |
-
if ( !preg_match( sprintf( '#%s$#', $sStub ), $sPath ) ) {
|
197 |
-
$sPath = $sPath.DIRECTORY_SEPARATOR.$sStub;
|
198 |
-
}
|
199 |
-
return $sPath.DIRECTORY_SEPARATOR;
|
200 |
-
}
|
201 |
-
|
202 |
-
/**
|
203 |
-
* For use with Twig
|
204 |
-
* @return array
|
205 |
-
*/
|
206 |
-
public function getTemplateRoots() {
|
207 |
-
if ( !is_array( $this->aTemplateRoots ) ) {
|
208 |
-
$this->aTemplateRoots = [];
|
209 |
-
}
|
210 |
-
array_unshift( $this->aTemplateRoots, $this->getTemplateRootMain() );
|
211 |
-
return array_unique( array_filter( $this->aTemplateRoots ) );
|
212 |
-
}
|
213 |
-
|
214 |
-
/**
|
215 |
-
* @return array
|
216 |
-
*/
|
217 |
-
public function getRenderVars() {
|
218 |
-
return $this->aRenderVars;
|
219 |
-
}
|
220 |
-
|
221 |
-
/**
|
222 |
-
* @param array $aVars
|
223 |
-
* @return $this
|
224 |
-
*/
|
225 |
-
public function setRenderVars( $aVars ) {
|
226 |
-
$this->aRenderVars = $aVars;
|
227 |
-
return $this;
|
228 |
-
}
|
229 |
-
|
230 |
-
/**
|
231 |
-
* @param string $sPath
|
232 |
-
* @return $this
|
233 |
-
*/
|
234 |
-
public function setTemplate( $sPath ) {
|
235 |
-
// if ( !preg_match( '#\.twig$#', $sPath ) ) {
|
236 |
-
// $sPath = $sPath . '.twig';
|
237 |
-
// }
|
238 |
-
$this->sTemplate = $sPath;
|
239 |
-
return $this;
|
240 |
-
}
|
241 |
-
|
242 |
-
/**
|
243 |
-
* @return $this
|
244 |
-
*/
|
245 |
-
public function setTemplateEngineHtml() {
|
246 |
-
return $this->setTemplateEngine( self::TEMPLATE_ENGINE_HTML );
|
247 |
-
}
|
248 |
-
|
249 |
-
/**
|
250 |
-
* @return $this
|
251 |
-
*/
|
252 |
-
public function setTemplateEnginePhp() {
|
253 |
-
return $this->setTemplateEngine( self::TEMPLATE_ENGINE_PHP );
|
254 |
-
}
|
255 |
-
|
256 |
-
/**
|
257 |
-
* @return $this
|
258 |
-
*/
|
259 |
-
public function setTemplateEngineTwig() {
|
260 |
-
return $this->setTemplateEngine( self::TEMPLATE_ENGINE_TWIG );
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
* @param int $nEngine
|
265 |
-
* @return $this
|
266 |
-
*/
|
267 |
-
protected function setTemplateEngine( $nEngine ) {
|
268 |
-
$this->nTemplateEngine = $nEngine;
|
269 |
-
return $this;
|
270 |
-
}
|
271 |
-
|
272 |
-
/**
|
273 |
-
* @param string $sPath
|
274 |
-
* @return $this
|
275 |
-
*/
|
276 |
-
public function addTemplateRoot( $sPath ) {
|
277 |
-
$aRoots = $this->getTemplateRoots();
|
278 |
-
$aRoots[] = $sPath;
|
279 |
-
$this->aTemplateRoots = $aRoots;
|
280 |
-
return $this;
|
281 |
-
}
|
282 |
-
|
283 |
-
/**
|
284 |
-
* @param string $sPath
|
285 |
-
* @return $this
|
286 |
-
*/
|
287 |
-
public function setTemplateRoot( $sPath ) {
|
288 |
-
$this->sTemplateRootMain = $sPath;
|
289 |
-
return $this;
|
290 |
-
}
|
291 |
-
|
292 |
-
/**
|
293 |
-
* @return string
|
294 |
-
*/
|
295 |
-
private function getEngineStub() {
|
296 |
-
switch ( $this->getTemplateEngine() ) {
|
297 |
-
|
298 |
-
case self::TEMPLATE_ENGINE_TWIG:
|
299 |
-
$sStub = 'twig';
|
300 |
-
break;
|
301 |
-
|
302 |
-
case self::TEMPLATE_ENGINE_HTML:
|
303 |
-
$sStub = 'html';
|
304 |
-
break;
|
305 |
-
|
306 |
-
case self::TEMPLATE_ENGINE_PHP:
|
307 |
-
$sStub = 'php';
|
308 |
-
break;
|
309 |
-
|
310 |
-
default:
|
311 |
-
$sStub = 'php';
|
312 |
-
break;
|
313 |
-
}
|
314 |
-
return $sStub;
|
315 |
-
}
|
316 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-request.php
DELETED
@@ -1,310 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class ICWP_WPSF_Request extends ICWP_WPSF_Foundation {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var ICWP_WPSF_Request
|
7 |
-
*/
|
8 |
-
protected static $oInstance = null;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var int
|
12 |
-
*/
|
13 |
-
protected static $nTime = null;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var float
|
17 |
-
*/
|
18 |
-
protected static $nMicroTime = null;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @var array
|
22 |
-
*/
|
23 |
-
protected $aRequestUriParts;
|
24 |
-
|
25 |
-
protected function __construct() {
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @return ICWP_WPSF_Request
|
30 |
-
*/
|
31 |
-
public static function GetInstance() {
|
32 |
-
if ( is_null( self::$oInstance ) ) {
|
33 |
-
self::$oInstance = new self();
|
34 |
-
}
|
35 |
-
return self::$oInstance;
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* @param string $sKey
|
40 |
-
* @param string $mDefault
|
41 |
-
* @param bool $bTrim -automatically trim whitespace
|
42 |
-
* @return mixed|null
|
43 |
-
*/
|
44 |
-
public function cookie( $sKey, $mDefault = null, $bTrim = true ) {
|
45 |
-
$mVal = $this->loadDP()->arrayFetch( $_COOKIE, $sKey, $mDefault );
|
46 |
-
return ( $bTrim && is_scalar( $mVal ) ) ? trim( $mVal ) : $mVal;
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* @param string $sKey
|
51 |
-
* @param mixed $mDefault
|
52 |
-
* @return mixed|null
|
53 |
-
*/
|
54 |
-
public function env( $sKey, $mDefault = null ) {
|
55 |
-
return $this->loadDP()->arrayFetch( $_ENV, $sKey, $mDefault );
|
56 |
-
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* @param string $sKey
|
60 |
-
* @param null $mDefault
|
61 |
-
* @param bool $bTrim -automatically trim whitespace
|
62 |
-
* @return mixed|null
|
63 |
-
*/
|
64 |
-
public function post( $sKey, $mDefault = null, $bTrim = true ) {
|
65 |
-
$mVal = $this->loadDP()->arrayFetch( $_POST, $sKey, $mDefault );
|
66 |
-
return ( $bTrim && is_scalar( $mVal ) ) ? trim( $mVal ) : $mVal;
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* @param string $sKey
|
71 |
-
* @param null $mDefault
|
72 |
-
* @param bool $bTrim -automatically trim whitespace
|
73 |
-
* @return mixed|null
|
74 |
-
*/
|
75 |
-
public function query( $sKey, $mDefault = null, $bTrim = true ) {
|
76 |
-
$mVal = $this->loadDP()->arrayFetch( $_GET, $sKey, $mDefault );
|
77 |
-
return ( $bTrim && is_scalar( $mVal ) ) ? trim( $mVal ) : $mVal;
|
78 |
-
}
|
79 |
-
|
80 |
-
/**
|
81 |
-
* @param string $sKey
|
82 |
-
* @param null $mDefault
|
83 |
-
* @param bool $bTrim -automatically trim whitespace
|
84 |
-
* @return mixed|null
|
85 |
-
*/
|
86 |
-
public function server( $sKey, $mDefault = null, $bTrim = true ) {
|
87 |
-
$mVal = $this->loadDP()->arrayFetch( $_SERVER, $sKey, $mDefault );
|
88 |
-
return ( $bTrim && is_scalar( $mVal ) ) ? trim( $mVal ) : $mVal;
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* @param string $sKey
|
93 |
-
* @param null $mDefault
|
94 |
-
* @param bool $bIncludeCookie
|
95 |
-
* @param bool $bTrim -automatically trim whitespace
|
96 |
-
* @return mixed|null
|
97 |
-
*/
|
98 |
-
public function request( $sKey, $bIncludeCookie = false, $mDefault = null, $bTrim = true ) {
|
99 |
-
$mVal = $this->post( $sKey, null, $bTrim );
|
100 |
-
if ( is_null( $mVal ) ) {
|
101 |
-
$mVal = $this->query( $sKey, null, $bTrim );
|
102 |
-
if ( is_null( $mVal && $bIncludeCookie ) ) {
|
103 |
-
$mVal = $this->cookie( $sKey );
|
104 |
-
}
|
105 |
-
}
|
106 |
-
return is_null( $mVal ) ? $mDefault : ( $bTrim && is_scalar( $mVal ) ) ? trim( $mVal ) : $mVal;
|
107 |
-
}
|
108 |
-
|
109 |
-
/**
|
110 |
-
* @return string
|
111 |
-
*/
|
112 |
-
public function getHost() {
|
113 |
-
return $this->server( 'HTTP_HOST' );
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* @return string
|
118 |
-
*/
|
119 |
-
public function getMethod() {
|
120 |
-
$sRequestMethod = $this->server( 'REQUEST_METHOD' );
|
121 |
-
return ( empty( $sRequestMethod ) ? 'get' : strtolower( $sRequestMethod ) );
|
122 |
-
}
|
123 |
-
|
124 |
-
/**
|
125 |
-
* @param bool $bIncludeCookie
|
126 |
-
* @return array
|
127 |
-
*/
|
128 |
-
public function getParams( $bIncludeCookie = true ) {
|
129 |
-
$aParams = array_merge( $_GET, $_POST );
|
130 |
-
return $bIncludeCookie ? array_merge( $aParams, $_COOKIE ) : $aParams;
|
131 |
-
}
|
132 |
-
|
133 |
-
/**
|
134 |
-
* @return string URI Path in lowercase
|
135 |
-
*/
|
136 |
-
public function getPath() {
|
137 |
-
return $this->getUriParts()[ 'path' ];
|
138 |
-
}
|
139 |
-
|
140 |
-
/**
|
141 |
-
* @return string
|
142 |
-
*/
|
143 |
-
public function getUri() {
|
144 |
-
return $this->server( 'REQUEST_URI' );
|
145 |
-
}
|
146 |
-
|
147 |
-
/**
|
148 |
-
* @return array
|
149 |
-
*/
|
150 |
-
public function getUriParts() {
|
151 |
-
if ( !isset( $this->aRequestUriParts ) ) {
|
152 |
-
$aExploded = explode( '?', $this->getUri(), 2 );
|
153 |
-
$this->aRequestUriParts = [
|
154 |
-
'path' => empty( $aExploded[ 0 ] ) ? '' : $aExploded[ 0 ],
|
155 |
-
'query' => empty( $aExploded[ 1 ] ) ? '' : $aExploded[ 1 ],
|
156 |
-
];
|
157 |
-
}
|
158 |
-
return $this->aRequestUriParts;
|
159 |
-
}
|
160 |
-
|
161 |
-
/**
|
162 |
-
* @return string
|
163 |
-
*/
|
164 |
-
public function getUserAgent() {
|
165 |
-
return $this->server( 'HTTP_USER_AGENT' );
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* @return string|null
|
170 |
-
*/
|
171 |
-
public function getScriptName() {
|
172 |
-
$sScriptName = $this->server( 'SCRIPT_NAME' );
|
173 |
-
return !empty( $sScriptName ) ? $sScriptName : $this->server( 'PHP_SELF' );
|
174 |
-
}
|
175 |
-
|
176 |
-
/**
|
177 |
-
* @return bool
|
178 |
-
*/
|
179 |
-
public function isMethodPost() {
|
180 |
-
return ( $this->getMethod() == 'post' );
|
181 |
-
}
|
182 |
-
|
183 |
-
/**
|
184 |
-
* TODO: scrap?
|
185 |
-
* Taken from http://www.phacks.net/detecting-search-engine-bot-and-web-spiders/
|
186 |
-
*/
|
187 |
-
public function isSearchEngineBot() {
|
188 |
-
|
189 |
-
$sUserAgent = $this->server( 'HTTP_USER_AGENT' );
|
190 |
-
if ( empty( $sUserAgent ) ) {
|
191 |
-
return false;
|
192 |
-
}
|
193 |
-
|
194 |
-
$sBots = 'Googlebot|bingbot|Twitterbot|Baiduspider|ia_archiver|R6_FeedFetcher|NetcraftSurveyAgent'
|
195 |
-
.'|Sogou web spider|Yahoo! Slurp|facebookexternalhit|PrintfulBot|msnbot|UnwindFetchor|urlresolver|Butterfly|TweetmemeBot';
|
196 |
-
|
197 |
-
return ( preg_match( "/$sBots/", $sUserAgent ) > 0 );
|
198 |
-
}
|
199 |
-
|
200 |
-
/**
|
201 |
-
* @param string $sRequestedUriPath
|
202 |
-
* @param string $sHostName - you can also send a full and valid URL
|
203 |
-
*/
|
204 |
-
public function sendResponseApache404( $sRequestedUriPath = '', $sHostName = '' ) {
|
205 |
-
if ( empty( $sRequestedUriPath ) ) {
|
206 |
-
$sRequestedUriPath = $this->server( 'REQUEST_URI' );
|
207 |
-
}
|
208 |
-
|
209 |
-
if ( empty( $sHostName ) ) {
|
210 |
-
$sHostName = $this->server( 'SERVER_NAME' );
|
211 |
-
}
|
212 |
-
else if ( filter_var( $sHostName, FILTER_VALIDATE_URL ) ) {
|
213 |
-
$sHostName = parse_url( $sRequestedUriPath, PHP_URL_HOST );
|
214 |
-
}
|
215 |
-
|
216 |
-
$bSsl = is_ssl() || $this->server( 'HTTP_X_FORWARDED_PROTO' ) == 'https';
|
217 |
-
header( 'HTTP/1.1 404 Not Found' );
|
218 |
-
$nPort = $bSsl ? 443 : (int)$this->server( 'SERVER_PORT' );
|
219 |
-
$sDie = sprintf(
|
220 |
-
'<html><head><title>404 Not Found</title><style type="text/css"></style></head><body><h1>Not Found</h1><p>The requested URL %s was not found on this server.</p><p>Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.</p><hr><address>Apache Server at %s Port %s</address></body></html>',
|
221 |
-
preg_replace( '#[^a-z0-9_&;=%/-]#i', '', esc_html( $sRequestedUriPath ) ),
|
222 |
-
$sHostName,
|
223 |
-
empty( $nPort ) ? 80 : $nPort
|
224 |
-
);
|
225 |
-
die( $sDie );
|
226 |
-
}
|
227 |
-
|
228 |
-
/**
|
229 |
-
* @param string $sStringContent
|
230 |
-
* @param string $sFilename
|
231 |
-
*/
|
232 |
-
public function downloadStringAsFile( $sStringContent, $sFilename ) {
|
233 |
-
header( "Content-type: application/octet-stream" );
|
234 |
-
header( "Content-disposition: attachment; filename=".$sFilename );
|
235 |
-
header( "Content-Transfer-Encoding: binary" );
|
236 |
-
header( "Content-Length: ".strlen( $sStringContent ) );
|
237 |
-
echo $sStringContent;
|
238 |
-
die();
|
239 |
-
}
|
240 |
-
|
241 |
-
/**
|
242 |
-
* @param $sKey
|
243 |
-
* @param $mValue
|
244 |
-
* @param int $nExpireLength
|
245 |
-
* @param null $sPath
|
246 |
-
* @param null $sDomain
|
247 |
-
* @param bool $bSsl
|
248 |
-
* @return bool
|
249 |
-
*/
|
250 |
-
public function setCookie( $sKey, $mValue, $nExpireLength = 3600, $sPath = null, $sDomain = null, $bSsl = true ) {
|
251 |
-
$_COOKIE[ $sKey ] = $mValue;
|
252 |
-
if ( function_exists( 'headers_sent' ) && headers_sent() ) {
|
253 |
-
return false;
|
254 |
-
}
|
255 |
-
return setcookie(
|
256 |
-
$sKey,
|
257 |
-
$mValue,
|
258 |
-
(int)( $this->ts() + $nExpireLength ),
|
259 |
-
( is_null( $sPath ) && defined( 'COOKIEPATH' ) ) ? COOKIEPATH : $sPath,
|
260 |
-
( is_null( $sDomain ) && defined( 'COOKIE_DOMAIN' ) ) ? COOKIE_DOMAIN : $sDomain,
|
261 |
-
$bSsl && is_ssl()
|
262 |
-
);
|
263 |
-
}
|
264 |
-
|
265 |
-
/**
|
266 |
-
* @param string $sKey
|
267 |
-
* @return bool
|
268 |
-
*/
|
269 |
-
public function setDeleteCookie( $sKey ) {
|
270 |
-
if ( isset( $_COOKIE[ $sKey ] ) ) {
|
271 |
-
unset( $_COOKIE[ $sKey ] );
|
272 |
-
}
|
273 |
-
return $this->setCookie( $sKey, '', -3600 );
|
274 |
-
}
|
275 |
-
|
276 |
-
/**
|
277 |
-
* @return int
|
278 |
-
*/
|
279 |
-
public function ts() {
|
280 |
-
if ( !isset( self::$nTime ) ) {
|
281 |
-
self::$nTime = time();
|
282 |
-
self::$nMicroTime = function_exists( 'microtime' ) ? @microtime( true ) : false;
|
283 |
-
}
|
284 |
-
return self::$nTime;
|
285 |
-
}
|
286 |
-
|
287 |
-
/**
|
288 |
-
* @param bool $bMillisecondOnly
|
289 |
-
* @return int
|
290 |
-
*/
|
291 |
-
public function mts( $bMillisecondOnly = false ) {
|
292 |
-
$nT = $this->ts();
|
293 |
-
if ( empty( self::$nMicroTime ) ) {
|
294 |
-
$nT = $bMillisecondOnly ? 0 : $nT;
|
295 |
-
}
|
296 |
-
else {
|
297 |
-
$nT = $bMillisecondOnly ? preg_replace( '#^[0-9]+\.#', '', self::$nMicroTime ) : self::$nMicroTime;
|
298 |
-
}
|
299 |
-
return $nT;
|
300 |
-
}
|
301 |
-
|
302 |
-
/**
|
303 |
-
* alias
|
304 |
-
* @return int
|
305 |
-
* @deprecated
|
306 |
-
*/
|
307 |
-
public function time() {
|
308 |
-
return $this->ts();
|
309 |
-
}
|
310 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-serviceproviders.php
CHANGED
@@ -10,11 +10,6 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
10 |
const URL_STATUS_CAKE_IPS = 'https://app.statuscake.com/Workfloor/Locations.php?format=json';
|
11 |
const URL_ICONTROLWP_IPS = 'https://serviceips.icontrolwp.com/';
|
12 |
|
13 |
-
/**
|
14 |
-
* @var string
|
15 |
-
*/
|
16 |
-
protected $sPrefix = '';
|
17 |
-
|
18 |
/**
|
19 |
* @var ICWP_WPSF_ServiceProviders
|
20 |
*/
|
@@ -34,7 +29,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
34 |
* @return string[][]
|
35 |
*/
|
36 |
public function getIps_CloudFlare() {
|
37 |
-
$oWp =
|
38 |
|
39 |
$sStoreKey = $this->prefix( 'serviceips_cloudflare' );
|
40 |
$aIps = $oWp->getTransient( $sStoreKey );
|
@@ -76,7 +71,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
76 |
* @return array[]|string[]
|
77 |
*/
|
78 |
public function getIps_iControlWP( $bFlat = false ) {
|
79 |
-
$oWp =
|
80 |
|
81 |
$sStoreKey = $this->prefix( 'serviceips_icontrolwp' );
|
82 |
$aIps = $oWp->getTransient( $sStoreKey );
|
@@ -92,7 +87,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
92 |
* @return array[]
|
93 |
*/
|
94 |
public function getIps_ManageWp() {
|
95 |
-
$oWp =
|
96 |
|
97 |
$sStoreKey = $this->prefix( 'serviceips_managewp' );
|
98 |
$aIps = $oWp->getTransient( $sStoreKey );
|
@@ -107,7 +102,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
107 |
* @return string[][]
|
108 |
*/
|
109 |
public function getIps_Pingdom() {
|
110 |
-
$oWp =
|
111 |
|
112 |
$sStoreKey = $this->prefix( 'serviceips_pingdom' );
|
113 |
$aIps = $oWp->getTransient( $sStoreKey );
|
@@ -125,7 +120,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
125 |
* @return string[]
|
126 |
*/
|
127 |
public function getIps_Statuscake() {
|
128 |
-
$oWp =
|
129 |
|
130 |
$sStoreKey = $this->prefix( 'serviceips_statuscake' );
|
131 |
$aIps = $oWp->getTransient( $sStoreKey );
|
@@ -140,7 +135,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
140 |
* @return array[]
|
141 |
*/
|
142 |
public function getIps_UptimeRobot() {
|
143 |
-
$oWp =
|
144 |
|
145 |
$sStoreKey = $this->prefix( 'serviceips_uptimerobot' );
|
146 |
$aIps = $oWp->getTransient( $sStoreKey );
|
@@ -160,7 +155,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
160 |
* @return bool
|
161 |
*/
|
162 |
public function isIp_AppleBot( $sIp, $sUserAgent ) {
|
163 |
-
$oWp =
|
164 |
|
165 |
$sStoreKey = $this->prefix( 'serviceips_applebot' );
|
166 |
$aIps = $oWp->getTransient( $sStoreKey );
|
@@ -182,7 +177,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
182 |
* @return bool
|
183 |
*/
|
184 |
public function isIp_BaiduBot( $sIp, $sUserAgent ) {
|
185 |
-
$oWp =
|
186 |
|
187 |
$sStoreKey = $this->prefix( 'serviceips_baidubot' );
|
188 |
$aIps = $oWp->getTransient( $sStoreKey );
|
@@ -275,7 +270,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
275 |
* @return bool
|
276 |
*/
|
277 |
public function isIp_GoogleBot( $sIp, $sUserAgent ) {
|
278 |
-
$oWp =
|
279 |
|
280 |
$sStoreKey = $this->prefix( 'serviceips_googlebot' );
|
281 |
$aIps = $oWp->getTransient( $sStoreKey );
|
@@ -340,7 +335,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
340 |
* @return bool
|
341 |
*/
|
342 |
public function isIp_YandexBot( $sIp, $sUserAgent ) {
|
343 |
-
$oWp =
|
344 |
|
345 |
$sStoreKey = $this->prefix( 'serviceips_yandexbot' );
|
346 |
$aIps = $oWp->getTransient( $sStoreKey );
|
@@ -363,7 +358,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
|
|
363 |
* @return bool
|
364 |
*/
|
365 |
public function isIp_YahooBot( $sIp, $sUserAgent ) {
|
366 |
-
$oWp =
|
367 |
|
368 |
$sStoreKey = $this->prefix( 'serviceips_yahoobot' );
|
369 |
$aIps = $oWp->getTransient( $sStoreKey );
|
10 |
const URL_STATUS_CAKE_IPS = 'https://app.statuscake.com/Workfloor/Locations.php?format=json';
|
11 |
const URL_ICONTROLWP_IPS = 'https://serviceips.icontrolwp.com/';
|
12 |
|
|
|
|
|
|
|
|
|
|
|
13 |
/**
|
14 |
* @var ICWP_WPSF_ServiceProviders
|
15 |
*/
|
29 |
* @return string[][]
|
30 |
*/
|
31 |
public function getIps_CloudFlare() {
|
32 |
+
$oWp = Services::WpGeneral();
|
33 |
|
34 |
$sStoreKey = $this->prefix( 'serviceips_cloudflare' );
|
35 |
$aIps = $oWp->getTransient( $sStoreKey );
|
71 |
* @return array[]|string[]
|
72 |
*/
|
73 |
public function getIps_iControlWP( $bFlat = false ) {
|
74 |
+
$oWp = Services::WpGeneral();
|
75 |
|
76 |
$sStoreKey = $this->prefix( 'serviceips_icontrolwp' );
|
77 |
$aIps = $oWp->getTransient( $sStoreKey );
|
87 |
* @return array[]
|
88 |
*/
|
89 |
public function getIps_ManageWp() {
|
90 |
+
$oWp = Services::WpGeneral();
|
91 |
|
92 |
$sStoreKey = $this->prefix( 'serviceips_managewp' );
|
93 |
$aIps = $oWp->getTransient( $sStoreKey );
|
102 |
* @return string[][]
|
103 |
*/
|
104 |
public function getIps_Pingdom() {
|
105 |
+
$oWp = Services::WpGeneral();
|
106 |
|
107 |
$sStoreKey = $this->prefix( 'serviceips_pingdom' );
|
108 |
$aIps = $oWp->getTransient( $sStoreKey );
|
120 |
* @return string[]
|
121 |
*/
|
122 |
public function getIps_Statuscake() {
|
123 |
+
$oWp = Services::WpGeneral();
|
124 |
|
125 |
$sStoreKey = $this->prefix( 'serviceips_statuscake' );
|
126 |
$aIps = $oWp->getTransient( $sStoreKey );
|
135 |
* @return array[]
|
136 |
*/
|
137 |
public function getIps_UptimeRobot() {
|
138 |
+
$oWp = Services::WpGeneral();
|
139 |
|
140 |
$sStoreKey = $this->prefix( 'serviceips_uptimerobot' );
|
141 |
$aIps = $oWp->getTransient( $sStoreKey );
|
155 |
* @return bool
|
156 |
*/
|
157 |
public function isIp_AppleBot( $sIp, $sUserAgent ) {
|
158 |
+
$oWp = Services::WpGeneral();
|
159 |
|
160 |
$sStoreKey = $this->prefix( 'serviceips_applebot' );
|
161 |
$aIps = $oWp->getTransient( $sStoreKey );
|
177 |
* @return bool
|
178 |
*/
|
179 |
public function isIp_BaiduBot( $sIp, $sUserAgent ) {
|
180 |
+
$oWp = Services::WpGeneral();
|
181 |
|
182 |
$sStoreKey = $this->prefix( 'serviceips_baidubot' );
|
183 |
$aIps = $oWp->getTransient( $sStoreKey );
|
270 |
* @return bool
|
271 |
*/
|
272 |
public function isIp_GoogleBot( $sIp, $sUserAgent ) {
|
273 |
+
$oWp = Services::WpGeneral();
|
274 |
|
275 |
$sStoreKey = $this->prefix( 'serviceips_googlebot' );
|
276 |
$aIps = $oWp->getTransient( $sStoreKey );
|
335 |
* @return bool
|
336 |
*/
|
337 |
public function isIp_YandexBot( $sIp, $sUserAgent ) {
|
338 |
+
$oWp = Services::WpGeneral();
|
339 |
|
340 |
$sStoreKey = $this->prefix( 'serviceips_yandexbot' );
|
341 |
$aIps = $oWp->getTransient( $sStoreKey );
|
358 |
* @return bool
|
359 |
*/
|
360 |
public function isIp_YahooBot( $sIp, $sUserAgent ) {
|
361 |
+
$oWp = Services::WpGeneral();
|
362 |
|
363 |
$sStoreKey = $this->prefix( 'serviceips_yahoobot' );
|
364 |
$aIps = $oWp->getTransient( $sStoreKey );
|
src/common/icwp-wpdb.php
DELETED
@@ -1,237 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class ICWP_WPSF_WpDb {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var ICWP_WPSF_WpDb
|
7 |
-
*/
|
8 |
-
protected static $oInstance = null;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var wpdb
|
12 |
-
*/
|
13 |
-
protected $oWpdb;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @return ICWP_WPSF_WpDb
|
17 |
-
*/
|
18 |
-
public static function GetInstance() {
|
19 |
-
if ( is_null( self::$oInstance ) ) {
|
20 |
-
self::$oInstance = new self;
|
21 |
-
}
|
22 |
-
return self::$oInstance;
|
23 |
-
}
|
24 |
-
|
25 |
-
public function __construct() {
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @param string $sSQL
|
30 |
-
* @return array
|
31 |
-
*/
|
32 |
-
public function dbDelta( $sSQL ) {
|
33 |
-
require_once( ABSPATH.'wp-admin/includes/upgrade.php' );
|
34 |
-
return dbDelta( $sSQL );
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* @param string $sTable
|
39 |
-
* @param array $aWhere - delete where (associative array)
|
40 |
-
* @return false|int
|
41 |
-
*/
|
42 |
-
public function deleteRowsFromTableWhere( $sTable, $aWhere ) {
|
43 |
-
return $this->loadWpdb()->delete( $sTable, $aWhere );
|
44 |
-
}
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Will completely remove this table from the database
|
48 |
-
* @param string $sTable
|
49 |
-
* @return bool|int
|
50 |
-
*/
|
51 |
-
public function doDropTable( $sTable ) {
|
52 |
-
$sQuery = sprintf( 'DROP TABLE IF EXISTS `%s`', $sTable );
|
53 |
-
return $this->doSql( $sQuery );
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Alias for doTruncateTable()
|
58 |
-
* @param string $sTable
|
59 |
-
* @return bool|int
|
60 |
-
*/
|
61 |
-
public function doEmptyTable( $sTable ) {
|
62 |
-
return $this->doTruncateTable( $sTable );
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* Given any SQL query, will perform it using the WordPress database object.
|
67 |
-
* @param string $sSqlQuery
|
68 |
-
* @return integer|boolean (number of rows affected or just true/false)
|
69 |
-
*/
|
70 |
-
public function doSql( $sSqlQuery ) {
|
71 |
-
return $this->loadWpdb()->query( $sSqlQuery );
|
72 |
-
}
|
73 |
-
|
74 |
-
/**
|
75 |
-
* @param string $sTable
|
76 |
-
* @return bool|int
|
77 |
-
*/
|
78 |
-
public function doTruncateTable( $sTable ) {
|
79 |
-
if ( !$this->getIfTableExists( $sTable ) ) {
|
80 |
-
return false;
|
81 |
-
}
|
82 |
-
$sQuery = sprintf( 'TRUNCATE TABLE `%s`', $sTable );
|
83 |
-
return $this->doSql( $sQuery );
|
84 |
-
}
|
85 |
-
|
86 |
-
public function getCharCollate() {
|
87 |
-
return $this->getWpdb()->get_charset_collate();
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* @param string $sTable
|
92 |
-
* @return bool
|
93 |
-
*/
|
94 |
-
public function getIfTableExists( $sTable ) {
|
95 |
-
$sQuery = sprintf( "SHOW TABLES LIKE '%s'", $sTable );
|
96 |
-
$mResult = $this->loadWpdb()->get_var( $sQuery );
|
97 |
-
return !is_null( $mResult );
|
98 |
-
}
|
99 |
-
|
100 |
-
/**
|
101 |
-
* @param string $sTableName
|
102 |
-
* @param string $sArrayMapCallBack
|
103 |
-
* @return array
|
104 |
-
*/
|
105 |
-
public function getColumnsForTable( $sTableName, $sArrayMapCallBack = '' ) {
|
106 |
-
$aColumns = $this->loadWpdb()->get_col( "DESCRIBE ".$sTableName, 0 );
|
107 |
-
|
108 |
-
if ( !empty( $sArrayMapCallBack ) && function_exists( $sArrayMapCallBack ) ) {
|
109 |
-
return array_map( $sArrayMapCallBack, $aColumns );
|
110 |
-
}
|
111 |
-
return $aColumns;
|
112 |
-
}
|
113 |
-
|
114 |
-
/**
|
115 |
-
* @param bool $bSiteBase
|
116 |
-
* @return string
|
117 |
-
*/
|
118 |
-
public function getPrefix( $bSiteBase = true ) {
|
119 |
-
$oDb = $this->loadWpdb();
|
120 |
-
return $bSiteBase ? $oDb->base_prefix : $oDb->prefix;
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* @return string
|
125 |
-
*/
|
126 |
-
public function getTable_Comments() {
|
127 |
-
return $this->loadWpdb()->comments;
|
128 |
-
}
|
129 |
-
|
130 |
-
/**
|
131 |
-
* @return string
|
132 |
-
*/
|
133 |
-
public function getTable_Options() {
|
134 |
-
return $this->loadWpdb()->options;
|
135 |
-
}
|
136 |
-
|
137 |
-
/**
|
138 |
-
* @return string
|
139 |
-
*/
|
140 |
-
public function getTable_Posts() {
|
141 |
-
return $this->loadWpdb()->posts;
|
142 |
-
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* @return string
|
146 |
-
*/
|
147 |
-
public function getTable_Users() {
|
148 |
-
return $this->loadWpdb()->users;
|
149 |
-
}
|
150 |
-
|
151 |
-
/**
|
152 |
-
* @param $sSql
|
153 |
-
* @return null|mixed
|
154 |
-
*/
|
155 |
-
public function getVar( $sSql ) {
|
156 |
-
return $this->loadWpdb()->get_var( $sSql );
|
157 |
-
}
|
158 |
-
|
159 |
-
/**
|
160 |
-
* @param string $sTable
|
161 |
-
* @param array $aData
|
162 |
-
* @return int|false
|
163 |
-
*/
|
164 |
-
public function insertDataIntoTable( $sTable, $aData ) {
|
165 |
-
return $this->loadWpdb()->insert( $sTable, $aData );
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* @param string $sTable
|
170 |
-
* @param string $nFormat
|
171 |
-
* @return mixed
|
172 |
-
*/
|
173 |
-
public function selectAllFromTable( $sTable, $nFormat = ARRAY_A ) {
|
174 |
-
$sQuery = sprintf( "SELECT * FROM `%s` WHERE `deleted_at` = 0", $sTable );
|
175 |
-
return $this->loadWpdb()->get_results( $sQuery, $nFormat );
|
176 |
-
}
|
177 |
-
|
178 |
-
/**
|
179 |
-
* @param string $sQuery
|
180 |
-
* @param $nFormat
|
181 |
-
* @return array|boolean
|
182 |
-
*/
|
183 |
-
public function selectCustom( $sQuery, $nFormat = ARRAY_A ) {
|
184 |
-
return $this->loadWpdb()->get_results( $sQuery, $nFormat );
|
185 |
-
}
|
186 |
-
|
187 |
-
/**
|
188 |
-
* @param string $sQuery
|
189 |
-
* @param string $nTotalCountKey
|
190 |
-
* @return array|boolean
|
191 |
-
*/
|
192 |
-
public function selectCount( $sQuery, $nTotalCountKey = 'total' ) {
|
193 |
-
$nCount = -1;
|
194 |
-
$aResult = $this->selectCustom( $sQuery, ARRAY_A );
|
195 |
-
if ( is_array( $aResult ) ) {
|
196 |
-
$nCount = (int)$aResult[ 0 ][ $nTotalCountKey ];
|
197 |
-
}
|
198 |
-
return $nCount;
|
199 |
-
}
|
200 |
-
|
201 |
-
/**
|
202 |
-
* @param $sQuery
|
203 |
-
* @param string $nFormat
|
204 |
-
* @return null|object|array
|
205 |
-
*/
|
206 |
-
public function selectRow( $sQuery, $nFormat = ARRAY_A ) {
|
207 |
-
return $this->loadWpdb()->get_row( $sQuery, $nFormat );
|
208 |
-
}
|
209 |
-
|
210 |
-
/**
|
211 |
-
* @param string $sTable
|
212 |
-
* @param array $aData - new insert data (associative array, column=>data)
|
213 |
-
* @param array $aWhere - insert where (associative array)
|
214 |
-
* @return integer|boolean (number of rows affected)
|
215 |
-
*/
|
216 |
-
public function updateRowsFromTableWhere( $sTable, $aData, $aWhere ) {
|
217 |
-
return $this->loadWpdb()->update( $sTable, $aData, $aWhere );
|
218 |
-
}
|
219 |
-
|
220 |
-
/**
|
221 |
-
* Loads our WPDB object if required.
|
222 |
-
* @return \wpdb
|
223 |
-
*/
|
224 |
-
protected function loadWpdb() {
|
225 |
-
if ( is_null( $this->oWpdb ) ) {
|
226 |
-
$this->oWpdb = $this->getWpdb();
|
227 |
-
}
|
228 |
-
return $this->oWpdb;
|
229 |
-
}
|
230 |
-
|
231 |
-
/**
|
232 |
-
*/
|
233 |
-
private function getWpdb() {
|
234 |
-
global $wpdb;
|
235 |
-
return $wpdb;
|
236 |
-
}
|
237 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-wpfilesystem.php
DELETED
@@ -1,492 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Services\Services;
|
4 |
-
|
5 |
-
class ICWP_WPSF_WpFilesystem {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @var ICWP_WPSF_WpFilesystem
|
9 |
-
*/
|
10 |
-
protected static $oInstance = null;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var WP_Filesystem_Base
|
14 |
-
*/
|
15 |
-
protected $oWpfs = null;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string
|
19 |
-
*/
|
20 |
-
protected $sWpConfigPath = null;
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @return ICWP_WPSF_WpFilesystem
|
24 |
-
*/
|
25 |
-
public static function GetInstance() {
|
26 |
-
if ( is_null( self::$oInstance ) ) {
|
27 |
-
self::$oInstance = new self();
|
28 |
-
}
|
29 |
-
return self::$oInstance;
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @param string $sBase
|
34 |
-
* @param string $sPath
|
35 |
-
* @return string
|
36 |
-
*/
|
37 |
-
public function pathJoin( $sBase, $sPath ) {
|
38 |
-
return rtrim( $sBase, DIRECTORY_SEPARATOR ).DIRECTORY_SEPARATOR.ltrim( $sPath, DIRECTORY_SEPARATOR );
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* @param $sFilePath
|
43 |
-
* @return boolean|null true/false whether file/directory exists
|
44 |
-
*/
|
45 |
-
public function exists( $sFilePath ) {
|
46 |
-
$oFs = $this->getWpfs();
|
47 |
-
if ( $oFs && $oFs->exists( $sFilePath ) ) {
|
48 |
-
return true;
|
49 |
-
}
|
50 |
-
return function_exists( 'file_exists' ) ? file_exists( $sFilePath ) : null;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* @param string $sNeedle
|
55 |
-
* @param string $sDir
|
56 |
-
* @param boolean $bIncludeExtension
|
57 |
-
* @param boolean $bCaseSensitive
|
58 |
-
* @return string|null - the full path to the file if found
|
59 |
-
*/
|
60 |
-
public function fileExistsInDir( $sNeedle, $sDir, $bIncludeExtension = true, $bCaseSensitive = false ) {
|
61 |
-
if ( empty( $sNeedle ) || empty( $sDir ) ) {
|
62 |
-
return false;
|
63 |
-
}
|
64 |
-
|
65 |
-
if ( !$bCaseSensitive ) {
|
66 |
-
$sNeedle = strtolower( $sNeedle );
|
67 |
-
}
|
68 |
-
|
69 |
-
//if the file you're searching for doesn't have an extension, then we don't include extensions in search
|
70 |
-
$nDotPosition = strpos( $sNeedle, '.' );
|
71 |
-
$bHasExtension = $nDotPosition !== false;
|
72 |
-
$bIncludeExtension = $bIncludeExtension && $bHasExtension;
|
73 |
-
|
74 |
-
$sNeedlePreExtension = $bHasExtension ? substr( $sNeedle, 0, $nDotPosition ) : $sNeedle;
|
75 |
-
|
76 |
-
$bFound = false;
|
77 |
-
$sFullPath = null;
|
78 |
-
foreach ( $this->getFilesInDir( $sDir ) as $oFileItem ) {
|
79 |
-
|
80 |
-
$sFilename = $oFileItem->getFilename();
|
81 |
-
if ( !$bCaseSensitive ) {
|
82 |
-
$sFilename = strtolower( $sFilename );
|
83 |
-
}
|
84 |
-
|
85 |
-
if ( $bIncludeExtension ) {
|
86 |
-
$bFound = ( $sFilename == $sNeedle );
|
87 |
-
}
|
88 |
-
else {
|
89 |
-
// This is not entirely accurate as it only finds whether a file "starts" with needle, ignoring subsequent characters
|
90 |
-
$bFound = ( strpos( $sFilename, $sNeedlePreExtension ) === 0 );
|
91 |
-
}
|
92 |
-
|
93 |
-
if ( $bFound ) {
|
94 |
-
$sFullPath = $oFileItem->getPathname();
|
95 |
-
break;
|
96 |
-
}
|
97 |
-
}
|
98 |
-
|
99 |
-
return $sFullPath;
|
100 |
-
}
|
101 |
-
|
102 |
-
/**
|
103 |
-
* @param string $sDir
|
104 |
-
* @param int $nMaxDepth - set to zero for no max
|
105 |
-
* @param RecursiveDirectoryIterator $oDirIterator
|
106 |
-
* @return SplFileInfo[]
|
107 |
-
*/
|
108 |
-
public function getFilesInDir( $sDir, $nMaxDepth = 1, $oDirIterator = null ) {
|
109 |
-
$aList = [];
|
110 |
-
|
111 |
-
try {
|
112 |
-
if ( empty( $oDirIterator ) ) {
|
113 |
-
$oDirIterator = new RecursiveDirectoryIterator( $sDir );
|
114 |
-
if ( method_exists( $oDirIterator, 'setFlags' ) ) {
|
115 |
-
$oDirIterator->setFlags( RecursiveDirectoryIterator::SKIP_DOTS );
|
116 |
-
}
|
117 |
-
}
|
118 |
-
|
119 |
-
$oRecurIter = new RecursiveIteratorIterator( $oDirIterator );
|
120 |
-
$oRecurIter->setMaxDepth( $nMaxDepth - 1 ); //since they start at zero.
|
121 |
-
|
122 |
-
/** @var SplFileInfo $oFile */
|
123 |
-
foreach ( $oRecurIter as $oFile ) {
|
124 |
-
$aList[] = clone $oFile;
|
125 |
-
}
|
126 |
-
}
|
127 |
-
catch ( Exception $oE ) { // UnexpectedValueException, RuntimeException, Exception
|
128 |
-
}
|
129 |
-
|
130 |
-
return $aList;
|
131 |
-
}
|
132 |
-
|
133 |
-
/**
|
134 |
-
* Returns a path where all backslashes "\" are converted to "/"
|
135 |
-
* @param string $sPath
|
136 |
-
* @return string
|
137 |
-
*/
|
138 |
-
public function normalizeFilePathDS( $sPath ) {
|
139 |
-
return ( DIRECTORY_SEPARATOR == '/' ) ? $sPath : str_replace( '\\', '/', $sPath );
|
140 |
-
}
|
141 |
-
|
142 |
-
protected function setWpConfigPath() {
|
143 |
-
$this->sWpConfigPath = ABSPATH.'wp-config.php';
|
144 |
-
if ( !$this->exists( $this->sWpConfigPath ) ) {
|
145 |
-
$this->sWpConfigPath = ABSPATH.'../wp-config.php';
|
146 |
-
if ( !$this->exists( $this->sWpConfigPath ) ) {
|
147 |
-
$this->sWpConfigPath = false;
|
148 |
-
}
|
149 |
-
}
|
150 |
-
}
|
151 |
-
|
152 |
-
public function getContent_WpConfig() {
|
153 |
-
return $this->getFileContent( $this->sWpConfigPath );
|
154 |
-
}
|
155 |
-
|
156 |
-
/**
|
157 |
-
* @param string $sContent
|
158 |
-
* @return bool
|
159 |
-
*/
|
160 |
-
public function putContent_WpConfig( $sContent ) {
|
161 |
-
return $this->putFileContent( $this->sWpConfigPath, $sContent );
|
162 |
-
}
|
163 |
-
|
164 |
-
/**
|
165 |
-
* @param string $sUrl
|
166 |
-
* @param boolean $bSecure
|
167 |
-
* @return boolean
|
168 |
-
*/
|
169 |
-
public function isUrlLive( $sUrl, $bSecure = false ) {
|
170 |
-
$sSchema = $bSecure ? 'https://' : 'http://';
|
171 |
-
$sUrl = ( strpos( $sUrl, 'http' ) !== 0 ) ? $sSchema.$sUrl : $sUrl;
|
172 |
-
return ( $this->getUrl( $sUrl ) != false );
|
173 |
-
}
|
174 |
-
|
175 |
-
/**
|
176 |
-
* @return string
|
177 |
-
*/
|
178 |
-
public function getWpConfigPath() {
|
179 |
-
return $this->sWpConfigPath;
|
180 |
-
}
|
181 |
-
|
182 |
-
/**
|
183 |
-
* @param string $sUrl
|
184 |
-
* @param array $aRequestArgs
|
185 |
-
* @param bool $bAlwaysRawResponse
|
186 |
-
* @return array|WP_Error|bool
|
187 |
-
*/
|
188 |
-
public function requestUrl( $sUrl, $aRequestArgs = [], $bAlwaysRawResponse = false ) {
|
189 |
-
|
190 |
-
$mResult = wp_remote_request( $sUrl, $aRequestArgs );
|
191 |
-
if ( $bAlwaysRawResponse ) {
|
192 |
-
return $mResult;
|
193 |
-
}
|
194 |
-
if ( is_wp_error( $mResult ) || !isset( $mResult[ 'response' ][ 'code' ] ) || $mResult[ 'response' ][ 'code' ] != 200 ) {
|
195 |
-
return false;
|
196 |
-
}
|
197 |
-
return $mResult;
|
198 |
-
}
|
199 |
-
|
200 |
-
/**
|
201 |
-
* @param string $sUrl
|
202 |
-
* @param array $aRequestArgs
|
203 |
-
* @return array|bool
|
204 |
-
*/
|
205 |
-
public function getUrl( $sUrl, $aRequestArgs = [] ) {
|
206 |
-
$aRequestArgs[ 'method' ] = 'GET';
|
207 |
-
return $this->requestUrl( $sUrl, $aRequestArgs );
|
208 |
-
}
|
209 |
-
|
210 |
-
/**
|
211 |
-
* @param string $sUrl
|
212 |
-
* @param array $aRequestArgs
|
213 |
-
* @return false|string
|
214 |
-
*/
|
215 |
-
public function getUrlContent( $sUrl, $aRequestArgs = [] ) {
|
216 |
-
$aResponse = $this->getUrl( $sUrl, $aRequestArgs );
|
217 |
-
if ( !$aResponse || !isset( $aResponse[ 'body' ] ) ) {
|
218 |
-
return false;
|
219 |
-
}
|
220 |
-
return $aResponse[ 'body' ];
|
221 |
-
}
|
222 |
-
|
223 |
-
/**
|
224 |
-
* @param string $sUrl
|
225 |
-
* @param array $aRequestArgs
|
226 |
-
* @return array|false
|
227 |
-
* @deprecated
|
228 |
-
*/
|
229 |
-
public function postUrl( $sUrl, $aRequestArgs = [] ) {
|
230 |
-
$aRequestArgs[ 'method' ] = 'POST';
|
231 |
-
return $this->requestUrl( $sUrl, $aRequestArgs );
|
232 |
-
}
|
233 |
-
|
234 |
-
public function getCanWpRemoteGet() {
|
235 |
-
$aUrlsToTest = [
|
236 |
-
'https://www.microsoft.com',
|
237 |
-
'https://www.google.com',
|
238 |
-
'https://www.facebook.com'
|
239 |
-
];
|
240 |
-
foreach ( $aUrlsToTest as $sUrl ) {
|
241 |
-
if ( $this->getUrl( $sUrl ) !== false ) {
|
242 |
-
return true;
|
243 |
-
}
|
244 |
-
}
|
245 |
-
return false;
|
246 |
-
}
|
247 |
-
|
248 |
-
public function getCanDiskWrite() {
|
249 |
-
$sFilePath = __DIR__.'/testfile.'.rand().'txt';
|
250 |
-
$sContents = "Testing icwp file read and write.";
|
251 |
-
|
252 |
-
// Write, read, verify, delete.
|
253 |
-
if ( $this->putFileContent( $sFilePath, $sContents ) ) {
|
254 |
-
$sFileContents = $this->getFileContent( $sFilePath );
|
255 |
-
if ( !is_null( $sFileContents ) && $sFileContents === $sContents ) {
|
256 |
-
return $this->deleteFile( $sFilePath );
|
257 |
-
}
|
258 |
-
}
|
259 |
-
return false;
|
260 |
-
}
|
261 |
-
|
262 |
-
/**
|
263 |
-
* @param string $sFilePath
|
264 |
-
* @return int|null
|
265 |
-
*/
|
266 |
-
public function getModifiedTime( $sFilePath ) {
|
267 |
-
return $this->getTime( $sFilePath, 'modified' );
|
268 |
-
}
|
269 |
-
|
270 |
-
/**
|
271 |
-
* @param string $sFilePath
|
272 |
-
* @return int|null
|
273 |
-
*/
|
274 |
-
public function getAccessedTime( $sFilePath ) {
|
275 |
-
return $this->getTime( $sFilePath, 'accessed' );
|
276 |
-
}
|
277 |
-
|
278 |
-
/**
|
279 |
-
* @param string $sFilePath
|
280 |
-
* @param string $sProperty
|
281 |
-
* @return int|null
|
282 |
-
*/
|
283 |
-
public function getTime( $sFilePath, $sProperty = 'modified' ) {
|
284 |
-
|
285 |
-
if ( !$this->exists( $sFilePath ) ) {
|
286 |
-
return null;
|
287 |
-
}
|
288 |
-
|
289 |
-
$oFs = $this->getWpfs();
|
290 |
-
switch ( $sProperty ) {
|
291 |
-
|
292 |
-
case 'modified' :
|
293 |
-
return $oFs ? $oFs->mtime( $sFilePath ) : filemtime( $sFilePath );
|
294 |
-
break;
|
295 |
-
case 'accessed' :
|
296 |
-
return $oFs ? $oFs->atime( $sFilePath ) : fileatime( $sFilePath );
|
297 |
-
break;
|
298 |
-
default:
|
299 |
-
return null;
|
300 |
-
break;
|
301 |
-
}
|
302 |
-
}
|
303 |
-
|
304 |
-
/**
|
305 |
-
* @param string $sFilePath
|
306 |
-
* @return NULL|boolean
|
307 |
-
*/
|
308 |
-
public function getCanReadWriteFile( $sFilePath ) {
|
309 |
-
if ( !file_exists( $sFilePath ) ) {
|
310 |
-
return null;
|
311 |
-
}
|
312 |
-
|
313 |
-
$nFileSize = filesize( $sFilePath );
|
314 |
-
if ( $nFileSize === 0 ) {
|
315 |
-
return null;
|
316 |
-
}
|
317 |
-
|
318 |
-
$sFileContent = $this->getFileContent( $sFilePath );
|
319 |
-
if ( empty( $sFileContent ) ) {
|
320 |
-
return false; //can't even read the file!
|
321 |
-
}
|
322 |
-
return $this->putFileContent( $sFilePath, $sFileContent );
|
323 |
-
}
|
324 |
-
|
325 |
-
/**
|
326 |
-
* @param string $sFilePath
|
327 |
-
* @return string|null
|
328 |
-
*/
|
329 |
-
public function getFileContent( $sFilePath ) {
|
330 |
-
$sContents = null;
|
331 |
-
$oFs = $this->getWpfs();
|
332 |
-
if ( $oFs ) {
|
333 |
-
$sContents = $oFs->get_contents( $sFilePath );
|
334 |
-
}
|
335 |
-
|
336 |
-
if ( empty( $sContents ) && function_exists( 'file_get_contents' ) ) {
|
337 |
-
$sContents = file_get_contents( $sFilePath );
|
338 |
-
}
|
339 |
-
return $sContents;
|
340 |
-
}
|
341 |
-
|
342 |
-
/**
|
343 |
-
* @param $sFilePath
|
344 |
-
* @return bool
|
345 |
-
*/
|
346 |
-
public function getFileSize( $sFilePath ) {
|
347 |
-
$oFs = $this->getWpfs();
|
348 |
-
if ( $oFs && ( $oFs->size( $sFilePath ) > 0 ) ) {
|
349 |
-
return $oFs->size( $sFilePath );
|
350 |
-
}
|
351 |
-
return @filesize( $sFilePath );
|
352 |
-
}
|
353 |
-
|
354 |
-
/**
|
355 |
-
* @param string|null $sBaseDir
|
356 |
-
* @param string $sPrefix
|
357 |
-
* @param string $outsRandomDir
|
358 |
-
* @return bool|string
|
359 |
-
*/
|
360 |
-
public function getTempDir( $sBaseDir = null, $sPrefix = '', &$outsRandomDir = '' ) {
|
361 |
-
$sTemp = rtrim( ( is_null( $sBaseDir ) ? get_temp_dir() : $sBaseDir ), DIRECTORY_SEPARATOR ).DIRECTORY_SEPARATOR;
|
362 |
-
|
363 |
-
$sCharset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz0123456789';
|
364 |
-
do {
|
365 |
-
$sDir = $sPrefix;
|
366 |
-
for ( $i = 0 ; $i < 8 ; $i++ ) {
|
367 |
-
$sDir .= $sCharset[ ( rand()%strlen( $sCharset ) ) ];
|
368 |
-
}
|
369 |
-
} while ( is_dir( $sTemp.$sDir ) );
|
370 |
-
|
371 |
-
$outsRandomDir = $sDir;
|
372 |
-
|
373 |
-
$bSuccess = true;
|
374 |
-
if ( !@mkdir( $sTemp.$sDir, 0755, true ) ) {
|
375 |
-
$bSuccess = false;
|
376 |
-
}
|
377 |
-
return ( $bSuccess ? $sTemp.$sDir : false );
|
378 |
-
}
|
379 |
-
|
380 |
-
/**
|
381 |
-
* @param string $sFilePath
|
382 |
-
* @param string $sContents
|
383 |
-
* @return boolean
|
384 |
-
*/
|
385 |
-
public function putFileContent( $sFilePath, $sContents ) {
|
386 |
-
$oFs = $this->getWpfs();
|
387 |
-
if ( $oFs && $oFs->put_contents( $sFilePath, $sContents, FS_CHMOD_FILE ) ) {
|
388 |
-
return true;
|
389 |
-
}
|
390 |
-
|
391 |
-
if ( function_exists( 'file_put_contents' ) ) {
|
392 |
-
return file_put_contents( $sFilePath, $sContents ) !== false;
|
393 |
-
}
|
394 |
-
return false;
|
395 |
-
}
|
396 |
-
|
397 |
-
/**
|
398 |
-
* Recursive delete
|
399 |
-
* @param string $sDir
|
400 |
-
* @return bool
|
401 |
-
*/
|
402 |
-
public function deleteDir( $sDir ) {
|
403 |
-
$oFs = $this->getWpfs();
|
404 |
-
if ( $oFs && $oFs->rmdir( $sDir, true ) ) {
|
405 |
-
return true;
|
406 |
-
}
|
407 |
-
return @rmdir( $sDir );
|
408 |
-
}
|
409 |
-
|
410 |
-
/**
|
411 |
-
* @param string $sFilePath
|
412 |
-
* @return boolean|null
|
413 |
-
*/
|
414 |
-
public function deleteFile( $sFilePath ) {
|
415 |
-
$oFs = $this->getWpfs();
|
416 |
-
if ( $oFs && $oFs->delete( $sFilePath ) ) {
|
417 |
-
return true;
|
418 |
-
}
|
419 |
-
return function_exists( 'unlink' ) ? @unlink( $sFilePath ) : null;
|
420 |
-
}
|
421 |
-
|
422 |
-
/**
|
423 |
-
* @param string $sFilePathSource
|
424 |
-
* @param string $sFilePathDestination
|
425 |
-
* @return bool|null
|
426 |
-
*/
|
427 |
-
public function move( $sFilePathSource, $sFilePathDestination ) {
|
428 |
-
$oFs = $this->getWpfs();
|
429 |
-
if ( $oFs && $oFs->move( $sFilePathSource, $sFilePathDestination ) ) {
|
430 |
-
return true;
|
431 |
-
}
|
432 |
-
return function_exists( 'rename' ) ? @rename( $sFilePathSource, $sFilePathDestination ) : null;
|
433 |
-
}
|
434 |
-
|
435 |
-
/**
|
436 |
-
* @param $sFilePath
|
437 |
-
* @return bool|mixed
|
438 |
-
*/
|
439 |
-
public function isFile( $sFilePath ) {
|
440 |
-
$oFs = $this->getWpfs();
|
441 |
-
if ( $oFs && $oFs->is_file( $sFilePath ) ) {
|
442 |
-
return true;
|
443 |
-
}
|
444 |
-
return function_exists( 'is_file' ) ? is_file( $sFilePath ) : null;
|
445 |
-
}
|
446 |
-
|
447 |
-
/**
|
448 |
-
* @param $sDirPath
|
449 |
-
* @return bool
|
450 |
-
*/
|
451 |
-
public function mkdir( $sDirPath ) {
|
452 |
-
return wp_mkdir_p( $sDirPath );
|
453 |
-
}
|
454 |
-
|
455 |
-
/**
|
456 |
-
* @param string $sFilePath
|
457 |
-
* @param int $nTime
|
458 |
-
* @return bool|mixed
|
459 |
-
*/
|
460 |
-
public function touch( $sFilePath, $nTime = null ) {
|
461 |
-
$oFs = $this->getWpfs();
|
462 |
-
if ( $oFs && $oFs->touch( $sFilePath, $nTime ) ) {
|
463 |
-
return true;
|
464 |
-
}
|
465 |
-
return function_exists( 'touch' ) ? @touch( $sFilePath, $nTime ) : null;
|
466 |
-
}
|
467 |
-
|
468 |
-
/**
|
469 |
-
* @return WP_Filesystem_Base
|
470 |
-
*/
|
471 |
-
protected function getWpfs() {
|
472 |
-
if ( is_null( $this->oWpfs ) ) {
|
473 |
-
$this->initFileSystem();
|
474 |
-
}
|
475 |
-
return $this->oWpfs;
|
476 |
-
}
|
477 |
-
|
478 |
-
/**
|
479 |
-
*/
|
480 |
-
private function initFileSystem() {
|
481 |
-
if ( is_null( $this->oWpfs ) ) {
|
482 |
-
$this->oWpfs = false;
|
483 |
-
require_once( ABSPATH.'wp-admin/includes/file.php' );
|
484 |
-
if ( WP_Filesystem() ) {
|
485 |
-
global $wp_filesystem;
|
486 |
-
if ( isset( $wp_filesystem ) && is_object( $wp_filesystem ) ) {
|
487 |
-
$this->oWpfs = $wp_filesystem;
|
488 |
-
}
|
489 |
-
}
|
490 |
-
}
|
491 |
-
}
|
492 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-wpfunctions-plugins.php
DELETED
@@ -1,547 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var ICWP_WPSF_WpFunctions_Plugins
|
7 |
-
*/
|
8 |
-
protected static $oInstance = null;
|
9 |
-
|
10 |
-
private function __construct() {
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @return ICWP_WPSF_WpFunctions_Plugins
|
15 |
-
*/
|
16 |
-
public static function GetInstance() {
|
17 |
-
if ( is_null( self::$oInstance ) ) {
|
18 |
-
self::$oInstance = new self();
|
19 |
-
}
|
20 |
-
return self::$oInstance;
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @param string $sPluginFile
|
25 |
-
* @param bool $bNetworkWide
|
26 |
-
* @return null|WP_Error
|
27 |
-
*/
|
28 |
-
public function activate( $sPluginFile, $bNetworkWide = false ) {
|
29 |
-
return activate_plugin( $sPluginFile, '', $bNetworkWide );
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @param string $sPluginFile
|
34 |
-
* @param bool $bNetworkWide
|
35 |
-
* @return null|WP_Error
|
36 |
-
*/
|
37 |
-
protected function activateQuietly( $sPluginFile, $bNetworkWide = false ) {
|
38 |
-
return activate_plugin( $sPluginFile, '', $bNetworkWide, true );
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* @param string $sPluginFile
|
43 |
-
* @param bool $bNetworkWide
|
44 |
-
*/
|
45 |
-
public function deactivate( $sPluginFile, $bNetworkWide = false ) {
|
46 |
-
deactivate_plugins( $sPluginFile, '', $bNetworkWide );
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* @param string $sPluginFile
|
51 |
-
* @param bool $bNetworkWide
|
52 |
-
*/
|
53 |
-
protected function deactivateQuietly( $sPluginFile, $bNetworkWide = false ) {
|
54 |
-
deactivate_plugins( $sPluginFile, true, $bNetworkWide );
|
55 |
-
}
|
56 |
-
|
57 |
-
/**
|
58 |
-
* @param string $sFile
|
59 |
-
* @param bool $bNetworkWide
|
60 |
-
* @return bool
|
61 |
-
*/
|
62 |
-
public function delete( $sFile, $bNetworkWide = false ) {
|
63 |
-
if ( !$this->isInstalled( $sFile ) ) {
|
64 |
-
return false;
|
65 |
-
}
|
66 |
-
|
67 |
-
if ( $this->isActive( $sFile ) ) {
|
68 |
-
$this->deactivate( $sFile, $bNetworkWide );
|
69 |
-
}
|
70 |
-
$this->uninstall( $sFile );
|
71 |
-
|
72 |
-
// delete the folder
|
73 |
-
$sPluginDir = dirname( $sFile );
|
74 |
-
if ( $sPluginDir == '.' ) { //it's not within a sub-folder
|
75 |
-
$sPluginDir = $sFile;
|
76 |
-
}
|
77 |
-
$sPath = path_join( WP_PLUGIN_DIR, $sPluginDir );
|
78 |
-
return $this->loadFS()->deleteDir( $sPath );
|
79 |
-
}
|
80 |
-
|
81 |
-
/**
|
82 |
-
* @param string $sUrlToInstall
|
83 |
-
* @param bool $bOverwrite
|
84 |
-
* @param bool $bMaintenanceMode
|
85 |
-
* @return array
|
86 |
-
*/
|
87 |
-
public function install( $sUrlToInstall, $bOverwrite = true, $bMaintenanceMode = false ) {
|
88 |
-
$this->loadWpUpgrades();
|
89 |
-
|
90 |
-
$aResult = [
|
91 |
-
'successful' => true,
|
92 |
-
'plugin_info' => '',
|
93 |
-
'errors' => []
|
94 |
-
];
|
95 |
-
|
96 |
-
$oUpgraderSkin = new ICWP_Upgrader_Skin();
|
97 |
-
$oUpgrader = new ICWP_Plugin_Upgrader( $oUpgraderSkin );
|
98 |
-
$oUpgrader->setOverwriteMode( $bOverwrite );
|
99 |
-
if ( $bMaintenanceMode ) {
|
100 |
-
$oUpgrader->maintenance_mode( true );
|
101 |
-
}
|
102 |
-
|
103 |
-
ob_start();
|
104 |
-
$sInstallResult = $oUpgrader->install( $sUrlToInstall );
|
105 |
-
ob_end_clean();
|
106 |
-
|
107 |
-
if ( $bMaintenanceMode ) {
|
108 |
-
$oUpgrader->maintenance_mode( false );
|
109 |
-
}
|
110 |
-
|
111 |
-
if ( is_wp_error( $oUpgraderSkin->m_aErrors[ 0 ] ) ) {
|
112 |
-
$aResult[ 'successful' ] = false;
|
113 |
-
$aResult[ 'errors' ] = $oUpgraderSkin->m_aErrors[ 0 ]->get_error_messages();
|
114 |
-
}
|
115 |
-
else {
|
116 |
-
$aResult[ 'plugin_info' ] = $oUpgrader->plugin_info();
|
117 |
-
}
|
118 |
-
|
119 |
-
$aResult[ 'feedback' ] = $oUpgraderSkin->getFeedback();
|
120 |
-
$aResult[ 'raw' ] = $sInstallResult;
|
121 |
-
return $aResult;
|
122 |
-
}
|
123 |
-
|
124 |
-
/**
|
125 |
-
* @param $sSlug
|
126 |
-
* @return array|bool
|
127 |
-
*/
|
128 |
-
public function installFromWpOrg( $sSlug ) {
|
129 |
-
include_once( ABSPATH.'wp-admin/includes/plugin-install.php' );
|
130 |
-
|
131 |
-
$api = plugins_api( 'plugin_information', [
|
132 |
-
'slug' => $sSlug,
|
133 |
-
'fields' => [
|
134 |
-
'sections' => false,
|
135 |
-
],
|
136 |
-
] );
|
137 |
-
|
138 |
-
if ( !is_wp_error( $api ) ) {
|
139 |
-
return $this->install( $api->download_link, true, true );
|
140 |
-
}
|
141 |
-
return false;
|
142 |
-
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* @param string $sFile
|
146 |
-
* @param bool $bUseBackup
|
147 |
-
* @return bool
|
148 |
-
*/
|
149 |
-
public function reinstall( $sFile, $bUseBackup = false ) {
|
150 |
-
$bSuccess = false;
|
151 |
-
|
152 |
-
if ( $this->isInstalled( $sFile ) ) {
|
153 |
-
|
154 |
-
$sSlug = $this->getSlug( $sFile );
|
155 |
-
if ( !empty( $sSlug ) ) {
|
156 |
-
$oFS = $this->loadFS();
|
157 |
-
|
158 |
-
$sDir = dirname( path_join( WP_PLUGIN_DIR, $sFile ) );
|
159 |
-
$sBackupDir = WP_PLUGIN_DIR.'/../'.basename( $sDir ).'bak'.time();
|
160 |
-
if ( $bUseBackup ) {
|
161 |
-
rename( $sDir, $sBackupDir );
|
162 |
-
}
|
163 |
-
|
164 |
-
$aResult = $this->installFromWpOrg( $sSlug );
|
165 |
-
$bSuccess = $aResult[ 'successful' ];
|
166 |
-
if ( $bSuccess ) {
|
167 |
-
wp_update_plugins(); //refreshes our update information
|
168 |
-
if ( $bUseBackup ) {
|
169 |
-
$oFS->deleteDir( $sBackupDir );
|
170 |
-
}
|
171 |
-
}
|
172 |
-
else {
|
173 |
-
if ( $bUseBackup ) {
|
174 |
-
$oFS->deleteDir( $sDir );
|
175 |
-
rename( $sBackupDir, $sDir );
|
176 |
-
}
|
177 |
-
}
|
178 |
-
}
|
179 |
-
}
|
180 |
-
return $bSuccess;
|
181 |
-
}
|
182 |
-
|
183 |
-
/**
|
184 |
-
* @param string $sFile
|
185 |
-
* @return array
|
186 |
-
*/
|
187 |
-
public function update( $sFile ) {
|
188 |
-
$this->loadWpUpgrades();
|
189 |
-
|
190 |
-
$aResult = [
|
191 |
-
'successful' => 1,
|
192 |
-
'errors' => []
|
193 |
-
];
|
194 |
-
|
195 |
-
$oUpgraderSkin = new ICWP_Bulk_Plugin_Upgrader_Skin();
|
196 |
-
$oUpgrader = new Plugin_Upgrader( $oUpgraderSkin );
|
197 |
-
ob_start();
|
198 |
-
$oUpgrader->bulk_upgrade( [ $sFile ] );
|
199 |
-
ob_end_clean();
|
200 |
-
|
201 |
-
if ( isset( $oUpgraderSkin->m_aErrors[ 0 ] ) ) {
|
202 |
-
if ( is_wp_error( $oUpgraderSkin->m_aErrors[ 0 ] ) ) {
|
203 |
-
$aResult[ 'successful' ] = 0;
|
204 |
-
$aResult[ 'errors' ] = $oUpgraderSkin->m_aErrors[ 0 ]->get_error_messages();
|
205 |
-
}
|
206 |
-
}
|
207 |
-
$aResult[ 'feedback' ] = $oUpgraderSkin->getFeedback();
|
208 |
-
return $aResult;
|
209 |
-
}
|
210 |
-
|
211 |
-
/**
|
212 |
-
* @param string $sPluginFile
|
213 |
-
* @return true
|
214 |
-
*/
|
215 |
-
public function uninstall( $sPluginFile ) {
|
216 |
-
return uninstall_plugin( $sPluginFile );
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* @return boolean|null
|
221 |
-
*/
|
222 |
-
protected function checkForUpdates() {
|
223 |
-
|
224 |
-
if ( class_exists( 'WPRC_Installer' ) && method_exists( 'WPRC_Installer', 'wprc_update_plugins' ) ) {
|
225 |
-
WPRC_Installer::wprc_update_plugins();
|
226 |
-
return true;
|
227 |
-
}
|
228 |
-
else if ( function_exists( 'wp_update_plugins' ) ) {
|
229 |
-
return ( wp_update_plugins() !== false );
|
230 |
-
}
|
231 |
-
return null;
|
232 |
-
}
|
233 |
-
|
234 |
-
/**
|
235 |
-
*/
|
236 |
-
protected function clearUpdates() {
|
237 |
-
$sKey = 'update_plugins';
|
238 |
-
$oResponse = $this->loadWp()->getTransient( $sKey );
|
239 |
-
if ( !is_object( $oResponse ) ) {
|
240 |
-
$oResponse = new stdClass();
|
241 |
-
}
|
242 |
-
$oResponse->last_checked = 0;
|
243 |
-
$this->loadWp()->setTransient( $sKey, $oResponse );
|
244 |
-
}
|
245 |
-
|
246 |
-
/**
|
247 |
-
* @param string $sValueToCompare
|
248 |
-
* @param string $sKey
|
249 |
-
* @return null|string
|
250 |
-
*/
|
251 |
-
public function findPluginBy( $sValueToCompare, $sKey = 'Name' ) {
|
252 |
-
$sFile = null;
|
253 |
-
|
254 |
-
foreach ( $this->getPlugins() as $sBaseFileName => $aPluginData ) {
|
255 |
-
if ( isset( $aPluginData[ $sKey ] ) && $sValueToCompare == $aPluginData[ $sKey ] ) {
|
256 |
-
$sFile = $sBaseFileName;
|
257 |
-
break;
|
258 |
-
}
|
259 |
-
}
|
260 |
-
|
261 |
-
return $sFile;
|
262 |
-
}
|
263 |
-
|
264 |
-
/**
|
265 |
-
* @param string $sFile - plugin base file, e.g. wp-folder/wp-plugin.php
|
266 |
-
* @return string
|
267 |
-
*/
|
268 |
-
public function getInstallationDir( $sFile ) {
|
269 |
-
return dirname( path_join( WP_PLUGIN_DIR, $sFile ) );
|
270 |
-
}
|
271 |
-
|
272 |
-
/**
|
273 |
-
* @param string $sPluginFile
|
274 |
-
* @return array|null
|
275 |
-
*/
|
276 |
-
public function getPlugin( $sPluginFile ) {
|
277 |
-
return $this->isInstalled( $sPluginFile ) ? $this->getPlugins()[ $sPluginFile ] : null;
|
278 |
-
}
|
279 |
-
|
280 |
-
/**
|
281 |
-
* @param string $sDirName
|
282 |
-
* @return string|null
|
283 |
-
*/
|
284 |
-
public function getFileFromDirName( $sDirName ) {
|
285 |
-
$sFile = null;
|
286 |
-
if ( !empty( $sDirName ) ) {
|
287 |
-
foreach ( $this->getInstalledBaseFiles() as $sF ) {
|
288 |
-
if ( strpos( $sFile, $sDirName.'/' ) === 0 ) {
|
289 |
-
$sFile = $sF;
|
290 |
-
break;
|
291 |
-
}
|
292 |
-
}
|
293 |
-
}
|
294 |
-
return $sFile;
|
295 |
-
}
|
296 |
-
|
297 |
-
/**
|
298 |
-
* @param string $sPluginFile
|
299 |
-
* @return null|stdClass
|
300 |
-
*/
|
301 |
-
public function getPluginDataAsObject( $sPluginFile ) {
|
302 |
-
$aPlugin = $this->getPlugin( $sPluginFile );
|
303 |
-
return is_null( $aPlugin ) ? null : $this->loadDP()->convertArrayToStdClass( $aPlugin );
|
304 |
-
}
|
305 |
-
|
306 |
-
/**
|
307 |
-
* @param string $sPluginFile
|
308 |
-
* @return int
|
309 |
-
*/
|
310 |
-
public function getActivePluginLoadPosition( $sPluginFile ) {
|
311 |
-
$nPosition = array_search( $sPluginFile, $this->getActivePlugins() );
|
312 |
-
return ( $nPosition === false ) ? -1 : $nPosition;
|
313 |
-
}
|
314 |
-
|
315 |
-
/**
|
316 |
-
* @return array
|
317 |
-
*/
|
318 |
-
public function getActivePlugins() {
|
319 |
-
$oWp = $this->loadWp();
|
320 |
-
$aActive = $oWp->getOption( ( $oWp->isMultisite() ? 'active_sitewide_plugins' : 'active_plugins' ) );
|
321 |
-
return is_array( $aActive ) ? $aActive : [];
|
322 |
-
}
|
323 |
-
|
324 |
-
/**
|
325 |
-
* @return array
|
326 |
-
*/
|
327 |
-
public function getInstalledBaseFiles() {
|
328 |
-
return array_keys( $this->getPlugins() );
|
329 |
-
}
|
330 |
-
|
331 |
-
/**
|
332 |
-
* @return array[]
|
333 |
-
*/
|
334 |
-
public function getPlugins() {
|
335 |
-
if ( !function_exists( 'get_plugins' ) ) {
|
336 |
-
require_once( ABSPATH.'wp-admin/includes/plugin.php' );
|
337 |
-
}
|
338 |
-
$aP = function_exists( 'get_plugins' ) ? get_plugins() : [];
|
339 |
-
return is_array( $aP ) ? $aP : [];
|
340 |
-
}
|
341 |
-
|
342 |
-
/**
|
343 |
-
* @return stdClass[] - keys are plugin base files
|
344 |
-
*/
|
345 |
-
public function getAllExtendedData() {
|
346 |
-
$oData = $this->loadWp()->getTransient( 'update_plugins' );
|
347 |
-
return array_merge(
|
348 |
-
isset( $oData->no_update ) ? $oData->no_update : [],
|
349 |
-
isset( $oData->response ) ? $oData->response : []
|
350 |
-
);
|
351 |
-
}
|
352 |
-
|
353 |
-
/**
|
354 |
-
* @param $sBaseFile
|
355 |
-
* @return null|stdClass
|
356 |
-
*/
|
357 |
-
public function getExtendedData( $sBaseFile ) {
|
358 |
-
$aData = $this->getAllExtendedData();
|
359 |
-
return isset( $aData[ $sBaseFile ] ) ? $aData[ $sBaseFile ] : null;
|
360 |
-
}
|
361 |
-
|
362 |
-
/**
|
363 |
-
* @return array
|
364 |
-
*/
|
365 |
-
public function getAllSlugs() {
|
366 |
-
$aSlugs = [];
|
367 |
-
|
368 |
-
foreach ( $this->getAllExtendedData() as $sBaseName => $oPlugData ) {
|
369 |
-
if ( isset( $oPlugData->slug ) ) {
|
370 |
-
$aSlugs[ $sBaseName ] = $oPlugData->slug;
|
371 |
-
}
|
372 |
-
}
|
373 |
-
|
374 |
-
return $aSlugs;
|
375 |
-
}
|
376 |
-
|
377 |
-
/**
|
378 |
-
* @param $sBaseName
|
379 |
-
* @return string
|
380 |
-
*/
|
381 |
-
public function getSlug( $sBaseName ) {
|
382 |
-
$oPluginInfo = $this->getExtendedData( $sBaseName );
|
383 |
-
return isset( $oPluginInfo->slug ) ? $oPluginInfo->slug : '';
|
384 |
-
}
|
385 |
-
|
386 |
-
/**
|
387 |
-
* @param string $sFile
|
388 |
-
* @return stdClass|null
|
389 |
-
*/
|
390 |
-
public function getUpdateInfo( $sFile ) {
|
391 |
-
$aU = $this->getUpdates();
|
392 |
-
return isset( $aU[ $sFile ] ) ? $aU[ $sFile ] : null;
|
393 |
-
}
|
394 |
-
|
395 |
-
/**
|
396 |
-
* @param string $sFile
|
397 |
-
* @return string
|
398 |
-
*/
|
399 |
-
public function getUpdateNewVersion( $sFile ) {
|
400 |
-
$oInfo = $this->getUpdateInfo( $sFile );
|
401 |
-
return ( !is_null( $oInfo ) && isset( $oInfo->new_version ) ) ? $oInfo->new_version : '';
|
402 |
-
}
|
403 |
-
|
404 |
-
/**
|
405 |
-
* @param bool $bForceUpdateCheck
|
406 |
-
* @return stdClass[]
|
407 |
-
*/
|
408 |
-
public function getUpdates( $bForceUpdateCheck = false ) {
|
409 |
-
if ( $bForceUpdateCheck ) {
|
410 |
-
$this->clearUpdates();
|
411 |
-
$this->checkForUpdates();
|
412 |
-
}
|
413 |
-
$aUpdates = $this->loadWp()->getWordpressUpdates( 'plugins' );
|
414 |
-
return is_array( $aUpdates ) ? $aUpdates : [];
|
415 |
-
}
|
416 |
-
|
417 |
-
/**
|
418 |
-
* @param string $sPluginFile
|
419 |
-
* @return string
|
420 |
-
*/
|
421 |
-
public function getUrl_Activate( $sPluginFile ) {
|
422 |
-
return $this->getUrl_Action( $sPluginFile, 'activate' );
|
423 |
-
}
|
424 |
-
|
425 |
-
/**
|
426 |
-
* @param string $sPluginFile
|
427 |
-
* @return string
|
428 |
-
*/
|
429 |
-
public function getUrl_Deactivate( $sPluginFile ) {
|
430 |
-
return $this->getUrl_Action( $sPluginFile, 'deactivate' );
|
431 |
-
}
|
432 |
-
|
433 |
-
/**
|
434 |
-
* @param string $sPluginFile
|
435 |
-
* @return string
|
436 |
-
*/
|
437 |
-
public function getUrl_Upgrade( $sPluginFile ) {
|
438 |
-
$aQueryArgs = [
|
439 |
-
'action' => 'upgrade-plugin',
|
440 |
-
'plugin' => urlencode( $sPluginFile ),
|
441 |
-
'_wpnonce' => wp_create_nonce( 'upgrade-plugin_'.$sPluginFile )
|
442 |
-
];
|
443 |
-
return add_query_arg( $aQueryArgs, self_admin_url( 'update.php' ) );
|
444 |
-
}
|
445 |
-
|
446 |
-
/**
|
447 |
-
* @param string $sPluginFile
|
448 |
-
* @param string $sAction
|
449 |
-
* @return string
|
450 |
-
*/
|
451 |
-
protected function getUrl_Action( $sPluginFile, $sAction ) {
|
452 |
-
return add_query_arg(
|
453 |
-
[
|
454 |
-
'action' => $sAction,
|
455 |
-
'plugin' => urlencode( $sPluginFile ),
|
456 |
-
'_wpnonce' => wp_create_nonce( $sAction.'-plugin_'.$sPluginFile )
|
457 |
-
],
|
458 |
-
self_admin_url( 'plugins.php' )
|
459 |
-
);
|
460 |
-
}
|
461 |
-
|
462 |
-
/**
|
463 |
-
* @param string $sFile
|
464 |
-
* @return bool
|
465 |
-
*/
|
466 |
-
public function isActive( $sFile ) {
|
467 |
-
return ( $this->isInstalled( $sFile ) && is_plugin_active( $sFile ) );
|
468 |
-
}
|
469 |
-
|
470 |
-
/**
|
471 |
-
* @param string $sFile The full plugin file.
|
472 |
-
* @return bool
|
473 |
-
*/
|
474 |
-
public function isInstalled( $sFile ) {
|
475 |
-
return in_array( $sFile, $this->getInstalledBaseFiles() );
|
476 |
-
}
|
477 |
-
|
478 |
-
/**
|
479 |
-
* @param string $sFile
|
480 |
-
* @return boolean
|
481 |
-
*/
|
482 |
-
public function isUpdateAvailable( $sFile ) {
|
483 |
-
return !is_null( $this->getUpdateInfo( $sFile ) );
|
484 |
-
}
|
485 |
-
|
486 |
-
/**
|
487 |
-
* @param string $sBaseName
|
488 |
-
* @return bool
|
489 |
-
*/
|
490 |
-
public function isWpOrg( $sBaseName ) {
|
491 |
-
$oPluginInfo = $this->getExtendedData( $sBaseName );
|
492 |
-
return isset( $oPluginInfo->id ) ? strpos( $oPluginInfo->id, 'w.org/' ) === 0 : false;
|
493 |
-
}
|
494 |
-
|
495 |
-
/**
|
496 |
-
* @param string $sFile
|
497 |
-
* @param int $nDesiredPosition
|
498 |
-
*/
|
499 |
-
public function setActivePluginLoadPosition( $sFile, $nDesiredPosition = 0 ) {
|
500 |
-
$oWp = $this->loadWp();
|
501 |
-
|
502 |
-
$aActive = $this->loadDP()
|
503 |
-
->setArrayValueToPosition(
|
504 |
-
$oWp->getOption( 'active_plugins' ),
|
505 |
-
$sFile,
|
506 |
-
$nDesiredPosition
|
507 |
-
);
|
508 |
-
$oWp->updateOption( 'active_plugins', $aActive );
|
509 |
-
|
510 |
-
if ( $oWp->isMultisite() ) {
|
511 |
-
$aActive = $this->loadDP()
|
512 |
-
->setArrayValueToPosition( $oWp->getOption( 'active_sitewide_plugins' ), $sFile, $nDesiredPosition );
|
513 |
-
$oWp->updateOption( 'active_sitewide_plugins', $aActive );
|
514 |
-
}
|
515 |
-
}
|
516 |
-
|
517 |
-
/**
|
518 |
-
* @param string $sFile
|
519 |
-
*/
|
520 |
-
public function setActivePluginLoadFirst( $sFile ) {
|
521 |
-
$this->setActivePluginLoadPosition( $sFile, 0 );
|
522 |
-
}
|
523 |
-
|
524 |
-
/**
|
525 |
-
* @param string $sFile
|
526 |
-
*/
|
527 |
-
public function setActivePluginLoadLast( $sFile ) {
|
528 |
-
$this->setActivePluginLoadPosition( $sFile, 1000 );
|
529 |
-
}
|
530 |
-
|
531 |
-
/**
|
532 |
-
* @param string $sPluginFile
|
533 |
-
* @return string
|
534 |
-
* @deprecated
|
535 |
-
*/
|
536 |
-
public function getLinkPluginUpgrade( $sPluginFile ) {
|
537 |
-
return $this->getUrl_Upgrade( $sPluginFile );
|
538 |
-
}
|
539 |
-
|
540 |
-
/**
|
541 |
-
* @return array
|
542 |
-
* @deprecated
|
543 |
-
*/
|
544 |
-
public function getInstalledPluginFiles() {
|
545 |
-
return $this->getInstalledBaseFiles();
|
546 |
-
}
|
547 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-wpfunctions-themes.php
DELETED
@@ -1,365 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class ICWP_WPSF_WpFunctions_Themes extends ICWP_WPSF_Foundation {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var ICWP_WPSF_WpFunctions_Themes
|
7 |
-
*/
|
8 |
-
protected static $oInstance = null;
|
9 |
-
|
10 |
-
private function __construct() {
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @return ICWP_WPSF_WpFunctions_Themes
|
15 |
-
*/
|
16 |
-
public static function GetInstance() {
|
17 |
-
if ( is_null( self::$oInstance ) ) {
|
18 |
-
self::$oInstance = new self();
|
19 |
-
}
|
20 |
-
return self::$oInstance;
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @param string $sThemeStylesheet
|
25 |
-
* @return bool
|
26 |
-
*/
|
27 |
-
public function activate( $sThemeStylesheet ) {
|
28 |
-
if ( empty( $sThemeStylesheet ) ) {
|
29 |
-
return false;
|
30 |
-
}
|
31 |
-
|
32 |
-
$oTheme = $this->getTheme( $sThemeStylesheet );
|
33 |
-
if ( !$oTheme->exists() ) {
|
34 |
-
return false;
|
35 |
-
}
|
36 |
-
|
37 |
-
switch_theme( $oTheme->get_stylesheet() );
|
38 |
-
|
39 |
-
// Now test currently active theme
|
40 |
-
$oCurrentTheme = $this->getCurrent();
|
41 |
-
|
42 |
-
return ( !is_null( $oCurrentTheme ) && ( $sThemeStylesheet == $oCurrentTheme->get_stylesheet() ) );
|
43 |
-
}
|
44 |
-
|
45 |
-
/**
|
46 |
-
* @param string $sStylesheet
|
47 |
-
* @return bool|WP_Error
|
48 |
-
*/
|
49 |
-
public function delete( $sStylesheet ) {
|
50 |
-
if ( empty( $sStylesheet ) ) {
|
51 |
-
return false;
|
52 |
-
}
|
53 |
-
if ( !function_exists( 'delete_theme' ) ) {
|
54 |
-
require_once( ABSPATH.'wp-admin/includes/theme.php' );
|
55 |
-
}
|
56 |
-
return function_exists( 'delete_theme' ) ? delete_theme( $sStylesheet ) : false;
|
57 |
-
}
|
58 |
-
|
59 |
-
/**
|
60 |
-
* @param $sSlug
|
61 |
-
* @return array|bool
|
62 |
-
*/
|
63 |
-
public function installFromWpOrg( $sSlug ) {
|
64 |
-
include_once( ABSPATH.'wp-admin/includes/plugin-install.php' );
|
65 |
-
|
66 |
-
$oApi = $this->getExtendedData( $sSlug );
|
67 |
-
|
68 |
-
if ( !is_wp_error( $oApi ) ) {
|
69 |
-
return $this->install( $oApi->download_link, true, true );
|
70 |
-
}
|
71 |
-
return false;
|
72 |
-
}
|
73 |
-
|
74 |
-
/**
|
75 |
-
* @param string $sUrlToInstall
|
76 |
-
* @param bool $bOverwrite
|
77 |
-
* @param bool $bMaintenanceMode
|
78 |
-
* @return array
|
79 |
-
*/
|
80 |
-
public function install( $sUrlToInstall, $bOverwrite = true, $bMaintenanceMode = false ) {
|
81 |
-
$this->loadWpUpgrades();
|
82 |
-
|
83 |
-
$aResult = [
|
84 |
-
'successful' => true,
|
85 |
-
'plugin_info' => '',
|
86 |
-
'errors' => []
|
87 |
-
];
|
88 |
-
|
89 |
-
$oUpgraderSkin = new ICWP_Upgrader_Skin();
|
90 |
-
$oUpgrader = new ICWP_Theme_Upgrader( $oUpgraderSkin );
|
91 |
-
$oUpgrader->setOverwriteMode( $bOverwrite );
|
92 |
-
if ( $bMaintenanceMode ) {
|
93 |
-
$oUpgrader->maintenance_mode( true );
|
94 |
-
}
|
95 |
-
|
96 |
-
ob_start();
|
97 |
-
$sInstallResult = $oUpgrader->install( $sUrlToInstall );
|
98 |
-
ob_end_clean();
|
99 |
-
|
100 |
-
if ( $bMaintenanceMode ) {
|
101 |
-
$oUpgrader->maintenance_mode( false );
|
102 |
-
}
|
103 |
-
|
104 |
-
if ( is_wp_error( $oUpgraderSkin->m_aErrors[ 0 ] ) ) {
|
105 |
-
$aResult[ 'successful' ] = false;
|
106 |
-
$aResult[ 'errors' ] = $oUpgraderSkin->m_aErrors[ 0 ]->get_error_messages();
|
107 |
-
}
|
108 |
-
else {
|
109 |
-
$aResult[ 'theme_info' ] = $oUpgrader->theme_info();
|
110 |
-
}
|
111 |
-
|
112 |
-
$aResult[ 'feedback' ] = $oUpgraderSkin->getFeedback();
|
113 |
-
return $aResult;
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* @param string $sSlug
|
118 |
-
* @param bool $bUseBackup
|
119 |
-
* @return bool
|
120 |
-
*/
|
121 |
-
public function reinstall( $sSlug, $bUseBackup = false ) {
|
122 |
-
$bSuccess = false;
|
123 |
-
|
124 |
-
if ( $this->isInstalled( $sSlug ) ) {
|
125 |
-
$oFS = $this->loadFS();
|
126 |
-
|
127 |
-
$oTheme = $this->getTheme( $sSlug );
|
128 |
-
|
129 |
-
$sDir = $oTheme->get_stylesheet_directory();
|
130 |
-
$sBackupDir = dirname( $sDir ).'/../../'.$sSlug.'bak'.time();
|
131 |
-
if ( $bUseBackup ) {
|
132 |
-
rename( $sDir, $sBackupDir );
|
133 |
-
}
|
134 |
-
|
135 |
-
$aResult = $this->installFromWpOrg( $sSlug );
|
136 |
-
$bSuccess = $aResult[ 'successful' ];
|
137 |
-
if ( $bSuccess ) {
|
138 |
-
wp_update_themes(); //refreshes our update information
|
139 |
-
if ( $bUseBackup ) {
|
140 |
-
$oFS->deleteDir( $sBackupDir );
|
141 |
-
}
|
142 |
-
}
|
143 |
-
else {
|
144 |
-
if ( $bUseBackup ) {
|
145 |
-
$oFS->deleteDir( $sDir );
|
146 |
-
rename( $sBackupDir, $sDir );
|
147 |
-
}
|
148 |
-
}
|
149 |
-
}
|
150 |
-
return $bSuccess;
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* @param string $sFile
|
155 |
-
* @return array
|
156 |
-
*/
|
157 |
-
public function update( $sFile ) {
|
158 |
-
$this->loadWpUpgrades();
|
159 |
-
|
160 |
-
$aResult = [
|
161 |
-
'successful' => 1,
|
162 |
-
'errors' => []
|
163 |
-
];
|
164 |
-
|
165 |
-
$oUpgraderSkin = new ICWP_Bulk_Theme_Upgrader_Skin();
|
166 |
-
$oUpgrader = new Theme_Upgrader( $oUpgraderSkin );
|
167 |
-
ob_start();
|
168 |
-
$oUpgrader->bulk_upgrade( [ $sFile ] );
|
169 |
-
ob_end_clean();
|
170 |
-
|
171 |
-
if ( isset( $oUpgraderSkin->m_aErrors[ 0 ] ) ) {
|
172 |
-
if ( is_wp_error( $oUpgraderSkin->m_aErrors[ 0 ] ) ) {
|
173 |
-
$aResult[ 'successful' ] = 0;
|
174 |
-
$aResult[ 'errors' ] = $oUpgraderSkin->m_aErrors[ 0 ]->get_error_messages();
|
175 |
-
}
|
176 |
-
}
|
177 |
-
$aResult[ 'feedback' ] = $oUpgraderSkin->getFeedback();
|
178 |
-
return $aResult;
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* @return string|WP_Theme
|
183 |
-
*/
|
184 |
-
public function getCurrentThemeName() {
|
185 |
-
return $this->loadWp()->getWordpressIsAtLeastVersion( '3.4.0' ) ? $this->getCurrent()
|
186 |
-
->get( 'Name' ) : get_current_theme();
|
187 |
-
}
|
188 |
-
|
189 |
-
/**
|
190 |
-
* @return null|WP_Theme
|
191 |
-
*/
|
192 |
-
public function getCurrent() {
|
193 |
-
return $this->getTheme();
|
194 |
-
}
|
195 |
-
|
196 |
-
/**
|
197 |
-
* @param string $sStylesheet
|
198 |
-
* @return bool
|
199 |
-
*/
|
200 |
-
public function getExists( $sStylesheet ) {
|
201 |
-
$oTheme = $this->getTheme( $sStylesheet );
|
202 |
-
return ( !is_null( $oTheme ) && ( $oTheme instanceof WP_Theme ) && $oTheme->exists() );
|
203 |
-
}
|
204 |
-
|
205 |
-
/**
|
206 |
-
* @param string $sStylesheet
|
207 |
-
* @return null|WP_Theme
|
208 |
-
*/
|
209 |
-
public function getTheme( $sStylesheet = null ) {
|
210 |
-
if ( $this->loadWp()->getWordpressIsAtLeastVersion( '3.4.0' ) ) {
|
211 |
-
if ( !function_exists( 'wp_get_theme' ) ) {
|
212 |
-
require_once( ABSPATH.'wp-admin/includes/theme.php' );
|
213 |
-
}
|
214 |
-
return function_exists( 'wp_get_theme' ) ? wp_get_theme( $sStylesheet ) : null;
|
215 |
-
}
|
216 |
-
$aThemes = $this->getThemes();
|
217 |
-
return array_key_exists( $sStylesheet, $aThemes ) ? $aThemes[ $sStylesheet ] : null;
|
218 |
-
}
|
219 |
-
|
220 |
-
/**
|
221 |
-
* Abstracts the WordPress wp_get_themes()
|
222 |
-
* @return array|WP_Theme[]
|
223 |
-
*/
|
224 |
-
public function getThemes() {
|
225 |
-
if ( !function_exists( 'wp_get_themes' ) ) {
|
226 |
-
require_once( ABSPATH.'wp-admin/includes/theme.php' );
|
227 |
-
}
|
228 |
-
return function_exists( 'wp_get_themes' ) ? wp_get_themes() : get_themes();
|
229 |
-
}
|
230 |
-
|
231 |
-
/**
|
232 |
-
* @param string $sSlug
|
233 |
-
* @return array|null
|
234 |
-
*/
|
235 |
-
public function getUpdateInfo( $sSlug ) {
|
236 |
-
$aU = $this->getUpdates();
|
237 |
-
return isset( $aU[ $sSlug ] ) ? $aU[ $sSlug ] : null;
|
238 |
-
}
|
239 |
-
|
240 |
-
/**
|
241 |
-
* @param bool $bForceUpdateCheck
|
242 |
-
* @return array
|
243 |
-
*/
|
244 |
-
public function getUpdates( $bForceUpdateCheck = false ) {
|
245 |
-
if ( $bForceUpdateCheck ) {
|
246 |
-
$this->clearUpdates();
|
247 |
-
$this->checkForUpdates();
|
248 |
-
}
|
249 |
-
$aUpdates = $this->loadWp()->getWordpressUpdates( 'themes' );
|
250 |
-
return is_array( $aUpdates ) ? $aUpdates : [];
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* @return null|WP_Theme
|
255 |
-
*/
|
256 |
-
public function getCurrentParent() {
|
257 |
-
$oTheme = $this->getCurrent();
|
258 |
-
return $this->isActiveThemeAChild() ? $this->getTheme( $oTheme->get_template() ) : null;
|
259 |
-
}
|
260 |
-
|
261 |
-
/**
|
262 |
-
* @param string $sBase
|
263 |
-
* @return object|WP_Error
|
264 |
-
*/
|
265 |
-
public function getExtendedData( $sBase ) {
|
266 |
-
include_once( ABSPATH.'wp-admin/includes/theme.php' );
|
267 |
-
|
268 |
-
$oApi = themes_api( 'theme_information', [
|
269 |
-
'slug' => $sBase,
|
270 |
-
'fields' => [
|
271 |
-
'sections' => false,
|
272 |
-
],
|
273 |
-
] );
|
274 |
-
return $oApi;
|
275 |
-
}
|
276 |
-
|
277 |
-
/**
|
278 |
-
* @param string $sSlug
|
279 |
-
* @param bool $bCheckIsActiveParent
|
280 |
-
* @return bool
|
281 |
-
*/
|
282 |
-
public function isActive( $sSlug, $bCheckIsActiveParent = false ) {
|
283 |
-
return ( $this->isInstalled( $sSlug ) && $this->getCurrent()->get_stylesheet() == $sSlug )
|
284 |
-
|| ( $bCheckIsActiveParent && $this->isActiveParent( $sSlug ) );
|
285 |
-
}
|
286 |
-
|
287 |
-
/**
|
288 |
-
* @return bool
|
289 |
-
*/
|
290 |
-
public function isActiveThemeAChild() {
|
291 |
-
$oTheme = $this->getCurrent();
|
292 |
-
return ( $oTheme->get_stylesheet() != $oTheme->get_template() );
|
293 |
-
}
|
294 |
-
|
295 |
-
/**
|
296 |
-
* @param string $sSlug
|
297 |
-
* @return bool - true if this is the Parent of the currently active theme
|
298 |
-
*/
|
299 |
-
public function isActiveParent( $sSlug ) {
|
300 |
-
return ( $this->isInstalled( $sSlug ) && $this->getCurrent()->get_template() == $sSlug );
|
301 |
-
}
|
302 |
-
|
303 |
-
/**
|
304 |
-
* @param string $sSlug The directory slug.
|
305 |
-
* @return bool
|
306 |
-
*/
|
307 |
-
public function isInstalled( $sSlug ) {
|
308 |
-
return !empty( $sSlug ) && !is_null( $this->getTheme( $sSlug ) );
|
309 |
-
}
|
310 |
-
|
311 |
-
/**
|
312 |
-
* @param string $sSlug
|
313 |
-
* @return boolean
|
314 |
-
*/
|
315 |
-
public function isUpdateAvailable( $sSlug ) {
|
316 |
-
return !is_null( $this->getUpdateInfo( $sSlug ) );
|
317 |
-
}
|
318 |
-
|
319 |
-
/**
|
320 |
-
* @param string $sBaseName
|
321 |
-
* @return bool
|
322 |
-
*/
|
323 |
-
public function isWpOrg( $sBaseName ) {
|
324 |
-
$bIsWpOrg = false;
|
325 |
-
$oInfo = $this->getExtendedData( $sBaseName );
|
326 |
-
if ( !empty( $oInfo ) && !is_wp_error( $oInfo ) && isset( $oInfo->download_link ) ) {
|
327 |
-
$bIsWpOrg = strpos( $oInfo->download_link, 'https://downloads.wordpress.org' ) === 0;
|
328 |
-
}
|
329 |
-
return $bIsWpOrg;
|
330 |
-
}
|
331 |
-
|
332 |
-
/**
|
333 |
-
* @return boolean|null
|
334 |
-
*/
|
335 |
-
protected function checkForUpdates() {
|
336 |
-
|
337 |
-
if ( class_exists( 'WPRC_Installer' ) && method_exists( 'WPRC_Installer', 'wprc_update_themes' ) ) {
|
338 |
-
WPRC_Installer::wprc_update_themes();
|
339 |
-
return true;
|
340 |
-
}
|
341 |
-
else if ( function_exists( 'wp_update_themes' ) ) {
|
342 |
-
return ( wp_update_themes() !== false );
|
343 |
-
}
|
344 |
-
return null;
|
345 |
-
}
|
346 |
-
|
347 |
-
/**
|
348 |
-
*/
|
349 |
-
protected function clearUpdates() {
|
350 |
-
$sKey = 'update_themes';
|
351 |
-
$oResponse = $this->loadWp()->getTransient( $sKey );
|
352 |
-
if ( !is_object( $oResponse ) ) {
|
353 |
-
$oResponse = new stdClass();
|
354 |
-
}
|
355 |
-
$oResponse->last_checked = 0;
|
356 |
-
$this->loadWp()->setTransient( $sKey, $oResponse );
|
357 |
-
}
|
358 |
-
|
359 |
-
/**
|
360 |
-
* @return array
|
361 |
-
*/
|
362 |
-
public function wpmsGetSiteAllowedThemes() {
|
363 |
-
return ( function_exists( 'get_site_allowed_themes' ) ? get_site_allowed_themes() : [] );
|
364 |
-
}
|
365 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-wpfunctions.php
DELETED
@@ -1,936 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var WP_Automatic_Updater
|
7 |
-
*/
|
8 |
-
protected $oWpAutomaticUpdater;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var ICWP_WPSF_WpFunctions
|
12 |
-
*/
|
13 |
-
protected static $oInstance = null;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @return ICWP_WPSF_WpFunctions
|
17 |
-
*/
|
18 |
-
public static function GetInstance() {
|
19 |
-
if ( is_null( self::$oInstance ) ) {
|
20 |
-
self::$oInstance = new self();
|
21 |
-
}
|
22 |
-
return self::$oInstance;
|
23 |
-
}
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @var string
|
27 |
-
*/
|
28 |
-
protected $sWpVersion;
|
29 |
-
|
30 |
-
public function __construct() {
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* @return null|string
|
35 |
-
*/
|
36 |
-
public function findWpLoad() {
|
37 |
-
return $this->findWpCoreFile( 'wp-load.php' );
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* @param $sFilename
|
42 |
-
* @return null|string
|
43 |
-
*/
|
44 |
-
public function findWpCoreFile( $sFilename ) {
|
45 |
-
$sLoaderPath = __DIR__;
|
46 |
-
$nLimiter = 0;
|
47 |
-
$nMaxLimit = count( explode( DIRECTORY_SEPARATOR, trim( $sLoaderPath, DIRECTORY_SEPARATOR ) ) );
|
48 |
-
$bFound = false;
|
49 |
-
|
50 |
-
do {
|
51 |
-
if ( @is_file( $sLoaderPath.DIRECTORY_SEPARATOR.$sFilename ) ) {
|
52 |
-
$bFound = true;
|
53 |
-
break;
|
54 |
-
}
|
55 |
-
$sLoaderPath = realpath( $sLoaderPath.DIRECTORY_SEPARATOR.'..' );
|
56 |
-
$nLimiter++;
|
57 |
-
} while ( $nLimiter < $nMaxLimit );
|
58 |
-
|
59 |
-
return $bFound ? $sLoaderPath.DIRECTORY_SEPARATOR.$sFilename : null;
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* @param string $sRedirect
|
64 |
-
* @return bool
|
65 |
-
*/
|
66 |
-
public function doForceRunAutomaticUpdates( $sRedirect = '' ) {
|
67 |
-
|
68 |
-
$lock_name = 'auto_updater.lock'; //ref: /wp-admin/includes/class-wp-upgrader.php
|
69 |
-
delete_option( $lock_name );
|
70 |
-
if ( !defined( 'DOING_CRON' ) ) {
|
71 |
-
define( 'DOING_CRON', true ); // this prevents WP from disabling plugins pre-upgrade
|
72 |
-
}
|
73 |
-
|
74 |
-
// does the actual updating
|
75 |
-
wp_maybe_auto_update();
|
76 |
-
|
77 |
-
if ( !empty( $sRedirect ) ) {
|
78 |
-
$this->doRedirect( network_admin_url( $sRedirect ) );
|
79 |
-
}
|
80 |
-
return true;
|
81 |
-
}
|
82 |
-
|
83 |
-
/**
|
84 |
-
* @return bool
|
85 |
-
*/
|
86 |
-
public function isRunningAutomaticUpdates() {
|
87 |
-
return ( get_option( 'auto_updater.lock' ) ? true : false );
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* The full plugin file to be upgraded.
|
92 |
-
* @param string $sPluginFile
|
93 |
-
* @return boolean
|
94 |
-
*/
|
95 |
-
public function doPluginUpgrade( $sPluginFile ) {
|
96 |
-
$oWpPlugins = $this->loadWpPlugins();
|
97 |
-
if ( !$oWpPlugins->isUpdateAvailable( $sPluginFile )
|
98 |
-
|| ( isset( $GLOBALS[ 'pagenow' ] ) && $GLOBALS[ 'pagenow' ] == 'update.php' ) ) {
|
99 |
-
return true;
|
100 |
-
}
|
101 |
-
wp_redirect( $oWpPlugins->getUrl_Upgrade( $sPluginFile ) );
|
102 |
-
exit();
|
103 |
-
}
|
104 |
-
|
105 |
-
/**
|
106 |
-
* Clears any WordPress caches
|
107 |
-
*/
|
108 |
-
public function doBustCache() {
|
109 |
-
global $_wp_using_ext_object_cache, $wp_object_cache;
|
110 |
-
$_wp_using_ext_object_cache = false;
|
111 |
-
if ( !empty( $wp_object_cache ) ) {
|
112 |
-
@$wp_object_cache->flush();
|
113 |
-
}
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* @return bool
|
118 |
-
*/
|
119 |
-
public function isPermalinksEnabled() {
|
120 |
-
return ( $this->getOption( 'permalink_structure' ) ? true : false );
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* @return array
|
125 |
-
* @see wp_redirect_admin_locations()
|
126 |
-
*/
|
127 |
-
public function getAutoRedirectLocations() {
|
128 |
-
return [ 'wp-admin', 'dashboard', 'admin', 'login', 'wp-login.php' ];
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
* @return array|false
|
133 |
-
*/
|
134 |
-
public function getCoreUpdates() {
|
135 |
-
include_once( ABSPATH.'wp-admin/includes/update.php' );
|
136 |
-
return get_core_updates();
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* @return string
|
141 |
-
*/
|
142 |
-
public function getDirUploads() {
|
143 |
-
$aDirParts = wp_get_upload_dir();
|
144 |
-
$bHasUploads = is_array( $aDirParts ) && !empty( $aDirParts[ 'basedir' ] )
|
145 |
-
&& $this->loadFS()->exists( $aDirParts[ 'basedir' ] );
|
146 |
-
return $bHasUploads ? $aDirParts[ 'basedir' ] : '';
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* @param string $sPath
|
151 |
-
* @return string
|
152 |
-
*/
|
153 |
-
public function getUrl_WpAdmin( $sPath = '' ) {
|
154 |
-
return get_admin_url( null, $sPath );
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* @param string $sPath
|
159 |
-
* @return string
|
160 |
-
*/
|
161 |
-
public function getHomeUrl( $sPath = '' ) {
|
162 |
-
$sUrl = home_url( $sPath );
|
163 |
-
if ( empty( $sUrl ) ) {
|
164 |
-
remove_all_filters( 'home_url' );
|
165 |
-
$sUrl = home_url( $sPath );
|
166 |
-
}
|
167 |
-
return $sUrl;
|
168 |
-
}
|
169 |
-
|
170 |
-
/**
|
171 |
-
* @param bool $bRemoveSchema
|
172 |
-
* @return string
|
173 |
-
*/
|
174 |
-
public function getWpUrl( $bRemoveSchema = false ) {
|
175 |
-
$sUrl = network_site_url();
|
176 |
-
if ( empty( $sUrl ) ) {
|
177 |
-
remove_all_filters( 'site_url' );
|
178 |
-
remove_all_filters( 'network_site_url' );
|
179 |
-
$sUrl = network_site_url();
|
180 |
-
}
|
181 |
-
if ( $bRemoveSchema ) {
|
182 |
-
$sUrl = preg_replace( '#^((http|https):)?\/\/#i', '', $sUrl );
|
183 |
-
}
|
184 |
-
return $sUrl;
|
185 |
-
}
|
186 |
-
|
187 |
-
/**
|
188 |
-
* @param string $sSeparator
|
189 |
-
* @return string
|
190 |
-
*/
|
191 |
-
public function getLocale( $sSeparator = '_' ) {
|
192 |
-
return str_replace( '_', $sSeparator, get_locale() );
|
193 |
-
}
|
194 |
-
|
195 |
-
/**
|
196 |
-
* @return string
|
197 |
-
*/
|
198 |
-
public function getLocaleForChecksums() {
|
199 |
-
global $wp_local_package;
|
200 |
-
return empty( $wp_local_package ) ? 'en_US' : $wp_local_package;
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* @param stdClass|string $mItem
|
205 |
-
* @param string $sContext from plugin|theme
|
206 |
-
* @return string
|
207 |
-
*/
|
208 |
-
public function getFileFromAutomaticUpdateItem( $mItem, $sContext = 'plugin' ) {
|
209 |
-
if ( is_object( $mItem ) && isset( $mItem->{$sContext} ) ) { // WP 3.8.2+
|
210 |
-
$mItem = $mItem->{$sContext};
|
211 |
-
}
|
212 |
-
else if ( !is_string( $mItem ) ) { // WP pre-3.8.2
|
213 |
-
$mItem = '';
|
214 |
-
}
|
215 |
-
return $mItem;
|
216 |
-
}
|
217 |
-
|
218 |
-
/**
|
219 |
-
* @return array
|
220 |
-
*/
|
221 |
-
public function getThemes() {
|
222 |
-
if ( !function_exists( 'wp_get_themes' ) ) {
|
223 |
-
require_once( ABSPATH.'wp-admin/includes/theme.php' );
|
224 |
-
}
|
225 |
-
return function_exists( 'wp_get_themes' ) ? wp_get_themes() : [];
|
226 |
-
}
|
227 |
-
|
228 |
-
/**
|
229 |
-
* @param string $sType - plugins, themes
|
230 |
-
* @return array
|
231 |
-
*/
|
232 |
-
public function getWordpressUpdates( $sType = 'plugins' ) {
|
233 |
-
$oCurrent = $this->getTransient( 'update_'.$sType );
|
234 |
-
return ( isset( $oCurrent->response ) && is_array( $oCurrent->response ) ) ? $oCurrent->response : [];
|
235 |
-
}
|
236 |
-
|
237 |
-
/**
|
238 |
-
* @return array
|
239 |
-
*/
|
240 |
-
public function getWordpressUpdates_Themes() {
|
241 |
-
return $this->getWordpressUpdates( 'themes' );
|
242 |
-
}
|
243 |
-
|
244 |
-
/**
|
245 |
-
* @param string $sKey
|
246 |
-
* @return mixed
|
247 |
-
*/
|
248 |
-
public function getTransient( $sKey ) {
|
249 |
-
// TODO: Handle multisite
|
250 |
-
|
251 |
-
if ( function_exists( 'get_site_transient' ) ) {
|
252 |
-
$mResult = get_site_transient( $sKey );
|
253 |
-
if ( empty( $mResult ) ) {
|
254 |
-
remove_all_filters( 'pre_site_transient_'.$sKey );
|
255 |
-
$mResult = get_site_transient( $sKey );
|
256 |
-
}
|
257 |
-
}
|
258 |
-
else if ( version_compare( $this->getVersion(), '2.7.9', '<=' ) ) {
|
259 |
-
$mResult = get_option( $sKey );
|
260 |
-
}
|
261 |
-
else if ( version_compare( $this->getVersion(), '2.9.9', '<=' ) ) {
|
262 |
-
$mResult = apply_filters( 'transient_'.$sKey, get_option( '_transient_'.$sKey ) );
|
263 |
-
}
|
264 |
-
else {
|
265 |
-
$mResult = apply_filters( 'site_transient_'.$sKey, get_option( '_site_transient_'.$sKey ) );
|
266 |
-
}
|
267 |
-
return $mResult;
|
268 |
-
}
|
269 |
-
|
270 |
-
/**
|
271 |
-
* @param string $sKey
|
272 |
-
* @param mixed $mValue
|
273 |
-
* @param int $nExpire
|
274 |
-
* @return bool
|
275 |
-
*/
|
276 |
-
public function setTransient( $sKey, $mValue, $nExpire = 0 ) {
|
277 |
-
return set_site_transient( $sKey, $mValue, $nExpire );
|
278 |
-
}
|
279 |
-
|
280 |
-
/**
|
281 |
-
* @param $sKey
|
282 |
-
* @return bool
|
283 |
-
*/
|
284 |
-
public function deleteTransient( $sKey ) {
|
285 |
-
|
286 |
-
if ( version_compare( $this->getVersion(), '2.7.9', '<=' ) ) {
|
287 |
-
$bResult = delete_option( $sKey );
|
288 |
-
}
|
289 |
-
else if ( function_exists( 'delete_site_transient' ) ) {
|
290 |
-
$bResult = delete_site_transient( $sKey );
|
291 |
-
}
|
292 |
-
else if ( version_compare( $this->getVersion(), '2.9.9', '<=' ) ) {
|
293 |
-
$bResult = delete_option( '_transient_'.$sKey );
|
294 |
-
}
|
295 |
-
else {
|
296 |
-
$bResult = delete_option( '_site_transient_'.$sKey );
|
297 |
-
}
|
298 |
-
return $bResult;
|
299 |
-
}
|
300 |
-
|
301 |
-
/**
|
302 |
-
* @return string
|
303 |
-
*/
|
304 |
-
public function getVersion() {
|
305 |
-
|
306 |
-
if ( empty( $this->sWpVersion ) ) {
|
307 |
-
$sVersionFile = ABSPATH.WPINC.'/version.php';
|
308 |
-
$sVersionContents = file_get_contents( $sVersionFile );
|
309 |
-
|
310 |
-
if ( preg_match( '/wp_version\s=\s\'([^(\'|")]+)\'/i', $sVersionContents, $aMatches ) ) {
|
311 |
-
$this->sWpVersion = $aMatches[ 1 ];
|
312 |
-
}
|
313 |
-
else {
|
314 |
-
global $wp_version;
|
315 |
-
$this->sWpVersion = $wp_version;
|
316 |
-
}
|
317 |
-
}
|
318 |
-
return $this->sWpVersion;
|
319 |
-
}
|
320 |
-
|
321 |
-
/**
|
322 |
-
* @param string $sVersionToMeet
|
323 |
-
* @return boolean
|
324 |
-
*/
|
325 |
-
public function getWordpressIsAtLeastVersion( $sVersionToMeet ) {
|
326 |
-
return version_compare( $this->getVersion(), $sVersionToMeet, '>=' );
|
327 |
-
}
|
328 |
-
|
329 |
-
/**
|
330 |
-
* @param string $sPluginBaseFilename
|
331 |
-
* @return boolean
|
332 |
-
*/
|
333 |
-
public function isPluginAutomaticallyUpdated( $sPluginBaseFilename ) {
|
334 |
-
$oUpdater = $this->getWpAutomaticUpdater();
|
335 |
-
if ( !$oUpdater ) {
|
336 |
-
return false;
|
337 |
-
}
|
338 |
-
|
339 |
-
// This is due to a change in the filter introduced in version 3.8.2
|
340 |
-
if ( $this->getWordpressIsAtLeastVersion( '3.8.2' ) ) {
|
341 |
-
$mPluginItem = new stdClass();
|
342 |
-
$mPluginItem->plugin = $sPluginBaseFilename;
|
343 |
-
}
|
344 |
-
else {
|
345 |
-
$mPluginItem = $sPluginBaseFilename;
|
346 |
-
}
|
347 |
-
|
348 |
-
return $oUpdater->should_update( 'plugin', $mPluginItem, WP_PLUGIN_DIR );
|
349 |
-
}
|
350 |
-
|
351 |
-
/**
|
352 |
-
* @return bool
|
353 |
-
*/
|
354 |
-
public function canCoreUpdateAutomatically() {
|
355 |
-
global $required_php_version, $required_mysql_version;
|
356 |
-
$future_minor_update = (object)[
|
357 |
-
'current' => $this->getVersion().'.1.next.minor',
|
358 |
-
'version' => $this->getVersion().'.1.next.minor',
|
359 |
-
'php_version' => $required_php_version,
|
360 |
-
'mysql_version' => $required_mysql_version,
|
361 |
-
];
|
362 |
-
return $this->getWpAutomaticUpdater()
|
363 |
-
->should_update( 'core', $future_minor_update, ABSPATH );
|
364 |
-
}
|
365 |
-
|
366 |
-
/**
|
367 |
-
* See: /wp-admin/update-core.php core_upgrade_preamble()
|
368 |
-
* @return bool
|
369 |
-
*/
|
370 |
-
public function hasCoreUpdate() {
|
371 |
-
$aUpdates = $this->getCoreUpdates();
|
372 |
-
return ( isset( $aUpdates[ 0 ]->response ) && 'latest' != $aUpdates[ 0 ]->response );
|
373 |
-
}
|
374 |
-
|
375 |
-
public function redirectHere() {
|
376 |
-
$this->doRedirect( $this->loadRequest()->getUri() );
|
377 |
-
}
|
378 |
-
|
379 |
-
/**
|
380 |
-
* @param array $aQueryParams
|
381 |
-
*/
|
382 |
-
public function redirectToLogin( $aQueryParams = [] ) {
|
383 |
-
$this->doRedirect( wp_login_url(), $aQueryParams );
|
384 |
-
}
|
385 |
-
|
386 |
-
/**
|
387 |
-
* @param array $aQueryParams
|
388 |
-
*/
|
389 |
-
public function redirectToAdmin( $aQueryParams = [] ) {
|
390 |
-
$this->doRedirect( is_multisite() ? get_admin_url() : admin_url(), $aQueryParams );
|
391 |
-
}
|
392 |
-
|
393 |
-
/**
|
394 |
-
* @param array $aQueryParams
|
395 |
-
*/
|
396 |
-
public function redirectToHome( $aQueryParams = [] ) {
|
397 |
-
$this->doRedirect( home_url(), $aQueryParams );
|
398 |
-
}
|
399 |
-
|
400 |
-
/**
|
401 |
-
* @param string $sUrl
|
402 |
-
* @param array $aQueryParams
|
403 |
-
* @param bool $bSafe
|
404 |
-
* @param bool $bProtectAgainstInfiniteLoops - if false, ignores the redirect loop protection
|
405 |
-
*/
|
406 |
-
public function doRedirect( $sUrl, $aQueryParams = [], $bSafe = true, $bProtectAgainstInfiniteLoops = true ) {
|
407 |
-
$sUrl = empty( $aQueryParams ) ? $sUrl : add_query_arg( $aQueryParams, $sUrl );
|
408 |
-
|
409 |
-
$oReq = $this->loadRequest();
|
410 |
-
// we prevent any repetitive redirect loops
|
411 |
-
if ( $bProtectAgainstInfiniteLoops ) {
|
412 |
-
if ( $oReq->cookie( 'icwp-isredirect' ) == 'yes' ) {
|
413 |
-
return;
|
414 |
-
}
|
415 |
-
else {
|
416 |
-
$oReq->setCookie( 'icwp-isredirect', 'yes', 5 );
|
417 |
-
}
|
418 |
-
}
|
419 |
-
|
420 |
-
// based on: https://make.wordpress.org/plugins/2015/04/20/fixing-add_query_arg-and-remove_query_arg-usage/
|
421 |
-
// we now escape the URL to be absolutely sure since we can't guarantee the URL coming through there
|
422 |
-
$sUrl = esc_url_raw( $sUrl );
|
423 |
-
$bSafe ? wp_redirect( $sUrl ) : wp_redirect( $sUrl );
|
424 |
-
exit();
|
425 |
-
}
|
426 |
-
|
427 |
-
/**
|
428 |
-
* @return string
|
429 |
-
*/
|
430 |
-
public function getCurrentPage() {
|
431 |
-
global $pagenow;
|
432 |
-
return $pagenow;
|
433 |
-
}
|
434 |
-
|
435 |
-
/**
|
436 |
-
* @return WP_Post
|
437 |
-
*/
|
438 |
-
public function getCurrentPost() {
|
439 |
-
global $post;
|
440 |
-
return $post;
|
441 |
-
}
|
442 |
-
|
443 |
-
/**
|
444 |
-
* @return int
|
445 |
-
*/
|
446 |
-
public function getCurrentPostId() {
|
447 |
-
$oPost = $this->getCurrentPost();
|
448 |
-
return empty( $oPost->ID ) ? -1 : $oPost->ID;
|
449 |
-
}
|
450 |
-
|
451 |
-
/**
|
452 |
-
* @param $nPostId
|
453 |
-
* @return false|WP_Post
|
454 |
-
*/
|
455 |
-
public function getPostById( $nPostId ) {
|
456 |
-
return WP_Post::get_instance( $nPostId );
|
457 |
-
}
|
458 |
-
|
459 |
-
/**
|
460 |
-
* @param string $sPageSlug
|
461 |
-
* @param bool $bWpmsOnly
|
462 |
-
* @return string
|
463 |
-
*/
|
464 |
-
public function getUrl_AdminPage( $sPageSlug, $bWpmsOnly = false ) {
|
465 |
-
$sUrl = sprintf( 'admin.php?page=%s', $sPageSlug );
|
466 |
-
return $bWpmsOnly ? network_admin_url( $sUrl ) : admin_url( $sUrl );
|
467 |
-
}
|
468 |
-
|
469 |
-
/**
|
470 |
-
* @param string $sPath
|
471 |
-
* @param bool $bWpmsOnly
|
472 |
-
* @return string
|
473 |
-
*/
|
474 |
-
public function getAdminUrl( $sPath = '', $bWpmsOnly = false ) {
|
475 |
-
return $bWpmsOnly ? network_admin_url( $sPath ) : admin_url( $sPath );
|
476 |
-
}
|
477 |
-
|
478 |
-
/**
|
479 |
-
* @param bool $bWpmsOnly
|
480 |
-
* @return string
|
481 |
-
*/
|
482 |
-
public function getAdminUrl_Plugins( $bWpmsOnly = false ) {
|
483 |
-
return $this->getAdminUrl( 'plugins.php', $bWpmsOnly );
|
484 |
-
}
|
485 |
-
|
486 |
-
/**
|
487 |
-
* @param bool $bWpmsOnly
|
488 |
-
* @return string
|
489 |
-
*/
|
490 |
-
public function getAdminUrl_Themes( $bWpmsOnly = false ) {
|
491 |
-
return $this->getAdminUrl( 'themes.php', $bWpmsOnly );
|
492 |
-
}
|
493 |
-
|
494 |
-
/**
|
495 |
-
* @param bool $bWpmsOnly
|
496 |
-
* @return string
|
497 |
-
*/
|
498 |
-
public function getAdminUrl_Updates( $bWpmsOnly = false ) {
|
499 |
-
return $this->getAdminUrl( 'update-core.php', $bWpmsOnly );
|
500 |
-
}
|
501 |
-
|
502 |
-
/**
|
503 |
-
* @return string
|
504 |
-
*/
|
505 |
-
public function getUrl_CurrentAdminPage() {
|
506 |
-
|
507 |
-
$sPage = $this->getCurrentPage();
|
508 |
-
$sUrl = self_admin_url( $sPage );
|
509 |
-
|
510 |
-
//special case for plugin admin pages.
|
511 |
-
if ( $sPage == 'admin.php' ) {
|
512 |
-
$sSubPage = $this->loadRequest()->query( 'page' );
|
513 |
-
if ( !empty( $sSubPage ) ) {
|
514 |
-
$aQueryArgs = [
|
515 |
-
'page' => $sSubPage,
|
516 |
-
];
|
517 |
-
$sUrl = add_query_arg( $aQueryArgs, $sUrl );
|
518 |
-
}
|
519 |
-
}
|
520 |
-
return $sUrl;
|
521 |
-
}
|
522 |
-
|
523 |
-
/**
|
524 |
-
* @param string
|
525 |
-
* @return string
|
526 |
-
*/
|
527 |
-
public function isCurrentPage( $sPage ) {
|
528 |
-
return $sPage == $this->getCurrentPage();
|
529 |
-
}
|
530 |
-
|
531 |
-
/**
|
532 |
-
* @param string
|
533 |
-
* @return string
|
534 |
-
*/
|
535 |
-
public function isPage_Updates() {
|
536 |
-
return $this->isCurrentPage( 'update.php' );
|
537 |
-
}
|
538 |
-
|
539 |
-
/**
|
540 |
-
* @param string $sUrlPath
|
541 |
-
* @return bool
|
542 |
-
*/
|
543 |
-
public function isLoginUrl( $sUrlPath ) {
|
544 |
-
$sLoginUrlPath = @parse_url( wp_login_url(), PHP_URL_PATH );
|
545 |
-
return ( !empty( $sUrlPath ) && ( rtrim( $sUrlPath, '/' ) == rtrim( $sLoginUrlPath, '/' ) ) );
|
546 |
-
}
|
547 |
-
|
548 |
-
/**
|
549 |
-
* @return bool
|
550 |
-
*/
|
551 |
-
public function isRequestLoginUrl() {
|
552 |
-
return $this->isLoginUrl( $this->loadRequest()->getPath() );
|
553 |
-
}
|
554 |
-
|
555 |
-
/**
|
556 |
-
* @return bool
|
557 |
-
*/
|
558 |
-
public function isRequestUserLogin() {
|
559 |
-
$oReq = $this->loadRequest();
|
560 |
-
return $this->isRequestLoginUrl() && $oReq->isMethodPost()
|
561 |
-
&& !is_null( $oReq->post( 'log' ) ) && !is_null( $oReq->post( 'pwd' ) );
|
562 |
-
}
|
563 |
-
|
564 |
-
/**
|
565 |
-
* @return bool
|
566 |
-
*/
|
567 |
-
public function isRequestUserRegister() {
|
568 |
-
$oReq = $this->loadRequest();
|
569 |
-
return $oReq->isMethodPost() && !is_null( $oReq->post( 'user_login' ) )
|
570 |
-
&& !is_null( $oReq->post( 'user_email' ) ) && $this->isRequestLoginUrl();
|
571 |
-
}
|
572 |
-
|
573 |
-
/**
|
574 |
-
* @return bool
|
575 |
-
*/
|
576 |
-
public function isRequestUserResetPasswordStart() {
|
577 |
-
$oReq = $this->loadRequest();
|
578 |
-
return $this->isRequestLoginUrl() && $oReq->isMethodPost() && !is_null( $oReq->post( 'user_login' ) );
|
579 |
-
}
|
580 |
-
|
581 |
-
/**
|
582 |
-
* @return int
|
583 |
-
*/
|
584 |
-
public function getAuthCookieExpiration() {
|
585 |
-
return (int)apply_filters( 'auth_cookie_expiration', 14*DAY_IN_SECONDS, 0, false );
|
586 |
-
}
|
587 |
-
|
588 |
-
/**
|
589 |
-
* @param $sTermSlug
|
590 |
-
* @return bool
|
591 |
-
*/
|
592 |
-
public function getDoesWpSlugExist( $sTermSlug ) {
|
593 |
-
return ( $this->getDoesWpPostSlugExist( $sTermSlug ) || term_exists( $sTermSlug ) );
|
594 |
-
}
|
595 |
-
|
596 |
-
/**
|
597 |
-
* @param $sTermSlug
|
598 |
-
* @return bool
|
599 |
-
*/
|
600 |
-
public function getDoesWpPostSlugExist( $sTermSlug ) {
|
601 |
-
$oDb = $this->loadDbProcessor();
|
602 |
-
$sQuery = "
|
603 |
-
SELECT ID FROM %s
|
604 |
-
WHERE post_name = '%s'
|
605 |
-
LIMIT 1
|
606 |
-
";
|
607 |
-
$sQuery = sprintf(
|
608 |
-
$sQuery,
|
609 |
-
$oDb->getTable_Posts(),
|
610 |
-
$sTermSlug
|
611 |
-
);
|
612 |
-
$nResult = $oDb->getVar( $sQuery );
|
613 |
-
return !is_null( $nResult ) && $nResult > 0;
|
614 |
-
}
|
615 |
-
|
616 |
-
/**
|
617 |
-
* @return string
|
618 |
-
*/
|
619 |
-
public function getSiteName() {
|
620 |
-
return function_exists( 'get_bloginfo' ) ? get_bloginfo( 'name' ) : 'WordPress Site';
|
621 |
-
}
|
622 |
-
|
623 |
-
/**
|
624 |
-
* @return string
|
625 |
-
*/
|
626 |
-
public function getSiteAdminEmail() {
|
627 |
-
return function_exists( 'get_bloginfo' ) ? get_bloginfo( 'admin_email' ) : '';
|
628 |
-
}
|
629 |
-
|
630 |
-
/**
|
631 |
-
* @return string
|
632 |
-
*/
|
633 |
-
public function getCookieDomain() {
|
634 |
-
return defined( 'COOKIE_DOMAIN' ) ? COOKIE_DOMAIN : false;
|
635 |
-
}
|
636 |
-
|
637 |
-
/**
|
638 |
-
* @return string
|
639 |
-
*/
|
640 |
-
public function getCookiePath() {
|
641 |
-
return defined( 'COOKIEPATH' ) ? COOKIEPATH : '/';
|
642 |
-
}
|
643 |
-
|
644 |
-
/**
|
645 |
-
* @return boolean
|
646 |
-
*/
|
647 |
-
public function isAjax() {
|
648 |
-
return defined( 'DOING_AJAX' ) && DOING_AJAX;
|
649 |
-
}
|
650 |
-
|
651 |
-
/**
|
652 |
-
* @return boolean
|
653 |
-
*/
|
654 |
-
public function isCron() {
|
655 |
-
return defined( 'DOING_CRON' ) && DOING_CRON;
|
656 |
-
}
|
657 |
-
|
658 |
-
/**
|
659 |
-
* @return boolean
|
660 |
-
*/
|
661 |
-
public function isXmlrpc() {
|
662 |
-
return defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST;
|
663 |
-
}
|
664 |
-
|
665 |
-
/**
|
666 |
-
* @return boolean
|
667 |
-
*/
|
668 |
-
public function isMobile() {
|
669 |
-
return function_exists( 'wp_is_mobile' ) && wp_is_mobile();
|
670 |
-
}
|
671 |
-
|
672 |
-
/**
|
673 |
-
* @return array
|
674 |
-
*/
|
675 |
-
public function getAllUserLoginUsernames() {
|
676 |
-
$aUsers = get_users( [ 'fields' => [ 'user_login' ] ] );
|
677 |
-
$aLogins = [];
|
678 |
-
foreach ( $aUsers as $oUser ) {
|
679 |
-
$aLogins[] = $oUser->user_login;
|
680 |
-
}
|
681 |
-
return $aLogins;
|
682 |
-
}
|
683 |
-
|
684 |
-
/**
|
685 |
-
* @return bool
|
686 |
-
*/
|
687 |
-
public function isMultisite() {
|
688 |
-
return function_exists( 'is_multisite' ) && is_multisite();
|
689 |
-
}
|
690 |
-
|
691 |
-
/**
|
692 |
-
* @return bool
|
693 |
-
*/
|
694 |
-
public function isMultisite_SubdomainInstall() {
|
695 |
-
return $this->isMultisite() && defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL;
|
696 |
-
}
|
697 |
-
|
698 |
-
/**
|
699 |
-
* @return bool
|
700 |
-
*/
|
701 |
-
public function isRest() {
|
702 |
-
$bIsRest = ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || !empty( $_REQUEST[ 'rest_route' ] );
|
703 |
-
|
704 |
-
global $wp_rewrite;
|
705 |
-
if ( !$bIsRest && function_exists( 'rest_url' ) && is_object( $wp_rewrite ) ) {
|
706 |
-
$sRestUrlBase = get_rest_url( get_current_blog_id(), '/' );
|
707 |
-
$sRestPath = trim( parse_url( $sRestUrlBase, PHP_URL_PATH ), '/' );
|
708 |
-
$sRequestPath = trim( $this->loadRequest()->getPath(), '/' );
|
709 |
-
$bIsRest = !empty( $sRequestPath ) && !empty( $sRestPath )
|
710 |
-
&& ( strpos( $sRequestPath, $sRestPath ) === 0 );
|
711 |
-
}
|
712 |
-
return $bIsRest;
|
713 |
-
}
|
714 |
-
|
715 |
-
/**
|
716 |
-
* @return string|null
|
717 |
-
*/
|
718 |
-
public function getRestNamespace() {
|
719 |
-
$sNameSpace = null;
|
720 |
-
|
721 |
-
$sPath = $this->getRestPath();
|
722 |
-
|
723 |
-
if ( !empty( $sPath ) ) {
|
724 |
-
$aParts = explode( '/', $sPath );
|
725 |
-
if ( !empty( $aParts ) ) {
|
726 |
-
$sNameSpace = $aParts[ 0 ];
|
727 |
-
}
|
728 |
-
}
|
729 |
-
return $sNameSpace;
|
730 |
-
}
|
731 |
-
|
732 |
-
/**
|
733 |
-
* @return string|null
|
734 |
-
*/
|
735 |
-
public function getRestPath() {
|
736 |
-
$sPath = null;
|
737 |
-
|
738 |
-
if ( $this->isRest() ) {
|
739 |
-
$oReq = $this->loadRequest();
|
740 |
-
|
741 |
-
$sPath = $oReq->request( 'rest_route' );
|
742 |
-
if ( empty( $sPath ) && $this->isPermalinksEnabled() ) {
|
743 |
-
$sFullUri = $this->loadWp()->getHomeUrl( $oReq->getPath() );
|
744 |
-
$sPath = substr( $sFullUri, strlen( get_rest_url( get_current_blog_id() ) ) );
|
745 |
-
}
|
746 |
-
}
|
747 |
-
return $sPath;
|
748 |
-
}
|
749 |
-
|
750 |
-
/**
|
751 |
-
* @param string $sKey
|
752 |
-
* @param string $sValue
|
753 |
-
* @return bool
|
754 |
-
*/
|
755 |
-
public function addOption( $sKey, $sValue ) {
|
756 |
-
return $this->isMultisite() ? add_site_option( $sKey, $sValue ) : add_option( $sKey, $sValue );
|
757 |
-
}
|
758 |
-
|
759 |
-
/**
|
760 |
-
* @param string $sKey
|
761 |
-
* @param $sValue
|
762 |
-
* @return boolean
|
763 |
-
*/
|
764 |
-
public function updateOption( $sKey, $sValue ) {
|
765 |
-
return $this->isMultisite() ? update_site_option( $sKey, $sValue ) : update_option( $sKey, $sValue );
|
766 |
-
}
|
767 |
-
|
768 |
-
/**
|
769 |
-
* @param string $sKey
|
770 |
-
* @param mixed $mDefault
|
771 |
-
* @return mixed
|
772 |
-
*/
|
773 |
-
public function getOption( $sKey, $mDefault = false ) {
|
774 |
-
return $this->isMultisite() ? get_site_option( $sKey, $mDefault ) : get_option( $sKey, $mDefault );
|
775 |
-
}
|
776 |
-
|
777 |
-
/**
|
778 |
-
* @param string $sKey
|
779 |
-
* @return mixed
|
780 |
-
*/
|
781 |
-
public function deleteOption( $sKey ) {
|
782 |
-
return $this->isMultisite() ? delete_site_option( $sKey ) : delete_option( $sKey );
|
783 |
-
}
|
784 |
-
|
785 |
-
/**
|
786 |
-
* @return string
|
787 |
-
*/
|
788 |
-
public function getCurrentWpAdminPage() {
|
789 |
-
|
790 |
-
$oReq = $this->loadRequest();
|
791 |
-
$sScript = $oReq->getScriptName();
|
792 |
-
if ( is_admin() && !empty( $sScript ) && basename( $sScript ) == 'admin.php' ) {
|
793 |
-
$sCurrentPage = $oReq->query( 'page' );
|
794 |
-
}
|
795 |
-
return empty( $sCurrentPage ) ? '' : $sCurrentPage;
|
796 |
-
}
|
797 |
-
|
798 |
-
/**
|
799 |
-
* @param int|null $nTime
|
800 |
-
* @param bool $bShowTime
|
801 |
-
* @param bool $bShowDate
|
802 |
-
* @return string
|
803 |
-
*/
|
804 |
-
public function getTimeStringForDisplay( $nTime = null, $bShowTime = true, $bShowDate = true ) {
|
805 |
-
$nTime = empty( $nTime ) ? $this->loadRequest()->ts() : $nTime;
|
806 |
-
|
807 |
-
$sFullTimeString = $bShowTime ? $this->getTimeFormat() : '';
|
808 |
-
if ( empty( $sFullTimeString ) ) {
|
809 |
-
$sFullTimeString = $bShowDate ? $this->getDateFormat() : '';
|
810 |
-
}
|
811 |
-
else {
|
812 |
-
$sFullTimeString = $bShowDate ? ( $sFullTimeString.' '.$this->getDateFormat() ) : $sFullTimeString;
|
813 |
-
}
|
814 |
-
return date_i18n( $sFullTimeString, $this->getTimeAsGmtOffset( $nTime ) );
|
815 |
-
}
|
816 |
-
|
817 |
-
/**
|
818 |
-
* @param int|null $nTime
|
819 |
-
* @return string
|
820 |
-
*/
|
821 |
-
public function getTimeStampForDisplay( $nTime = null ) {
|
822 |
-
$nTime = empty( $nTime ) ? $this->loadRequest()->ts() : $nTime;
|
823 |
-
return date_i18n( DATE_RFC2822, $this->getTimeAsGmtOffset( $nTime ) );
|
824 |
-
}
|
825 |
-
|
826 |
-
/**
|
827 |
-
* @param int $nTime
|
828 |
-
* @return int
|
829 |
-
*/
|
830 |
-
public function getTimeAsGmtOffset( $nTime = null ) {
|
831 |
-
|
832 |
-
$nTimezoneOffset = wp_timezone_override_offset();
|
833 |
-
if ( $nTimezoneOffset === false ) {
|
834 |
-
$nTimezoneOffset = $this->getOption( 'gmt_offset' );
|
835 |
-
if ( empty( $nTimezoneOffset ) ) {
|
836 |
-
$nTimezoneOffset = 0;
|
837 |
-
}
|
838 |
-
}
|
839 |
-
|
840 |
-
$nTime = is_null( $nTime ) ? $this->loadRequest()->ts() : $nTime;
|
841 |
-
return $nTime + ( $nTimezoneOffset*HOUR_IN_SECONDS );
|
842 |
-
}
|
843 |
-
|
844 |
-
/**
|
845 |
-
* @return string
|
846 |
-
*/
|
847 |
-
public function getTimeFormat() {
|
848 |
-
$sFormat = $this->getOption( 'time_format' );
|
849 |
-
if ( empty( $sFormat ) ) {
|
850 |
-
$sFormat = 'H:i';
|
851 |
-
}
|
852 |
-
return $sFormat;
|
853 |
-
}
|
854 |
-
|
855 |
-
/**
|
856 |
-
* @return string
|
857 |
-
*/
|
858 |
-
public function getDateFormat() {
|
859 |
-
$sFormat = $this->getOption( 'date_format' );
|
860 |
-
if ( empty( $sFormat ) ) {
|
861 |
-
$sFormat = 'F j, Y';
|
862 |
-
}
|
863 |
-
return $sFormat;
|
864 |
-
}
|
865 |
-
|
866 |
-
/**
|
867 |
-
* @return false|WP_Automatic_Updater
|
868 |
-
*/
|
869 |
-
public function getWpAutomaticUpdater() {
|
870 |
-
if ( !isset( $this->oWpAutomaticUpdater ) ) {
|
871 |
-
if ( !class_exists( 'WP_Automatic_Updater', false ) ) {
|
872 |
-
include_once( ABSPATH.'wp-admin/includes/class-wp-upgrader.php' );
|
873 |
-
}
|
874 |
-
if ( class_exists( 'WP_Automatic_Updater', false ) ) {
|
875 |
-
$this->oWpAutomaticUpdater = new WP_Automatic_Updater();
|
876 |
-
}
|
877 |
-
else {
|
878 |
-
$this->oWpAutomaticUpdater = false;
|
879 |
-
}
|
880 |
-
}
|
881 |
-
return $this->oWpAutomaticUpdater;
|
882 |
-
}
|
883 |
-
|
884 |
-
/**
|
885 |
-
* Flushes the Rewrite rules and forces a re-commit to the .htaccess where applicable
|
886 |
-
*/
|
887 |
-
public function resavePermalinks() {
|
888 |
-
/** @var WP_Rewrite $wp_rewrite */
|
889 |
-
global $wp_rewrite;
|
890 |
-
if ( is_object( $wp_rewrite ) ) {
|
891 |
-
$wp_rewrite->flush_rules( true );
|
892 |
-
}
|
893 |
-
}
|
894 |
-
|
895 |
-
/**
|
896 |
-
* @return bool
|
897 |
-
*/
|
898 |
-
public function turnOffCache() {
|
899 |
-
if ( !defined( 'DONOTCACHEPAGE' ) ) {
|
900 |
-
define( 'DONOTCACHEPAGE', true );
|
901 |
-
}
|
902 |
-
|
903 |
-
add_action( 'shutdown', function () {
|
904 |
-
// WP Fastest Cache
|
905 |
-
if ( isset( $GLOBALS[ 'wp_fastest_cache' ] ) &&
|
906 |
-
$GLOBALS[ 'wp_fastest_cache' ] instanceof \WpFastestCache
|
907 |
-
&& method_exists( $GLOBALS[ 'wp_fastest_cache' ], 'singleDeleteCache' ) ) {
|
908 |
-
$nPostId = $this->getCurrentPostId();
|
909 |
-
if ( $nPostId > 0 ) {
|
910 |
-
$GLOBALS[ 'wp_fastest_cache' ]->singleDeleteCache( false, $this->getCurrentPostId() );
|
911 |
-
}
|
912 |
-
}
|
913 |
-
} );
|
914 |
-
return DONOTCACHEPAGE;
|
915 |
-
}
|
916 |
-
|
917 |
-
/**
|
918 |
-
* @param string $sMessage
|
919 |
-
* @param string $sTitle
|
920 |
-
* @param bool $bTurnOffCachePage
|
921 |
-
*/
|
922 |
-
public function wpDie( $sMessage, $sTitle = '', $bTurnOffCachePage = true ) {
|
923 |
-
if ( $bTurnOffCachePage ) {
|
924 |
-
$this->turnOffCache();
|
925 |
-
}
|
926 |
-
wp_die( $sMessage, $sTitle );
|
927 |
-
}
|
928 |
-
|
929 |
-
/**
|
930 |
-
* @return string[]
|
931 |
-
* @deprecated
|
932 |
-
*/
|
933 |
-
public function getCoreChecksums() {
|
934 |
-
return \FernleafSystems\Wordpress\Services\Services::WpGeneral()->getCoreChecksums();
|
935 |
-
}
|
936 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-wpincludes.php
DELETED
@@ -1,79 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Services\Services;
|
4 |
-
|
5 |
-
class ICWP_WPSF_WpIncludes extends ICWP_WPSF_Foundation {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @var ICWP_WPSF_WpIncludes
|
9 |
-
*/
|
10 |
-
protected static $oInstance = null;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @return ICWP_WPSF_WpIncludes
|
14 |
-
*/
|
15 |
-
public static function GetInstance() {
|
16 |
-
if ( is_null( self::$oInstance ) ) {
|
17 |
-
self::$oInstance = new self();
|
18 |
-
}
|
19 |
-
return self::$oInstance;
|
20 |
-
}
|
21 |
-
|
22 |
-
public function __construct() {
|
23 |
-
}
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @return string
|
27 |
-
*/
|
28 |
-
public function getUrl_Jquery() {
|
29 |
-
return $this->getJsUrl( 'jquery/jquery.js' );
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @param string $sJsInclude
|
34 |
-
* @return string
|
35 |
-
*/
|
36 |
-
public function getJsUrl( $sJsInclude ) {
|
37 |
-
return $this->getIncludeUrl( path_join( 'js', $sJsInclude ) );
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* @param string $sInclude
|
42 |
-
* @return string
|
43 |
-
*/
|
44 |
-
public function getIncludeUrl( $sInclude ) {
|
45 |
-
$sInclude = path_join( 'wp-includes', $sInclude );
|
46 |
-
return $this->addIncludeModifiedParam( path_join( $this->loadWp()->getWpUrl(), $sInclude ), $sInclude );
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* @param string $sUrl
|
51 |
-
* @param string $sInclude
|
52 |
-
* @return string
|
53 |
-
*/
|
54 |
-
public function addIncludeModifiedParam( $sUrl, $sInclude ) {
|
55 |
-
$nTime = \FernleafSystems\Wordpress\Services\Services::WpFs()
|
56 |
-
->getModifiedTime( path_join( ABSPATH, $sInclude ) );
|
57 |
-
return add_query_arg( [ 'mtime' => $nTime ], $sUrl );
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Supports PHP 5.3+
|
62 |
-
* @param string $sIncludeHandle
|
63 |
-
* @param string $sAttribute
|
64 |
-
* @param string $sValue
|
65 |
-
* @return $this
|
66 |
-
*/
|
67 |
-
public function addIncludeAttribute( $sIncludeHandle, $sAttribute, $sValue ) {
|
68 |
-
add_filter( 'script_loader_tag',
|
69 |
-
function ( $sTag, $sHandle ) use ( $sIncludeHandle, $sAttribute, $sValue ) {
|
70 |
-
if ( $sHandle == $sIncludeHandle && strpos( $sTag, $sAttribute.'=' ) === false ) {
|
71 |
-
$sTag = str_replace( ' src', sprintf( ' %s="%s" src', $sAttribute, $sValue ), $sTag );
|
72 |
-
}
|
73 |
-
return $sTag;
|
74 |
-
},
|
75 |
-
10, 2
|
76 |
-
);
|
77 |
-
return $this;
|
78 |
-
}
|
79 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/icwp-wpupgrades.php
DELETED
@@ -1,358 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class ICWP_WPSF_WpUpgrades extends ICWP_WPSF_Foundation {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var ICWP_WPSF_WpUpgrades
|
7 |
-
*/
|
8 |
-
protected static $oInstance = null;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @return ICWP_WPSF_WpUpgrades
|
12 |
-
*/
|
13 |
-
public static function GetInstance() {
|
14 |
-
if ( is_null( self::$oInstance ) ) {
|
15 |
-
self::$oInstance = new self();
|
16 |
-
}
|
17 |
-
return self::$oInstance;
|
18 |
-
}
|
19 |
-
}
|
20 |
-
|
21 |
-
require_once( ABSPATH.'wp-admin/includes/upgrade.php' );
|
22 |
-
require_once( ABSPATH.'wp-admin/includes/class-wp-upgrader.php' );
|
23 |
-
|
24 |
-
if ( class_exists( 'WP_Upgrader_Skin', false ) ) {
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Class ICWP_Upgrader_Skin
|
28 |
-
*/
|
29 |
-
class ICWP_Upgrader_Skin extends WP_Upgrader_Skin {
|
30 |
-
|
31 |
-
public $m_aErrors;
|
32 |
-
|
33 |
-
public $aFeedback;
|
34 |
-
|
35 |
-
public function __construct() {
|
36 |
-
parent::__construct();
|
37 |
-
$this->done_header = true;
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* @return array
|
42 |
-
*/
|
43 |
-
public function getFeedback() {
|
44 |
-
return $this->aFeedback;
|
45 |
-
}
|
46 |
-
|
47 |
-
function error( $errors ) {
|
48 |
-
}
|
49 |
-
|
50 |
-
function feedback( $string ) {
|
51 |
-
}
|
52 |
-
}
|
53 |
-
}
|
54 |
-
|
55 |
-
if ( class_exists( 'Plugin_Upgrader' ) ) {
|
56 |
-
class ICWP_Plugin_Upgrader extends Plugin_Upgrader {
|
57 |
-
|
58 |
-
protected $fModeOverwrite = true;
|
59 |
-
|
60 |
-
public function install( $package, $args = [] ) {
|
61 |
-
|
62 |
-
$defaults = [
|
63 |
-
'clear_update_cache' => true,
|
64 |
-
];
|
65 |
-
$parsed_args = wp_parse_args( $args, $defaults );
|
66 |
-
|
67 |
-
$this->init();
|
68 |
-
$this->install_strings();
|
69 |
-
|
70 |
-
add_filter( 'upgrader_source_selection', [ $this, 'check_package' ] );
|
71 |
-
add_filter( 'upgrader_clear_destination', [ $this, 'clearStatCache' ] );
|
72 |
-
|
73 |
-
$oResult = $this->run( [
|
74 |
-
'package' => $package,
|
75 |
-
'destination' => WP_PLUGIN_DIR,
|
76 |
-
'clear_destination' => $this->getOverwriteMode(),
|
77 |
-
// key to overwrite and why we're extending the native wordpress class
|
78 |
-
'clear_working' => true,
|
79 |
-
'hook_extra' => [
|
80 |
-
'type' => 'plugin',
|
81 |
-
'action' => 'install',
|
82 |
-
]
|
83 |
-
] );
|
84 |
-
|
85 |
-
remove_filter( 'upgrader_source_selection', [ $this, 'check_package' ] );
|
86 |
-
remove_filter( 'upgrader_clear_destination', [ $this, 'clearStatCache' ] );
|
87 |
-
|
88 |
-
if ( !$this->result || is_wp_error( $this->result ) ) {
|
89 |
-
return $this->result;
|
90 |
-
}
|
91 |
-
|
92 |
-
// Force refresh of plugin update information
|
93 |
-
wp_clean_plugins_cache( $parsed_args[ 'clear_update_cache' ] );
|
94 |
-
|
95 |
-
return true;
|
96 |
-
}
|
97 |
-
|
98 |
-
/**
|
99 |
-
* This is inserted right after clearing the target directory. It seems that some systems are slow
|
100 |
-
* in updating filesystem "info" because we were receiving permission denied when trying to recreate
|
101 |
-
* the install directory.
|
102 |
-
*/
|
103 |
-
public function clearStatCache() {
|
104 |
-
clearstatcache();
|
105 |
-
sleep( 1 );
|
106 |
-
}
|
107 |
-
|
108 |
-
public function getOverwriteMode() {
|
109 |
-
return $this->fModeOverwrite;
|
110 |
-
}
|
111 |
-
|
112 |
-
public function setOverwriteMode( $fOn = true ) {
|
113 |
-
$this->fModeOverwrite = $fOn;
|
114 |
-
}
|
115 |
-
}
|
116 |
-
}
|
117 |
-
|
118 |
-
if ( class_exists( 'Bulk_Plugin_Upgrader_Skin', false ) ) {
|
119 |
-
/**
|
120 |
-
* Class ICWP_Bulk_Plugin_Upgrader_Skin
|
121 |
-
*/
|
122 |
-
class ICWP_Bulk_Plugin_Upgrader_Skin extends Bulk_Plugin_Upgrader_Skin {
|
123 |
-
|
124 |
-
/**
|
125 |
-
* @var array
|
126 |
-
*/
|
127 |
-
public $m_aErrors;
|
128 |
-
|
129 |
-
/**
|
130 |
-
* @var array
|
131 |
-
*/
|
132 |
-
public $aFeedback;
|
133 |
-
|
134 |
-
/**
|
135 |
-
*
|
136 |
-
*/
|
137 |
-
public function __construct() {
|
138 |
-
parent::__construct( compact( 'nonce', 'url' ) );
|
139 |
-
$this->m_aErrors = [];
|
140 |
-
$this->aFeedback = [];
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* @param string|array $errors
|
145 |
-
*/
|
146 |
-
function error( $errors ) {
|
147 |
-
$this->m_aErrors[] = $errors;
|
148 |
-
|
149 |
-
if ( is_string( $errors ) ) {
|
150 |
-
$this->feedback( $errors );
|
151 |
-
}
|
152 |
-
else if ( is_wp_error( $errors ) && $errors->get_error_code() ) {
|
153 |
-
foreach ( $errors->get_error_messages() as $message ) {
|
154 |
-
if ( $errors->get_error_data() ) {
|
155 |
-
$this->feedback( $message.' '.$errors->get_error_data() );
|
156 |
-
}
|
157 |
-
else {
|
158 |
-
$this->feedback( $message );
|
159 |
-
}
|
160 |
-
}
|
161 |
-
}
|
162 |
-
}
|
163 |
-
|
164 |
-
/**
|
165 |
-
* @return array
|
166 |
-
*/
|
167 |
-
public function getFeedback() {
|
168 |
-
return $this->aFeedback;
|
169 |
-
}
|
170 |
-
|
171 |
-
/**
|
172 |
-
* @param string $string
|
173 |
-
*/
|
174 |
-
function feedback( $string ) {
|
175 |
-
if ( isset( $this->upgrader->strings[ $string ] ) ) {
|
176 |
-
$string = $this->upgrader->strings[ $string ];
|
177 |
-
}
|
178 |
-
|
179 |
-
if ( strpos( $string, '%' ) !== false ) {
|
180 |
-
$args = func_get_args();
|
181 |
-
$args = array_splice( $args, 1 );
|
182 |
-
if ( !empty( $args ) ) {
|
183 |
-
$string = vsprintf( $string, $args );
|
184 |
-
}
|
185 |
-
}
|
186 |
-
if ( empty( $string ) ) {
|
187 |
-
return;
|
188 |
-
}
|
189 |
-
$this->aFeedback[] = $string;
|
190 |
-
}
|
191 |
-
|
192 |
-
function before( $title = '' ) {
|
193 |
-
}
|
194 |
-
|
195 |
-
function after( $title = '' ) {
|
196 |
-
}
|
197 |
-
|
198 |
-
function flush_output() {
|
199 |
-
}
|
200 |
-
/*
|
201 |
-
function footer() {
|
202 |
-
var_dump(debug_backtrace());
|
203 |
-
die( 'testing' );
|
204 |
-
}
|
205 |
-
*/
|
206 |
-
}
|
207 |
-
}
|
208 |
-
|
209 |
-
if ( class_exists( 'Theme_Upgrader' ) ) {
|
210 |
-
|
211 |
-
require_once ABSPATH.'wp-admin/includes/theme.php'; // to get themes_api
|
212 |
-
class ICWP_Theme_Upgrader extends Theme_Upgrader {
|
213 |
-
|
214 |
-
protected $fModeOverwrite = true;
|
215 |
-
|
216 |
-
public function install( $package, $args = [] ) {
|
217 |
-
|
218 |
-
$defaults = [
|
219 |
-
'clear_update_cache' => true,
|
220 |
-
];
|
221 |
-
$parsed_args = wp_parse_args( $args, $defaults );
|
222 |
-
|
223 |
-
$this->init();
|
224 |
-
$this->install_strings();
|
225 |
-
|
226 |
-
add_filter( 'upgrader_source_selection', [ $this, 'check_package' ] );
|
227 |
-
add_filter( 'upgrader_post_install', [ $this, 'check_parent_theme_filter' ], 10, 3 );
|
228 |
-
add_filter( 'upgrader_clear_destination', [ $this, 'clearStatCache' ] );
|
229 |
-
|
230 |
-
$this->run( [
|
231 |
-
'package' => $package,
|
232 |
-
'destination' => get_theme_root(),
|
233 |
-
'clear_destination' => $this->getOverwriteMode(),
|
234 |
-
'clear_working' => true,
|
235 |
-
'hook_extra' => [
|
236 |
-
'type' => 'theme',
|
237 |
-
'action' => 'install',
|
238 |
-
],
|
239 |
-
] );
|
240 |
-
|
241 |
-
remove_filter( 'upgrader_source_selection', [ $this, 'check_package' ] );
|
242 |
-
remove_filter( 'upgrader_post_install', [ $this, 'check_parent_theme_filter' ] );
|
243 |
-
remove_filter( 'upgrader_clear_destination', [ $this, 'clearStatCache' ] );
|
244 |
-
|
245 |
-
if ( !$this->result || is_wp_error( $this->result ) ) {
|
246 |
-
return $this->result;
|
247 |
-
}
|
248 |
-
|
249 |
-
// Refresh the Theme Update information
|
250 |
-
wp_clean_themes_cache( $parsed_args[ 'clear_update_cache' ] );
|
251 |
-
|
252 |
-
return true;
|
253 |
-
}
|
254 |
-
|
255 |
-
/**
|
256 |
-
* This is inserted right after clearing the target directory. It seems that some systems are slow
|
257 |
-
* in updating filesystem "info" because we were receiving permission denied when trying to recreate
|
258 |
-
* the install directory.
|
259 |
-
*/
|
260 |
-
public function clearStatCache() {
|
261 |
-
clearstatcache();
|
262 |
-
sleep( 1 );
|
263 |
-
}
|
264 |
-
|
265 |
-
public function getOverwriteMode() {
|
266 |
-
return $this->fModeOverwrite;
|
267 |
-
}
|
268 |
-
|
269 |
-
public function setOverwriteMode( $fOn = true ) {
|
270 |
-
$this->fModeOverwrite = $fOn;
|
271 |
-
}
|
272 |
-
}
|
273 |
-
}
|
274 |
-
|
275 |
-
if ( class_exists( 'Bulk_Theme_Upgrader_Skin', false ) ) {
|
276 |
-
|
277 |
-
/**
|
278 |
-
* Class Worpit_Bulk_Theme_Upgrader_Skin
|
279 |
-
*/
|
280 |
-
class ICWP_Bulk_Theme_Upgrader_Skin extends Bulk_Theme_Upgrader_Skin {
|
281 |
-
|
282 |
-
/**
|
283 |
-
* @var array
|
284 |
-
*/
|
285 |
-
public $m_aErrors;
|
286 |
-
|
287 |
-
/**
|
288 |
-
* @var array
|
289 |
-
*/
|
290 |
-
public $aFeedback;
|
291 |
-
|
292 |
-
/**
|
293 |
-
*/
|
294 |
-
public function __construct() {
|
295 |
-
parent::__construct( compact( 'title', 'nonce', 'url', 'theme' ) );
|
296 |
-
$this->m_aErrors = [];
|
297 |
-
$this->aFeedback = [];
|
298 |
-
}
|
299 |
-
|
300 |
-
/**
|
301 |
-
* @param string|array $errors
|
302 |
-
*/
|
303 |
-
function error( $errors ) {
|
304 |
-
$this->m_aErrors[] = $errors;
|
305 |
-
|
306 |
-
if ( is_string( $errors ) ) {
|
307 |
-
$this->feedback( $errors );
|
308 |
-
}
|
309 |
-
else if ( is_wp_error( $errors ) && $errors->get_error_code() ) {
|
310 |
-
foreach ( $errors->get_error_messages() as $message ) {
|
311 |
-
if ( $errors->get_error_data() ) {
|
312 |
-
$this->feedback( $message.' '.$errors->get_error_data() );
|
313 |
-
}
|
314 |
-
else {
|
315 |
-
$this->feedback( $message );
|
316 |
-
}
|
317 |
-
}
|
318 |
-
}
|
319 |
-
}
|
320 |
-
|
321 |
-
/**
|
322 |
-
* @return array
|
323 |
-
*/
|
324 |
-
public function getFeedback() {
|
325 |
-
return $this->aFeedback;
|
326 |
-
}
|
327 |
-
|
328 |
-
/**
|
329 |
-
* @param string $string
|
330 |
-
*/
|
331 |
-
function feedback( $string ) {
|
332 |
-
if ( isset( $this->upgrader->strings[ $string ] ) ) {
|
333 |
-
$string = $this->upgrader->strings[ $string ];
|
334 |
-
}
|
335 |
-
|
336 |
-
if ( strpos( $string, '%' ) !== false ) {
|
337 |
-
$args = func_get_args();
|
338 |
-
$args = array_splice( $args, 1 );
|
339 |
-
if ( !empty( $args ) ) {
|
340 |
-
$string = vsprintf( $string, $args );
|
341 |
-
}
|
342 |
-
}
|
343 |
-
if ( empty( $string ) ) {
|
344 |
-
return;
|
345 |
-
}
|
346 |
-
$this->aFeedback[] = $string;
|
347 |
-
}
|
348 |
-
|
349 |
-
function before( $title = '' ) {
|
350 |
-
}
|
351 |
-
|
352 |
-
function after( $title = '' ) {
|
353 |
-
}
|
354 |
-
|
355 |
-
function flush_output() {
|
356 |
-
}
|
357 |
-
}
|
358 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/wp-admin-notices.php
CHANGED
@@ -2,6 +2,10 @@
|
|
2 |
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
|
|
|
|
|
|
|
|
|
5 |
class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
|
6 |
|
7 |
/**
|
@@ -9,11 +13,6 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
|
|
9 |
*/
|
10 |
protected static $oInstance = null;
|
11 |
|
12 |
-
/**
|
13 |
-
* @var array
|
14 |
-
*/
|
15 |
-
protected $aAdminNotices;
|
16 |
-
|
17 |
/**
|
18 |
* @var string
|
19 |
*/
|
@@ -35,67 +34,9 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
|
|
35 |
}
|
36 |
|
37 |
protected function __construct() {
|
38 |
-
$this->sFlashMessage = '';
|
39 |
-
add_action( 'admin_notices', [ $this, 'onWpAdminNotices' ] );
|
40 |
-
add_action( 'network_admin_notices', [ $this, 'onWpAdminNotices' ] );
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* @param array $aAjaxResponse
|
45 |
-
* @return array
|
46 |
-
*/
|
47 |
-
public function handleAuthAjax( $aAjaxResponse ) {
|
48 |
-
if ( empty( $aAjaxResponse ) && $this->loadRequest()->request( 'exec' ) === 'dismiss_admin_notice' ) {
|
49 |
-
$aAjaxResponse = $this->ajaxExec_DismissAdminNotice();
|
50 |
-
}
|
51 |
-
return $aAjaxResponse;
|
52 |
-
}
|
53 |
-
|
54 |
-
/**
|
55 |
-
* @return array
|
56 |
-
*/
|
57 |
-
protected function ajaxExec_DismissAdminNotice() {
|
58 |
-
// Get all notices and if this notice exists, we set it to "hidden"
|
59 |
-
$sNoticeId = sanitize_key( $this->loadRequest()->query( 'notice_id', '' ) );
|
60 |
-
$aNotices = apply_filters( $this->getPrefix().'register_admin_notices', [] );
|
61 |
-
if ( !empty( $sNoticeId ) && array_key_exists( $sNoticeId, $aNotices ) ) {
|
62 |
-
$this->setMeta( $aNotices[ $sNoticeId ][ 'id' ] );
|
63 |
-
}
|
64 |
-
return [ 'success' => true ];
|
65 |
}
|
66 |
|
67 |
public function onWpAdminNotices() {
|
68 |
-
do_action( $this->getPrefix().'generate_admin_notices' );
|
69 |
-
foreach ( $this->getNotices() as $sKey => $sAdminNoticeContent ) {
|
70 |
-
echo $sAdminNoticeContent;
|
71 |
-
}
|
72 |
-
$this->flashUserAdminNotice();
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* @param string $sNoticeId
|
77 |
-
* @return true
|
78 |
-
*/
|
79 |
-
public function isDismissed( $sNoticeId ) {
|
80 |
-
$aMeta = $this->getMeta( $sNoticeId );
|
81 |
-
return ( isset( $aMeta[ 'time' ] ) && $aMeta[ 'time' ] > 0 );
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* @param string $sNoticeId
|
86 |
-
* @return false|string
|
87 |
-
*/
|
88 |
-
public function getMeta( $sNoticeId ) {
|
89 |
-
$mValue = [];
|
90 |
-
|
91 |
-
$oMeta = $this->getCurrentUserMeta();
|
92 |
-
|
93 |
-
$sCleanNotice = 'notice_'.str_replace( [ '-', '_' ], '', $sNoticeId );
|
94 |
-
if ( isset( $oMeta->{$sCleanNotice} ) && is_array( $oMeta->{$sCleanNotice} ) ) {
|
95 |
-
$mValue = $oMeta->{$sCleanNotice};
|
96 |
-
}
|
97 |
-
|
98 |
-
return $mValue;
|
99 |
}
|
100 |
|
101 |
/**
|
@@ -106,21 +47,6 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
|
|
106 |
return Services::WpUsers()->metaVoForUser( rtrim( $this->getPrefix(), '-' ) );
|
107 |
}
|
108 |
|
109 |
-
/**
|
110 |
-
* @param string $sNoticeId
|
111 |
-
* @param array $aMeta
|
112 |
-
*/
|
113 |
-
public function setMeta( $sNoticeId, $aMeta = [] ) {
|
114 |
-
if ( !is_array( $aMeta ) ) {
|
115 |
-
$aMeta = [];
|
116 |
-
}
|
117 |
-
|
118 |
-
$oMeta = $this->getCurrentUserMeta();
|
119 |
-
$sCleanNotice = 'notice_'.str_replace( [ '-', '_' ], '', $sNoticeId );
|
120 |
-
$oMeta->{$sCleanNotice} = array_merge( [ 'time' => $this->loadRequest()->ts() ], $aMeta );
|
121 |
-
return;
|
122 |
-
}
|
123 |
-
|
124 |
/**
|
125 |
* @return string
|
126 |
*/
|
@@ -128,105 +54,6 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
|
|
128 |
return $this->sPrefix;
|
129 |
}
|
130 |
|
131 |
-
/**
|
132 |
-
* @param string $sPrefix
|
133 |
-
* @return $this
|
134 |
-
*/
|
135 |
-
public function setPrefix( $sPrefix ) {
|
136 |
-
$this->sPrefix = rtrim( $sPrefix, '-' ).'-';
|
137 |
-
return $this;
|
138 |
-
}
|
139 |
-
|
140 |
-
/**
|
141 |
-
* @return array
|
142 |
-
*/
|
143 |
-
protected function getNotices() {
|
144 |
-
if ( !isset( $this->aAdminNotices ) || !is_array( $this->aAdminNotices ) ) {
|
145 |
-
$this->aAdminNotices = [];
|
146 |
-
}
|
147 |
-
return $this->aAdminNotices;
|
148 |
-
}
|
149 |
-
|
150 |
-
/**
|
151 |
-
* @param string $sNoticeId
|
152 |
-
* @return bool
|
153 |
-
*/
|
154 |
-
protected function getNoticeAlreadyExists( $sNoticeId ) {
|
155 |
-
return !empty( $this->aAdminNotices[ $sNoticeId ] );
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* @param string $sNoticeId
|
160 |
-
* @param string $sNotice
|
161 |
-
* @return $this
|
162 |
-
*/
|
163 |
-
public function addAdminNotice( $sNotice, $sNoticeId = '' ) {
|
164 |
-
if ( !empty( $sNotice ) ) {
|
165 |
-
if ( empty( $sNoticeId ) ) {
|
166 |
-
$sNoticeId = md5( uniqid( '', true ) );
|
167 |
-
}
|
168 |
-
if ( !$this->getNoticeAlreadyExists( $sNoticeId ) ) {
|
169 |
-
$aCurrentNotices = $this->getNotices();
|
170 |
-
$aCurrentNotices[ $sNoticeId ] = $sNotice;
|
171 |
-
$this->aAdminNotices = $aCurrentNotices;
|
172 |
-
}
|
173 |
-
}
|
174 |
-
return $this;
|
175 |
-
}
|
176 |
-
|
177 |
-
/**
|
178 |
-
* Use this to add a simple message to the admin notice collection. It'll wrap it up in basic html
|
179 |
-
* @param string $sRawMessage
|
180 |
-
* @param string $sType
|
181 |
-
* @return $this
|
182 |
-
*/
|
183 |
-
public function addRawAdminNotice( $sRawMessage, $sType = 'updated' ) {
|
184 |
-
return $this->addAdminNotice( $this->wrapAdminNoticeHtml( $sRawMessage, $sType ) );
|
185 |
-
}
|
186 |
-
|
187 |
-
/**
|
188 |
-
* Provides the basic HTML template for printing a WordPress Admin Notices
|
189 |
-
* @param $sNotice - The message to be displayed.
|
190 |
-
* @param $sMessageClass - either error or updated
|
191 |
-
* @param $bPrint - if true, will echo. false will return the string
|
192 |
-
* @return boolean|string
|
193 |
-
*/
|
194 |
-
protected function wrapAdminNoticeHtml( $sNotice = '', $sMessageClass = 'updated', $bPrint = false ) {
|
195 |
-
$sWrapper = '<div class="%s odp-admin-notice">%s</div>';
|
196 |
-
$sFullNotice = sprintf( $sWrapper, $sMessageClass, $sNotice );
|
197 |
-
if ( $bPrint ) {
|
198 |
-
echo $sFullNotice;
|
199 |
-
return true;
|
200 |
-
}
|
201 |
-
else {
|
202 |
-
return $sFullNotice;
|
203 |
-
}
|
204 |
-
}
|
205 |
-
|
206 |
-
/**
|
207 |
-
* @param string $sMessage
|
208 |
-
* @param bool $bError
|
209 |
-
* @return $this
|
210 |
-
*/
|
211 |
-
public function addFlashUserMessage( $sMessage, $bError = false ) {
|
212 |
-
if ( Services::WpUsers()->isUserLoggedIn() ) {
|
213 |
-
$this->getCurrentUserMeta()->flash_msg = ( $bError ? 'error' : 'updated' )
|
214 |
-
.'::'.sanitize_text_field( $sMessage )
|
215 |
-
.'::'.( Services::Request()->ts() + 300 );
|
216 |
-
}
|
217 |
-
return $this;
|
218 |
-
}
|
219 |
-
|
220 |
-
protected function flashUserAdminNotice() {
|
221 |
-
$this->flushFlash();
|
222 |
-
if ( $this->hasFlash() ) {
|
223 |
-
$aParts = $this->getFlashParts();
|
224 |
-
if ( empty( $aParts[ 2 ] ) || Services::Request()->ts() < $aParts[ 2 ] ) {
|
225 |
-
echo $this->wrapAdminNoticeHtml( '<p>'.$aParts[ 1 ].'</p>', $aParts[ 0 ] );
|
226 |
-
}
|
227 |
-
}
|
228 |
-
}
|
229 |
-
|
230 |
/**
|
231 |
* @return string
|
232 |
*/
|
@@ -249,15 +76,6 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
|
|
249 |
return isset( $aParts[ 1 ] ) ? $aParts[ 1 ] : '';
|
250 |
}
|
251 |
|
252 |
-
/**
|
253 |
-
* Requires that the flash has been flushed
|
254 |
-
* @return bool
|
255 |
-
*/
|
256 |
-
public function hasFlash() {
|
257 |
-
$sFlash = $this->getFlash();
|
258 |
-
return !empty( $sFlash );
|
259 |
-
}
|
260 |
-
|
261 |
/**
|
262 |
* @return $this
|
263 |
*/
|
2 |
|
3 |
use FernleafSystems\Wordpress\Services\Services;
|
4 |
|
5 |
+
/**
|
6 |
+
* Class ICWP_WPSF_WpAdminNotices
|
7 |
+
* @deprecated 8.4
|
8 |
+
*/
|
9 |
class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
|
10 |
|
11 |
/**
|
13 |
*/
|
14 |
protected static $oInstance = null;
|
15 |
|
|
|
|
|
|
|
|
|
|
|
16 |
/**
|
17 |
* @var string
|
18 |
*/
|
34 |
}
|
35 |
|
36 |
protected function __construct() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
}
|
38 |
|
39 |
public function onWpAdminNotices() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
|
42 |
/**
|
47 |
return Services::WpUsers()->metaVoForUser( rtrim( $this->getPrefix(), '-' ) );
|
48 |
}
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
/**
|
51 |
* @return string
|
52 |
*/
|
54 |
return $this->sPrefix;
|
55 |
}
|
56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
/**
|
58 |
* @return string
|
59 |
*/
|
76 |
return isset( $aParts[ 1 ] ) ? $aParts[ 1 ] : '';
|
77 |
}
|
78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
/**
|
80 |
* @return $this
|
81 |
*/
|
src/common/wp-comments.php
DELETED
@@ -1,105 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Services\Services;
|
4 |
-
|
5 |
-
class ICWP_WPSF_WpComments extends ICWP_WPSF_Foundation {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @var ICWP_WPSF_WpComments
|
9 |
-
*/
|
10 |
-
protected static $oInstance = null;
|
11 |
-
|
12 |
-
private function __construct() {
|
13 |
-
}
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @return ICWP_WPSF_WpComments
|
17 |
-
*/
|
18 |
-
public static function GetInstance() {
|
19 |
-
if ( is_null( self::$oInstance ) ) {
|
20 |
-
self::$oInstance = new self();
|
21 |
-
}
|
22 |
-
return self::$oInstance;
|
23 |
-
}
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @param WP_Post|null $oPost - queries the current post if null
|
27 |
-
* @return bool
|
28 |
-
*/
|
29 |
-
public function isCommentsOpen( $oPost = null ) {
|
30 |
-
if ( is_null( $oPost ) || !is_a( $oPost, 'WP_Post' ) ) {
|
31 |
-
global $post;
|
32 |
-
$oPost = $post;
|
33 |
-
}
|
34 |
-
return ( is_a( $oPost, 'WP_Post' ) ? ( $oPost->comment_status == 'open' ) : $this->isCommentsOpenByDefault() );
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* @return bool
|
39 |
-
*/
|
40 |
-
public function isCommentsOpenByDefault() {
|
41 |
-
return ( $this->loadWp()->getOption( 'default_comment_status' ) == 'open' );
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* @param string $sAuthorEmail
|
46 |
-
* @return bool
|
47 |
-
*/
|
48 |
-
public function isAuthorApproved( $sAuthorEmail ) {
|
49 |
-
|
50 |
-
if ( !$this->loadDP()->validEmail( $sAuthorEmail ) ) {
|
51 |
-
return false;
|
52 |
-
}
|
53 |
-
|
54 |
-
$oDb = $this->loadDbProcessor();
|
55 |
-
$sQuery = "
|
56 |
-
SELECT comment_approved
|
57 |
-
FROM %s
|
58 |
-
WHERE
|
59 |
-
comment_author_email = '%s'
|
60 |
-
AND comment_approved = '1'
|
61 |
-
LIMIT 1
|
62 |
-
";
|
63 |
-
|
64 |
-
$sQuery = sprintf(
|
65 |
-
$sQuery,
|
66 |
-
$oDb->getTable_Comments(),
|
67 |
-
esc_sql( $sAuthorEmail )
|
68 |
-
);
|
69 |
-
return $oDb->getVar( $sQuery ) == 1;
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* @param string $sAuthorEmail
|
74 |
-
* @return bool
|
75 |
-
*/
|
76 |
-
public function countApproved( $sAuthorEmail ) {
|
77 |
-
$nCount = 0;
|
78 |
-
|
79 |
-
if ( $this->loadDP()->validEmail( $sAuthorEmail ) ) {
|
80 |
-
$oDb = $this->loadDbProcessor();
|
81 |
-
$sQuery = "
|
82 |
-
SELECT COUNT(*)
|
83 |
-
FROM %s
|
84 |
-
WHERE
|
85 |
-
comment_author_email = '%s'
|
86 |
-
AND comment_approved = 1
|
87 |
-
";
|
88 |
-
|
89 |
-
$sQuery = sprintf(
|
90 |
-
$sQuery,
|
91 |
-
$oDb->getTable_Comments(),
|
92 |
-
esc_sql( $sAuthorEmail )
|
93 |
-
);
|
94 |
-
$nCount = (int)$oDb->getVar( $sQuery );
|
95 |
-
}
|
96 |
-
return $nCount;
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* @return bool
|
101 |
-
*/
|
102 |
-
public function isCommentPost() {
|
103 |
-
return $this->loadRequest()->isMethodPost() && $this->loadWp()->isCurrentPage( 'wp-comments-post.php' );
|
104 |
-
}
|
105 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/wp-users.php
DELETED
@@ -1,290 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var ICWP_WPSF_WpUsers
|
7 |
-
*/
|
8 |
-
protected static $oInstance = null;
|
9 |
-
|
10 |
-
private function __construct() {
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @return ICWP_WPSF_WpUsers
|
15 |
-
*/
|
16 |
-
public static function GetInstance() {
|
17 |
-
if ( is_null( self::$oInstance ) ) {
|
18 |
-
self::$oInstance = new self();
|
19 |
-
}
|
20 |
-
return self::$oInstance;
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @param string $sKey
|
25 |
-
* @param integer $nUserId -user ID
|
26 |
-
* @return boolean
|
27 |
-
*/
|
28 |
-
public function deleteUserMeta( $sKey, $nUserId = null ) {
|
29 |
-
if ( empty( $nUserId ) ) {
|
30 |
-
$nUserId = $this->getCurrentWpUserId();
|
31 |
-
}
|
32 |
-
else if ( $nUserId instanceof WP_User ) {
|
33 |
-
$nUserId = $nUserId->ID;
|
34 |
-
}
|
35 |
-
|
36 |
-
$bSuccess = false;
|
37 |
-
if ( $nUserId > 0 ) {
|
38 |
-
$bSuccess = delete_user_meta( $nUserId, $sKey );
|
39 |
-
}
|
40 |
-
return $bSuccess;
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* @param array $aLoginUrlParams
|
45 |
-
*/
|
46 |
-
public function forceUserRelogin( $aLoginUrlParams = [] ) {
|
47 |
-
$this->logoutUser();
|
48 |
-
$this->loadWp()->redirectToLogin( $aLoginUrlParams );
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* @param array $aArgs
|
53 |
-
* @return WP_User[]
|
54 |
-
*/
|
55 |
-
public function getAllUsers( $aArgs = [] ) {
|
56 |
-
$aArgs = wp_parse_args(
|
57 |
-
$aArgs,
|
58 |
-
[
|
59 |
-
'blog_id' => 0,
|
60 |
-
// 'fields' => array(
|
61 |
-
// 'ID',
|
62 |
-
// 'user_login',
|
63 |
-
// 'user_email',
|
64 |
-
// 'user_pass',
|
65 |
-
// )
|
66 |
-
]
|
67 |
-
);
|
68 |
-
return function_exists( 'get_users' ) ? get_users( $aArgs ) : [];
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* @return integer
|
73 |
-
*/
|
74 |
-
public function getCurrentUserLevel() {
|
75 |
-
$oUser = $this->getCurrentWpUser();
|
76 |
-
return ( is_object( $oUser ) && ( $oUser instanceof WP_User ) ) ? $oUser->get( 'user_level' ) : -1;
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* @return array
|
81 |
-
*/
|
82 |
-
public function getLevelToRoleMap() {
|
83 |
-
return [
|
84 |
-
0 => 'subscriber',
|
85 |
-
1 => 'contributor',
|
86 |
-
2 => 'author',
|
87 |
-
3 => 'editor',
|
88 |
-
8 => 'administrator'
|
89 |
-
];
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* @param bool $bSlugsOnly
|
94 |
-
* @return string[]|array[]
|
95 |
-
*/
|
96 |
-
public function getAvailableUserRoles( $bSlugsOnly = true ) {
|
97 |
-
require_once( ABSPATH.'wp-admin/includes/user.php' );
|
98 |
-
return $bSlugsOnly ? array_keys( get_editable_roles() ) : get_editable_roles();
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* @return null|WP_User
|
103 |
-
*/
|
104 |
-
public function getCurrentWpUser() {
|
105 |
-
return $this->isUserLoggedIn() ? wp_get_current_user() : null;
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* @return int - 0 if not logged in or can't get the current User
|
110 |
-
*/
|
111 |
-
public function getCurrentWpUserId() {
|
112 |
-
$oUser = $this->getCurrentWpUser();
|
113 |
-
return is_null( $oUser ) ? 0 : $oUser->ID;
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* @return null|string
|
118 |
-
*/
|
119 |
-
public function getCurrentWpUsername() {
|
120 |
-
$oUser = $this->getCurrentWpUser();
|
121 |
-
return is_null( $oUser ) ? null : $oUser->user_login;
|
122 |
-
}
|
123 |
-
|
124 |
-
/**
|
125 |
-
* @param WP_User $oUser
|
126 |
-
* @return string
|
127 |
-
*/
|
128 |
-
public function getAdminUrl_ProfileEdit( $oUser = null ) {
|
129 |
-
if ( $oUser instanceof WP_User ) {
|
130 |
-
$sPath = 'user-edit.php?user_id='.$oUser->ID;
|
131 |
-
}
|
132 |
-
else {
|
133 |
-
$sPath = 'profile.php';
|
134 |
-
}
|
135 |
-
return $this->loadWp()->getAdminUrl( $sPath );
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* @param string $sEmail
|
140 |
-
* @return WP_User|null
|
141 |
-
*/
|
142 |
-
public function getUserByEmail( $sEmail ) {
|
143 |
-
return $this->getUserBy( 'email', $sEmail );
|
144 |
-
}
|
145 |
-
|
146 |
-
/**
|
147 |
-
* @param int $nId
|
148 |
-
* @return WP_User|null
|
149 |
-
*/
|
150 |
-
public function getUserById( $nId ) {
|
151 |
-
return $this->getUserBy( 'id', $nId );
|
152 |
-
}
|
153 |
-
|
154 |
-
/**
|
155 |
-
* @param $sUsername
|
156 |
-
* @return null|WP_User
|
157 |
-
*/
|
158 |
-
public function getUserByUsername( $sUsername ) {
|
159 |
-
return $this->getUserBy( 'login', $sUsername );
|
160 |
-
}
|
161 |
-
|
162 |
-
/**
|
163 |
-
* @param string $sKey
|
164 |
-
* @param mixed $mValue
|
165 |
-
* @return null|WP_User
|
166 |
-
*/
|
167 |
-
public function getUserBy( $sKey, $mValue ) {
|
168 |
-
$oU = function_exists( 'get_user_by' ) ? get_user_by( $sKey, $mValue ) : null;
|
169 |
-
return empty( $oU ) ? null : $oU;
|
170 |
-
}
|
171 |
-
|
172 |
-
/**
|
173 |
-
* @param string $sKey should be already prefixed
|
174 |
-
* @param int|null $nUserId - if omitted get for current user
|
175 |
-
* @return false|string
|
176 |
-
*/
|
177 |
-
public function getUserMeta( $sKey, $nUserId = null ) {
|
178 |
-
if ( empty( $nUserId ) ) {
|
179 |
-
$nUserId = $this->getCurrentWpUserId();
|
180 |
-
}
|
181 |
-
else if ( $nUserId instanceof WP_User ) {
|
182 |
-
$nUserId = $nUserId->ID;
|
183 |
-
}
|
184 |
-
|
185 |
-
$mResult = false;
|
186 |
-
if ( $nUserId > 0 ) {
|
187 |
-
$mResult = get_user_meta( $nUserId, $sKey, true );
|
188 |
-
}
|
189 |
-
return $mResult;
|
190 |
-
}
|
191 |
-
|
192 |
-
/**
|
193 |
-
* @param WP_User $oUser
|
194 |
-
* @return string|null
|
195 |
-
* @see wp-login.php
|
196 |
-
*/
|
197 |
-
public function getPasswordResetUrl( $oUser ) {
|
198 |
-
$sUrl = null;
|
199 |
-
|
200 |
-
$sResetKey = get_password_reset_key( $oUser );
|
201 |
-
if ( !is_wp_error( $sResetKey ) ) {
|
202 |
-
$sUrl = add_query_arg(
|
203 |
-
[
|
204 |
-
'action' => 'rp',
|
205 |
-
'key' => $sResetKey,
|
206 |
-
'login' => $oUser->user_login,
|
207 |
-
],
|
208 |
-
wp_login_url()
|
209 |
-
);
|
210 |
-
}
|
211 |
-
|
212 |
-
return $sUrl;
|
213 |
-
}
|
214 |
-
|
215 |
-
/**
|
216 |
-
* @param WP_User|null $oUser
|
217 |
-
* @return bool
|
218 |
-
*/
|
219 |
-
public function isUserAdmin( $oUser = null ) {
|
220 |
-
if ( empty( $oUser ) ) {
|
221 |
-
$bIsAdmin = $this->isUserLoggedIn() && current_user_can( 'manage_options' );
|
222 |
-
}
|
223 |
-
else {
|
224 |
-
$bIsAdmin = user_can( $oUser, 'manage_options' );
|
225 |
-
}
|
226 |
-
return $bIsAdmin;
|
227 |
-
}
|
228 |
-
|
229 |
-
/**
|
230 |
-
* @return bool
|
231 |
-
*/
|
232 |
-
public function isUserLoggedIn() {
|
233 |
-
return function_exists( 'is_user_logged_in' ) && is_user_logged_in();
|
234 |
-
}
|
235 |
-
|
236 |
-
/**
|
237 |
-
* Fires the WordPress logout functions. If $bQuiet is true, it'll manually
|
238 |
-
* call the WordPress logout code, so as not to fire any other logout actions
|
239 |
-
* We might want to be "quiet" so as not to fire out own action hooks.
|
240 |
-
* @param bool $bQuiet
|
241 |
-
*/
|
242 |
-
public function logoutUser( $bQuiet = false ) {
|
243 |
-
if ( $bQuiet ) {
|
244 |
-
wp_destroy_current_session();
|
245 |
-
wp_clear_auth_cookie();
|
246 |
-
}
|
247 |
-
else {
|
248 |
-
wp_logout();
|
249 |
-
}
|
250 |
-
}
|
251 |
-
|
252 |
-
/**
|
253 |
-
* Updates the user meta data for the current (or supplied user ID)
|
254 |
-
* @param string $sKey
|
255 |
-
* @param mixed $mValue
|
256 |
-
* @param WP_User|int $nUserId -user ID
|
257 |
-
* @return boolean
|
258 |
-
*/
|
259 |
-
public function updateUserMeta( $sKey, $mValue, $nUserId = null ) {
|
260 |
-
if ( empty( $nUserId ) ) {
|
261 |
-
$nUserId = $this->getCurrentWpUserId();
|
262 |
-
}
|
263 |
-
else if ( $nUserId instanceof WP_User ) {
|
264 |
-
$nUserId = $nUserId->ID;
|
265 |
-
}
|
266 |
-
|
267 |
-
$bSuccess = false;
|
268 |
-
if ( $nUserId > 0 ) {
|
269 |
-
$bSuccess = update_user_meta( $nUserId, $sKey, $mValue );
|
270 |
-
}
|
271 |
-
return $bSuccess;
|
272 |
-
}
|
273 |
-
|
274 |
-
/**
|
275 |
-
* @param string $sUsername
|
276 |
-
* @return bool
|
277 |
-
*/
|
278 |
-
public function setUserLoggedIn( $sUsername ) {
|
279 |
-
|
280 |
-
$oUser = $this->getUserByUsername( $sUsername );
|
281 |
-
$bSuccess = $oUser instanceof WP_User;
|
282 |
-
if ( $bSuccess ) {
|
283 |
-
wp_clear_auth_cookie();
|
284 |
-
wp_set_current_user( $oUser->ID, $oUser->user_login );
|
285 |
-
wp_set_auth_cookie( $oUser->ID, true );
|
286 |
-
do_action( 'wp_login', $oUser->user_login, $oUser );
|
287 |
-
}
|
288 |
-
return $bSuccess;
|
289 |
-
}
|
290 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/common/wp-widget.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
/**
|
4 |
* Class ICWP_WPSF_WpWidget
|
|
|
5 |
*/
|
6 |
abstract class ICWP_WPSF_WpWidget extends \WP_Widget {
|
7 |
|
2 |
|
3 |
/**
|
4 |
* Class ICWP_WPSF_WpWidget
|
5 |
+
* @deprecated 8.4
|
6 |
*/
|
7 |
abstract class ICWP_WPSF_WpWidget extends \WP_Widget {
|
8 |
|
src/config/changelog.json
CHANGED
@@ -356,7 +356,7 @@
|
|
356 |
"timestamp": "1491523200",
|
357 |
"name": "",
|
358 |
"summary": "Introduction of Login Authentication Portal",
|
359 |
-
"link": "https://
|
360 |
"is_patch": false,
|
361 |
"options_added": true,
|
362 |
"options_removed": true
|
@@ -700,13 +700,13 @@
|
|
700 |
{
|
701 |
"type": "changed",
|
702 |
"summary": "Major overhaul of Two-Factor / Multi-Factor Login Authentication",
|
703 |
-
"link": "https://
|
704 |
"version": "5.8.0"
|
705 |
},
|
706 |
{
|
707 |
"type": "changed",
|
708 |
"summary": "Introduction of Login Authentication Portal for improved Multi-Factor Authentication",
|
709 |
-
"link": "https://
|
710 |
"version": "5.8.0"
|
711 |
},
|
712 |
{
|
@@ -747,7 +747,7 @@
|
|
747 |
{
|
748 |
"type": "improvements",
|
749 |
"summary": "Further preparation for Shield Central release",
|
750 |
-
"link": "https://
|
751 |
"version": "5.8.0"
|
752 |
}
|
753 |
]
|
356 |
"timestamp": "1491523200",
|
357 |
"name": "",
|
358 |
"summary": "Introduction of Login Authentication Portal",
|
359 |
+
"link": "https://shsec.io/86",
|
360 |
"is_patch": false,
|
361 |
"options_added": true,
|
362 |
"options_removed": true
|
700 |
{
|
701 |
"type": "changed",
|
702 |
"summary": "Major overhaul of Two-Factor / Multi-Factor Login Authentication",
|
703 |
+
"link": "https://shsec.io/87",
|
704 |
"version": "5.8.0"
|
705 |
},
|
706 |
{
|
707 |
"type": "changed",
|
708 |
"summary": "Introduction of Login Authentication Portal for improved Multi-Factor Authentication",
|
709 |
+
"link": "https://shsec.io/86",
|
710 |
"version": "5.8.0"
|
711 |
},
|
712 |
{
|
747 |
{
|
748 |
"type": "improvements",
|
749 |
"summary": "Further preparation for Shield Central release",
|
750 |
+
"link": "https://shsec.io/83",
|
751 |
"version": "5.8.0"
|
752 |
}
|
753 |
]
|
src/config/feature-admin_access_restriction.php
CHANGED
@@ -82,8 +82,8 @@
|
|
82 |
"section": "section_enable_plugin_feature_admin_access_restriction",
|
83 |
"default": "Y",
|
84 |
"type": "checkbox",
|
85 |
-
"link_info": "https://
|
86 |
-
"link_blog": "https://
|
87 |
"name": "Enable Security Admin",
|
88 |
"summary": "Enforce Security Admin Access Restriction",
|
89 |
"description": "Enable this with great care and consideration. When this Access Key option is enabled, you must specify a key below and use it to gain access to this plugin."
|
@@ -94,7 +94,7 @@
|
|
94 |
"sensitive": true,
|
95 |
"default": "",
|
96 |
"type": "password",
|
97 |
-
"link_info": "https://
|
98 |
"link_blog": "",
|
99 |
"name": "Security Admin Access Key",
|
100 |
"summary": "Provide/Update Security Admin Access Key",
|
@@ -107,7 +107,7 @@
|
|
107 |
"premium": true,
|
108 |
"default": "",
|
109 |
"type": "array",
|
110 |
-
"link_info": "https://
|
111 |
"link_blog": "",
|
112 |
"name": "Security Admins",
|
113 |
"summary": "Persistent Security Admins",
|
@@ -119,7 +119,7 @@
|
|
119 |
"default": 30,
|
120 |
"type": "integer",
|
121 |
"min": 1,
|
122 |
-
"link_info": "https://
|
123 |
"link_blog": "",
|
124 |
"name": "Security Admin Timeout",
|
125 |
"summary": "Specify An Automatic Timeout Interval For Security Admin Access",
|
@@ -130,8 +130,8 @@
|
|
130 |
"section": "section_admin_access_restriction_areas",
|
131 |
"default": "Y",
|
132 |
"type": "checkbox",
|
133 |
-
"link_info": "https://
|
134 |
-
"link_blog": "https://
|
135 |
"name": "Pages",
|
136 |
"summary": "Restrict Access To Key WordPress Posts And Pages Actions",
|
137 |
"description": "Careful: This will restrict access to page/post creation, editing and deletion. Note: Selecting 'Edit' will also restrict all other options."
|
@@ -141,7 +141,7 @@
|
|
141 |
"section": "section_admin_access_restriction_areas",
|
142 |
"default": "N",
|
143 |
"type": "checkbox",
|
144 |
-
"link_info": "https://
|
145 |
"link_blog": "",
|
146 |
"name": "Admin Users",
|
147 |
"summary": "Restrict Access To Create/Delete/Modify Other Admin Users",
|
@@ -170,8 +170,8 @@
|
|
170 |
"text": "Delete"
|
171 |
}
|
172 |
],
|
173 |
-
"link_info": "https://
|
174 |
-
"link_blog": "https://
|
175 |
"summary": "Restrict Access To Key WordPress Plugin Actions",
|
176 |
"description": "Careful: This will restrict access to plugin installation, update, activation and deletion. Note: Selecting 'Activate' will also restrict all other options."
|
177 |
},
|
@@ -202,8 +202,8 @@
|
|
202 |
"text": "Delete"
|
203 |
}
|
204 |
],
|
205 |
-
"link_info": "https://
|
206 |
-
"link_blog": "https://
|
207 |
"summary": "Restrict Access To WordPress Theme Actions",
|
208 |
"description": "Careful: This will restrict access to theme installation, update, activation and deletion."
|
209 |
},
|
@@ -226,8 +226,8 @@
|
|
226 |
"text": "Delete"
|
227 |
}
|
228 |
],
|
229 |
-
"link_info": "https://
|
230 |
-
"link_blog": "https://
|
231 |
"summary": "Restrict Access To Key WordPress Posts And Pages Actions",
|
232 |
"description": "Careful: This will restrict access to page/post creation, editing and deletion."
|
233 |
},
|
@@ -237,8 +237,8 @@
|
|
237 |
"premium": true,
|
238 |
"default": "N",
|
239 |
"type": "checkbox",
|
240 |
-
"link_info": "https://
|
241 |
-
"link_blog": "https://
|
242 |
"name": "Enable White Label",
|
243 |
"summary": "Activate Your White Label Settings",
|
244 |
"description": "Use this option to turn on/off the whole White Label feature."
|
@@ -260,7 +260,7 @@
|
|
260 |
"sensitive": true,
|
261 |
"default": "Shield",
|
262 |
"type": "text",
|
263 |
-
"link_info": "https://
|
264 |
"link_blog": "",
|
265 |
"name": "Plugin Name",
|
266 |
"summary": "The Name Of The Plugin",
|
@@ -282,9 +282,9 @@
|
|
282 |
"key": "wl_companyname",
|
283 |
"section": "section_whitelabel",
|
284 |
"sensitive": true,
|
285 |
-
"default": "
|
286 |
"type": "text",
|
287 |
-
"link_info": "https://
|
288 |
"link_blog": "",
|
289 |
"name": "Company Name",
|
290 |
"summary": "The Name Of Your Company",
|
@@ -306,7 +306,7 @@
|
|
306 |
"key": "wl_homeurl",
|
307 |
"section": "section_whitelabel",
|
308 |
"sensitive": true,
|
309 |
-
"default": "https://
|
310 |
"type": "text",
|
311 |
"link_info": "",
|
312 |
"link_blog": "",
|
@@ -320,7 +320,7 @@
|
|
320 |
"sensitive": true,
|
321 |
"default": "pluginlogo_16x16.png",
|
322 |
"type": "text",
|
323 |
-
"link_info": "https://
|
324 |
"link_blog": "",
|
325 |
"name": "Menu Icon",
|
326 |
"summary": "Menu Icon URL",
|
@@ -344,7 +344,7 @@
|
|
344 |
"sensitive": true,
|
345 |
"default": "pluginlogo_banner-772x250.png",
|
346 |
"type": "text",
|
347 |
-
"link_info": "https://
|
348 |
"link_blog": "",
|
349 |
"name": "Dashboard Logo",
|
350 |
"summary": "Dashboard Logo URL",
|
@@ -381,6 +381,7 @@
|
|
381 |
"siteurl",
|
382 |
"home",
|
383 |
"admin_email",
|
|
|
384 |
"users_can_register",
|
385 |
"comments_notify",
|
386 |
"comment_moderation",
|
82 |
"section": "section_enable_plugin_feature_admin_access_restriction",
|
83 |
"default": "Y",
|
84 |
"type": "checkbox",
|
85 |
+
"link_info": "https://shsec.io/40",
|
86 |
+
"link_blog": "https://shsec.io/wpsf02",
|
87 |
"name": "Enable Security Admin",
|
88 |
"summary": "Enforce Security Admin Access Restriction",
|
89 |
"description": "Enable this with great care and consideration. When this Access Key option is enabled, you must specify a key below and use it to gain access to this plugin."
|
94 |
"sensitive": true,
|
95 |
"default": "",
|
96 |
"type": "password",
|
97 |
+
"link_info": "https://shsec.io/42",
|
98 |
"link_blog": "",
|
99 |
"name": "Security Admin Access Key",
|
100 |
"summary": "Provide/Update Security Admin Access Key",
|
107 |
"premium": true,
|
108 |
"default": "",
|
109 |
"type": "array",
|
110 |
+
"link_info": "https://shsec.io/dk",
|
111 |
"link_blog": "",
|
112 |
"name": "Security Admins",
|
113 |
"summary": "Persistent Security Admins",
|
119 |
"default": 30,
|
120 |
"type": "integer",
|
121 |
"min": 1,
|
122 |
+
"link_info": "https://shsec.io/41",
|
123 |
"link_blog": "",
|
124 |
"name": "Security Admin Timeout",
|
125 |
"summary": "Specify An Automatic Timeout Interval For Security Admin Access",
|
130 |
"section": "section_admin_access_restriction_areas",
|
131 |
"default": "Y",
|
132 |
"type": "checkbox",
|
133 |
+
"link_info": "https://shsec.io/a0",
|
134 |
+
"link_blog": "https://shsec.io/wpsf32",
|
135 |
"name": "Pages",
|
136 |
"summary": "Restrict Access To Key WordPress Posts And Pages Actions",
|
137 |
"description": "Careful: This will restrict access to page/post creation, editing and deletion. Note: Selecting 'Edit' will also restrict all other options."
|
141 |
"section": "section_admin_access_restriction_areas",
|
142 |
"default": "N",
|
143 |
"type": "checkbox",
|
144 |
+
"link_info": "https://shsec.io/a0",
|
145 |
"link_blog": "",
|
146 |
"name": "Admin Users",
|
147 |
"summary": "Restrict Access To Create/Delete/Modify Other Admin Users",
|
170 |
"text": "Delete"
|
171 |
}
|
172 |
],
|
173 |
+
"link_info": "https://shsec.io/a0",
|
174 |
+
"link_blog": "https://shsec.io/wpsf21",
|
175 |
"summary": "Restrict Access To Key WordPress Plugin Actions",
|
176 |
"description": "Careful: This will restrict access to plugin installation, update, activation and deletion. Note: Selecting 'Activate' will also restrict all other options."
|
177 |
},
|
202 |
"text": "Delete"
|
203 |
}
|
204 |
],
|
205 |
+
"link_info": "https://shsec.io/a0",
|
206 |
+
"link_blog": "https://shsec.io/wpsf21",
|
207 |
"summary": "Restrict Access To WordPress Theme Actions",
|
208 |
"description": "Careful: This will restrict access to theme installation, update, activation and deletion."
|
209 |
},
|
226 |
"text": "Delete"
|
227 |
}
|
228 |
],
|
229 |
+
"link_info": "https://shsec.io/a0",
|
230 |
+
"link_blog": "https://shsec.io/wpsf21",
|
231 |
"summary": "Restrict Access To Key WordPress Posts And Pages Actions",
|
232 |
"description": "Careful: This will restrict access to page/post creation, editing and deletion."
|
233 |
},
|
237 |
"premium": true,
|
238 |
"default": "N",
|
239 |
"type": "checkbox",
|
240 |
+
"link_info": "https://shsec.io/dr",
|
241 |
+
"link_blog": "https://shsec.io/ds",
|
242 |
"name": "Enable White Label",
|
243 |
"summary": "Activate Your White Label Settings",
|
244 |
"description": "Use this option to turn on/off the whole White Label feature."
|
260 |
"sensitive": true,
|
261 |
"default": "Shield",
|
262 |
"type": "text",
|
263 |
+
"link_info": "https://shsec.io/dt",
|
264 |
"link_blog": "",
|
265 |
"name": "Plugin Name",
|
266 |
"summary": "The Name Of The Plugin",
|
282 |
"key": "wl_companyname",
|
283 |
"section": "section_whitelabel",
|
284 |
"sensitive": true,
|
285 |
+
"default": "Example Company Name",
|
286 |
"type": "text",
|
287 |
+
"link_info": "https://shsec.io/dt",
|
288 |
"link_blog": "",
|
289 |
"name": "Company Name",
|
290 |
"summary": "The Name Of Your Company",
|
306 |
"key": "wl_homeurl",
|
307 |
"section": "section_whitelabel",
|
308 |
"sensitive": true,
|
309 |
+
"default": "https://shsec.io/7f",
|
310 |
"type": "text",
|
311 |
"link_info": "",
|
312 |
"link_blog": "",
|
320 |
"sensitive": true,
|
321 |
"default": "pluginlogo_16x16.png",
|
322 |
"type": "text",
|
323 |
+
"link_info": "https://shsec.io/dt",
|
324 |
"link_blog": "",
|
325 |
"name": "Menu Icon",
|
326 |
"summary": "Menu Icon URL",
|
344 |
"sensitive": true,
|
345 |
"default": "pluginlogo_banner-772x250.png",
|
346 |
"type": "text",
|
347 |
+
"link_info": "https://shsec.io/dt",
|
348 |
"link_blog": "",
|
349 |
"name": "Dashboard Logo",
|
350 |
"summary": "Dashboard Logo URL",
|
381 |
"siteurl",
|
382 |
"home",
|
383 |
"admin_email",
|
384 |
+
"new_admin_email",
|
385 |
"users_can_register",
|
386 |
"comments_notify",
|
387 |
"comment_moderation",
|
src/config/feature-audit_trail.php
CHANGED
@@ -65,8 +65,8 @@
|
|
65 |
"section": "section_enable_plugin_feature_audit_trail",
|
66 |
"default": "Y",
|
67 |
"type": "checkbox",
|
68 |
-
"link_info": "https://
|
69 |
-
"link_blog": "https://
|
70 |
"name": "Enable Audit Trail",
|
71 |
"summary": "Enable (or Disable) The Audit Trail module",
|
72 |
"description": "Un-Checking this option will completely disable the Audit Trail module"
|
@@ -77,8 +77,8 @@
|
|
77 |
"default": 14,
|
78 |
"min": 1,
|
79 |
"type": "integer",
|
80 |
-
"link_info": "https://
|
81 |
-
"link_blog": "https://
|
82 |
"name": "Auto Clean",
|
83 |
"summary": "Enable Audit Auto Cleaning",
|
84 |
"description": "Events older than the number of days specified will be automatically cleaned from the database"
|
@@ -101,8 +101,8 @@
|
|
101 |
"section": "section_enable_audit_contexts",
|
102 |
"default": "Y",
|
103 |
"type": "checkbox",
|
104 |
-
"link_info": "https://
|
105 |
-
"link_blog": "https://
|
106 |
"name": "Users And Logins",
|
107 |
"summary": "Enable Audit Context - Users And Logins",
|
108 |
"description": "When this context is enabled, the audit trail will track activity relating to: Users And Logins"
|
@@ -112,8 +112,8 @@
|
|
112 |
"section": "section_enable_audit_contexts",
|
113 |
"default": "Y",
|
114 |
"type": "checkbox",
|
115 |
-
"link_info": "https://
|
116 |
-
"link_blog": "https://
|
117 |
"name": "Plugins",
|
118 |
"summary": "Enable Audit Context - Plugins",
|
119 |
"description": "When this context is enabled, the audit trail will track activity relating to: WordPress Plugins"
|
@@ -123,8 +123,8 @@
|
|
123 |
"section": "section_enable_audit_contexts",
|
124 |
"default": "Y",
|
125 |
"type": "checkbox",
|
126 |
-
"link_info": "https://
|
127 |
-
"link_blog": "https://
|
128 |
"name": "Themes",
|
129 |
"summary": "Enable Audit Context - Themes",
|
130 |
"description": "When this context is enabled, the audit trail will track activity relating to: WordPress Themes"
|
@@ -134,8 +134,8 @@
|
|
134 |
"section": "section_enable_audit_contexts",
|
135 |
"default": "Y",
|
136 |
"type": "checkbox",
|
137 |
-
"link_info": "https://
|
138 |
-
"link_blog": "https://
|
139 |
"name": "Posts And Pages",
|
140 |
"summary": "Enable Audit Context - Posts And Pages",
|
141 |
"description": "When this context is enabled, the audit trail will track activity relating to: Editing and publishing of posts and pages"
|
@@ -145,8 +145,8 @@
|
|
145 |
"section": "section_enable_audit_contexts",
|
146 |
"default": "Y",
|
147 |
"type": "checkbox",
|
148 |
-
"link_info": "https://
|
149 |
-
"link_blog": "https://
|
150 |
"name": "WordPress And Settings",
|
151 |
"summary": "Enable Audit Context - WordPress And Settings",
|
152 |
"description": "When this context is enabled, the audit trail will track activity relating to: WordPress upgrades and changes to particular WordPress settings"
|
@@ -156,8 +156,8 @@
|
|
156 |
"section": "section_enable_audit_contexts",
|
157 |
"default": "Y",
|
158 |
"type": "checkbox",
|
159 |
-
"link_info": "https://
|
160 |
-
"link_blog": "https://
|
161 |
"name": "Emails",
|
162 |
"summary": "Enable Audit Context - Emails",
|
163 |
"description": "When this context is enabled, the audit trail will track activity relating to: Email Sending"
|
@@ -167,8 +167,8 @@
|
|
167 |
"section": "section_enable_audit_contexts",
|
168 |
"default": "Y",
|
169 |
"type": "checkbox",
|
170 |
-
"link_info": "https://
|
171 |
-
"link_blog": "https://
|
172 |
"name": "Shield",
|
173 |
"summary": "Enable Audit Context - Shield",
|
174 |
"description": "When this context is enabled, the audit trail will track activity relating to: Shield"
|
65 |
"section": "section_enable_plugin_feature_audit_trail",
|
66 |
"default": "Y",
|
67 |
"type": "checkbox",
|
68 |
+
"link_info": "https://shsec.io/5p",
|
69 |
+
"link_blog": "https://shsec.io/a1",
|
70 |
"name": "Enable Audit Trail",
|
71 |
"summary": "Enable (or Disable) The Audit Trail module",
|
72 |
"description": "Un-Checking this option will completely disable the Audit Trail module"
|
77 |
"default": 14,
|
78 |
"min": 1,
|
79 |
"type": "integer",
|
80 |
+
"link_info": "https://shsec.io/a2",
|
81 |
+
"link_blog": "https://shsec.io/a1",
|
82 |
"name": "Auto Clean",
|
83 |
"summary": "Enable Audit Auto Cleaning",
|
84 |
"description": "Events older than the number of days specified will be automatically cleaned from the database"
|
101 |
"section": "section_enable_audit_contexts",
|
102 |
"default": "Y",
|
103 |
"type": "checkbox",
|
104 |
+
"link_info": "https://shsec.io/a3",
|
105 |
+
"link_blog": "https://shsec.io/a1",
|
106 |
"name": "Users And Logins",
|
107 |
"summary": "Enable Audit Context - Users And Logins",
|
108 |
"description": "When this context is enabled, the audit trail will track activity relating to: Users And Logins"
|
112 |
"section": "section_enable_audit_contexts",
|
113 |
"default": "Y",
|
114 |
"type": "checkbox",
|
115 |
+
"link_info": "https://shsec.io/a3",
|
116 |
+
"link_blog": "https://shsec.io/a1",
|
117 |
"name": "Plugins",
|
118 |
"summary": "Enable Audit Context - Plugins",
|
119 |
"description": "When this context is enabled, the audit trail will track activity relating to: WordPress Plugins"
|
123 |
"section": "section_enable_audit_contexts",
|
124 |
"default": "Y",
|
125 |
"type": "checkbox",
|
126 |
+
"link_info": "https://shsec.io/a3",
|
127 |
+
"link_blog": "https://shsec.io/a1",
|
128 |
"name": "Themes",
|
129 |
"summary": "Enable Audit Context - Themes",
|
130 |
"description": "When this context is enabled, the audit trail will track activity relating to: WordPress Themes"
|
134 |
"section": "section_enable_audit_contexts",
|
135 |
"default": "Y",
|
136 |
"type": "checkbox",
|
137 |
+
"link_info": "https://shsec.io/a3",
|
138 |
+
"link_blog": "https://shsec.io/a1",
|
139 |
"name": "Posts And Pages",
|
140 |
"summary": "Enable Audit Context - Posts And Pages",
|
141 |
"description": "When this context is enabled, the audit trail will track activity relating to: Editing and publishing of posts and pages"
|
145 |
"section": "section_enable_audit_contexts",
|
146 |
"default": "Y",
|
147 |
"type": "checkbox",
|
148 |
+
"link_info": "https://shsec.io/a3",
|
149 |
+
"link_blog": "https://shsec.io/a1",
|
150 |
"name": "WordPress And Settings",
|
151 |
"summary": "Enable Audit Context - WordPress And Settings",
|
152 |
"description": "When this context is enabled, the audit trail will track activity relating to: WordPress upgrades and changes to particular WordPress settings"
|
156 |
"section": "section_enable_audit_contexts",
|
157 |
"default": "Y",
|
158 |
"type": "checkbox",
|
159 |
+
"link_info": "https://shsec.io/a3",
|
160 |
+
"link_blog": "https://shsec.io/a1",
|
161 |
"name": "Emails",
|
162 |
"summary": "Enable Audit Context - Emails",
|
163 |
"description": "When this context is enabled, the audit trail will track activity relating to: Email Sending"
|
167 |
"section": "section_enable_audit_contexts",
|
168 |
"default": "Y",
|
169 |
"type": "checkbox",
|
170 |
+
"link_info": "https://shsec.io/a4",
|
171 |
+
"link_blog": "https://shsec.io/a1",
|
172 |
"name": "Shield",
|
173 |
"summary": "Enable Audit Context - Shield",
|
174 |
"description": "When this context is enabled, the audit trail will track activity relating to: Shield"
|
src/config/feature-autoupdates.php
CHANGED
@@ -52,7 +52,7 @@
|
|
52 |
"section": "section_enable_plugin_feature_automatic_updates_control",
|
53 |
"default": "Y",
|
54 |
"type": "checkbox",
|
55 |
-
"link_info": "https://
|
56 |
"link_blog": "",
|
57 |
"name": "Enable Automatic Updates",
|
58 |
"summary": "Enable (or Disable) The Automatic Updates module",
|
@@ -63,7 +63,7 @@
|
|
63 |
"section": "section_automatic_updates_for_wordpress_components",
|
64 |
"default": "N",
|
65 |
"type": "checkbox",
|
66 |
-
"link_info": "https://
|
67 |
"link_blog": "",
|
68 |
"name": "Disable All",
|
69 |
"summary": "Completely Disable WordPress Automatic Updates",
|
@@ -88,7 +88,7 @@
|
|
88 |
"text": "Major and Minor Versions"
|
89 |
}
|
90 |
],
|
91 |
-
"link_info": "https://
|
92 |
"link_blog": "",
|
93 |
"name": "WordPress Core Updates",
|
94 |
"summary": "Decide how the WordPress Core will automatically update, if at all",
|
@@ -156,7 +156,7 @@
|
|
156 |
"premium": true,
|
157 |
"default": "0",
|
158 |
"type": "integer",
|
159 |
-
"link_info": "https://
|
160 |
"link_blog": "",
|
161 |
"name": "Update Delay",
|
162 |
"summary": "Delay Automatic Updates For Period Of Stability",
|
@@ -181,7 +181,7 @@
|
|
181 |
"text": "As Soon As Possible"
|
182 |
}
|
183 |
],
|
184 |
-
"link_info": "https://
|
185 |
"link_blog": "",
|
186 |
"name": "WordPress Core Updates",
|
187 |
"summary": "Decide how the WordPress Core will automatically update, if at all",
|
52 |
"section": "section_enable_plugin_feature_automatic_updates_control",
|
53 |
"default": "Y",
|
54 |
"type": "checkbox",
|
55 |
+
"link_info": "https://shsec.io/3w",
|
56 |
"link_blog": "",
|
57 |
"name": "Enable Automatic Updates",
|
58 |
"summary": "Enable (or Disable) The Automatic Updates module",
|
63 |
"section": "section_automatic_updates_for_wordpress_components",
|
64 |
"default": "N",
|
65 |
"type": "checkbox",
|
66 |
+
"link_info": "https://shsec.io/3v",
|
67 |
"link_blog": "",
|
68 |
"name": "Disable All",
|
69 |
"summary": "Completely Disable WordPress Automatic Updates",
|
88 |
"text": "Major and Minor Versions"
|
89 |
}
|
90 |
],
|
91 |
+
"link_info": "https://shsec.io/3x",
|
92 |
"link_blog": "",
|
93 |
"name": "WordPress Core Updates",
|
94 |
"summary": "Decide how the WordPress Core will automatically update, if at all",
|
156 |
"premium": true,
|
157 |
"default": "0",
|
158 |
"type": "integer",
|
159 |
+
"link_info": "https://shsec.io/e5",
|
160 |
"link_blog": "",
|
161 |
"name": "Update Delay",
|
162 |
"summary": "Delay Automatic Updates For Period Of Stability",
|
181 |
"text": "As Soon As Possible"
|
182 |
}
|
183 |
],
|
184 |
+
"link_info": "https://shsec.io/3x",
|
185 |
"link_blog": "",
|
186 |
"name": "WordPress Core Updates",
|
187 |
"summary": "Decide how the WordPress Core will automatically update, if at all",
|
src/config/feature-comments_filter.php
CHANGED
@@ -92,8 +92,8 @@
|
|
92 |
"section": "section_enable_plugin_feature_spam_comments_protection_filter",
|
93 |
"default": "Y",
|
94 |
"type": "checkbox",
|
95 |
-
"link_info": "https://
|
96 |
-
"link_blog": "https://
|
97 |
"name": "Enable SPAM Protection",
|
98 |
"summary": "Enable (or Disable) The Comments SPAM Protection module",
|
99 |
"description": "Un-Checking this option will completely disable the Comments SPAM Protection module"
|
@@ -104,7 +104,7 @@
|
|
104 |
"default": 1,
|
105 |
"min": 1,
|
106 |
"type": "integer",
|
107 |
-
"link_info": "https://
|
108 |
"link_blog": "",
|
109 |
"name": "Trusted Commenter Minimum",
|
110 |
"summary": "Minimum Number Of Approved Comments Before Commenter Is Trusted",
|
@@ -122,7 +122,7 @@
|
|
122 |
"subscriber"
|
123 |
],
|
124 |
"type": "array",
|
125 |
-
"link_info": "https://
|
126 |
"link_blog": "",
|
127 |
"name": "Trusted Users",
|
128 |
"summary": "Don't Scan Comments For Users With The Following Roles",
|
@@ -133,8 +133,8 @@
|
|
133 |
"section": "section_bot_comment_spam_protection_filter",
|
134 |
"default": "N",
|
135 |
"type": "checkbox",
|
136 |
-
"link_info": "https://
|
137 |
-
"link_blog": "https://
|
138 |
"name": "GASP Protection",
|
139 |
"summary": "Block Bot Comment SPAM",
|
140 |
"description": "Taking the lead from the original GASP plugin for WordPress, we have extended it to include advanced spam-bot protection."
|
@@ -145,7 +145,7 @@
|
|
145 |
"default": 10,
|
146 |
"min": 0,
|
147 |
"type": "integer",
|
148 |
-
"link_info": "https://
|
149 |
"link_blog": "",
|
150 |
"name": "Comments Cooldown",
|
151 |
"summary": "Limit posting comments to X seconds after the page has loaded",
|
@@ -174,7 +174,7 @@
|
|
174 |
"text": "Block And Redirect"
|
175 |
}
|
176 |
],
|
177 |
-
"link_info": "https://
|
178 |
"link_blog": "",
|
179 |
"name": "Default SPAM Action",
|
180 |
"summary": "How To Categorise Comments When Identified To Be SPAM",
|
@@ -185,8 +185,8 @@
|
|
185 |
"section": "section_human_spam_filter",
|
186 |
"default": "N",
|
187 |
"type": "checkbox",
|
188 |
-
"link_info": "https://
|
189 |
-
"link_blog": "https://
|
190 |
"name": "Human SPAM Filter",
|
191 |
"summary": "Enable (or Disable) The Human SPAM Filter module",
|
192 |
"description": "Scans the content of WordPress comments for keywords that are indicative of SPAM and marks the comment according to your preferred setting below."
|
@@ -229,7 +229,7 @@
|
|
229 |
"text": "Browser User Agent"
|
230 |
}
|
231 |
],
|
232 |
-
"link_info": "https://
|
233 |
"link_blog": "",
|
234 |
"name": "Comment Filter Items",
|
235 |
"summary": "Select The Items To Scan For SPAM",
|
@@ -267,7 +267,7 @@
|
|
267 |
"section": "section_recaptcha",
|
268 |
"default": "N",
|
269 |
"type": "checkbox",
|
270 |
-
"link_info": "https://
|
271 |
"link_blog": "",
|
272 |
"name": "Google reCAPTCHA",
|
273 |
"summary": "Enable Google reCAPTCHA For Comments",
|
@@ -297,7 +297,7 @@
|
|
297 |
"text": "Invisible"
|
298 |
}
|
299 |
],
|
300 |
-
"link_info": "https://
|
301 |
"link_blog": "",
|
302 |
"name": "reCAPTCHA Style",
|
303 |
"summary": "How Google reCAPTCHA Will Be Displayed",
|
@@ -309,8 +309,8 @@
|
|
309 |
"default": 600,
|
310 |
"min": 0,
|
311 |
"type": "integer",
|
312 |
-
"link_info": "https://
|
313 |
-
"link_blog": "https://
|
314 |
"name": "Comment Token Expire",
|
315 |
"summary": "A visitor has X seconds within which to post a comment",
|
316 |
"description": "Default: 600 seconds (10 minutes). Each visitor is given a unique 'Token' so they can comment. This restricts spambots, but we need to force these tokens to expire and at the same time not bother the visitors."
|
@@ -321,7 +321,7 @@
|
|
321 |
"sensitive": true,
|
322 |
"default": "default",
|
323 |
"type": "text",
|
324 |
-
"link_info": "https://
|
325 |
"link_blog": "",
|
326 |
"name": "Custom Checkbox Message",
|
327 |
"summary": "If you want a custom checkbox message, please provide this here",
|
@@ -333,7 +333,7 @@
|
|
333 |
"sensitive": true,
|
334 |
"default": "default",
|
335 |
"type": "text",
|
336 |
-
"link_info": "https://
|
337 |
"link_blog": "",
|
338 |
"name": "Custom Alert Message",
|
339 |
"summary": "If you want a custom alert message, please provide this here",
|
@@ -345,7 +345,7 @@
|
|
345 |
"sensitive": true,
|
346 |
"default": "default",
|
347 |
"type": "text",
|
348 |
-
"link_info": "https://
|
349 |
"link_blog": "",
|
350 |
"name": "Custom Wait Message",
|
351 |
"summary": "If you want a custom submit-button wait message, please provide this here.",
|
@@ -357,7 +357,7 @@
|
|
357 |
"sensitive": true,
|
358 |
"default": "default",
|
359 |
"type": "text",
|
360 |
-
"link_info": "https://
|
361 |
"link_blog": "",
|
362 |
"name": "Custom Reload Message",
|
363 |
"summary": "If you want a custom message when the comment token has expired, please provide this here.",
|
92 |
"section": "section_enable_plugin_feature_spam_comments_protection_filter",
|
93 |
"default": "Y",
|
94 |
"type": "checkbox",
|
95 |
+
"link_info": "https://shsec.io/3z",
|
96 |
+
"link_blog": "https://shsec.io/wpsf04",
|
97 |
"name": "Enable SPAM Protection",
|
98 |
"summary": "Enable (or Disable) The Comments SPAM Protection module",
|
99 |
"description": "Un-Checking this option will completely disable the Comments SPAM Protection module"
|
104 |
"default": 1,
|
105 |
"min": 1,
|
106 |
"type": "integer",
|
107 |
+
"link_info": "https://shsec.io/fu",
|
108 |
"link_blog": "",
|
109 |
"name": "Trusted Commenter Minimum",
|
110 |
"summary": "Minimum Number Of Approved Comments Before Commenter Is Trusted",
|
122 |
"subscriber"
|
123 |
],
|
124 |
"type": "array",
|
125 |
+
"link_info": "https://shsec.io/fu",
|
126 |
"link_blog": "",
|
127 |
"name": "Trusted Users",
|
128 |
"summary": "Don't Scan Comments For Users With The Following Roles",
|
133 |
"section": "section_bot_comment_spam_protection_filter",
|
134 |
"default": "N",
|
135 |
"type": "checkbox",
|
136 |
+
"link_info": "https://shsec.io/3n",
|
137 |
+
"link_blog": "https://shsec.io/2n",
|
138 |
"name": "GASP Protection",
|
139 |
"summary": "Block Bot Comment SPAM",
|
140 |
"description": "Taking the lead from the original GASP plugin for WordPress, we have extended it to include advanced spam-bot protection."
|
145 |
"default": 10,
|
146 |
"min": 0,
|
147 |
"type": "integer",
|
148 |
+
"link_info": "https://shsec.io/3o",
|
149 |
"link_blog": "",
|
150 |
"name": "Comments Cooldown",
|
151 |
"summary": "Limit posting comments to X seconds after the page has loaded",
|
174 |
"text": "Block And Redirect"
|
175 |
}
|
176 |
],
|
177 |
+
"link_info": "https://shsec.io/6j",
|
178 |
"link_blog": "",
|
179 |
"name": "Default SPAM Action",
|
180 |
"summary": "How To Categorise Comments When Identified To Be SPAM",
|
185 |
"section": "section_human_spam_filter",
|
186 |
"default": "N",
|
187 |
"type": "checkbox",
|
188 |
+
"link_info": "https://shsec.io/57",
|
189 |
+
"link_blog": "https://shsec.io/9w",
|
190 |
"name": "Human SPAM Filter",
|
191 |
"summary": "Enable (or Disable) The Human SPAM Filter module",
|
192 |
"description": "Scans the content of WordPress comments for keywords that are indicative of SPAM and marks the comment according to your preferred setting below."
|
229 |
"text": "Browser User Agent"
|
230 |
}
|
231 |
],
|
232 |
+
"link_info": "https://shsec.io/58",
|
233 |
"link_blog": "",
|
234 |
"name": "Comment Filter Items",
|
235 |
"summary": "Select The Items To Scan For SPAM",
|
267 |
"section": "section_recaptcha",
|
268 |
"default": "N",
|
269 |
"type": "checkbox",
|
270 |
+
"link_info": "https://shsec.io/shld5",
|
271 |
"link_blog": "",
|
272 |
"name": "Google reCAPTCHA",
|
273 |
"summary": "Enable Google reCAPTCHA For Comments",
|
297 |
"text": "Invisible"
|
298 |
}
|
299 |
],
|
300 |
+
"link_info": "https://shsec.io/e4",
|
301 |
"link_blog": "",
|
302 |
"name": "reCAPTCHA Style",
|
303 |
"summary": "How Google reCAPTCHA Will Be Displayed",
|
309 |
"default": 600,
|
310 |
"min": 0,
|
311 |
"type": "integer",
|
312 |
+
"link_info": "https://shsec.io/3o",
|
313 |
+
"link_blog": "https://shsec.io/9v",
|
314 |
"name": "Comment Token Expire",
|
315 |
"summary": "A visitor has X seconds within which to post a comment",
|
316 |
"description": "Default: 600 seconds (10 minutes). Each visitor is given a unique 'Token' so they can comment. This restricts spambots, but we need to force these tokens to expire and at the same time not bother the visitors."
|
321 |
"sensitive": true,
|
322 |
"default": "default",
|
323 |
"type": "text",
|
324 |
+
"link_info": "https://shsec.io/3p",
|
325 |
"link_blog": "",
|
326 |
"name": "Custom Checkbox Message",
|
327 |
"summary": "If you want a custom checkbox message, please provide this here",
|
333 |
"sensitive": true,
|
334 |
"default": "default",
|
335 |
"type": "text",
|
336 |
+
"link_info": "https://shsec.io/3p",
|
337 |
"link_blog": "",
|
338 |
"name": "Custom Alert Message",
|
339 |
"summary": "If you want a custom alert message, please provide this here",
|
345 |
"sensitive": true,
|
346 |
"default": "default",
|
347 |
"type": "text",
|
348 |
+
"link_info": "https://shsec.io/3p",
|
349 |
"link_blog": "",
|
350 |
"name": "Custom Wait Message",
|
351 |
"summary": "If you want a custom submit-button wait message, please provide this here.",
|
357 |
"sensitive": true,
|
358 |
"default": "default",
|
359 |
"type": "text",
|
360 |
+
"link_info": "https://shsec.io/3p",
|
361 |
"link_blog": "",
|
362 |
"name": "Custom Reload Message",
|
363 |
"summary": "If you want a custom message when the comment token has expired, please provide this here.",
|
src/config/feature-firewall.php
CHANGED
@@ -74,8 +74,8 @@
|
|
74 |
"section": "section_enable_plugin_feature_wordpress_firewall",
|
75 |
"default": "Y",
|
76 |
"type": "checkbox",
|
77 |
-
"link_info": "https://
|
78 |
-
"link_blog": "https://
|
79 |
"name": "Enable Firewall",
|
80 |
"summary": "Enable (or Disable) The Firewall module",
|
81 |
"description": "Un-Checking this option will completely disable the Firewall module"
|
@@ -224,7 +224,7 @@
|
|
224 |
"section": "section_whitelist",
|
225 |
"default": "",
|
226 |
"type": "comma_separated_lists",
|
227 |
-
"link_info": "https://
|
228 |
"link_blog": "",
|
229 |
"name": "Whitelist Parameters",
|
230 |
"summary": "Detail pages and parameters that are whitelisted (ignored by the firewall)",
|
74 |
"section": "section_enable_plugin_feature_wordpress_firewall",
|
75 |
"default": "Y",
|
76 |
"type": "checkbox",
|
77 |
+
"link_info": "https://shsec.io/43",
|
78 |
+
"link_blog": "https://shsec.io/wpsf01",
|
79 |
"name": "Enable Firewall",
|
80 |
"summary": "Enable (or Disable) The Firewall module",
|
81 |
"description": "Un-Checking this option will completely disable the Firewall module"
|
224 |
"section": "section_whitelist",
|
225 |
"default": "",
|
226 |
"type": "comma_separated_lists",
|
227 |
+
"link_info": "https://shsec.io/2a",
|
228 |
"link_blog": "",
|
229 |
"name": "Whitelist Parameters",
|
230 |
"summary": "Detail pages and parameters that are whitelisted (ignored by the firewall)",
|
src/config/feature-hack_protect.php
CHANGED
@@ -138,8 +138,8 @@
|
|
138 |
"section": "section_enable_plugin_feature_hack_protection_tools",
|
139 |
"default": "Y",
|
140 |
"type": "checkbox",
|
141 |
-
"link_info": "https://
|
142 |
-
"link_blog": "https://
|
143 |
"name": "Enable Hack Guard",
|
144 |
"summary": "Enable (or Disable) The Hack Guard Module",
|
145 |
"description": "Un-Checking this option will completely disable the Hack Guard module"
|
@@ -176,8 +176,8 @@
|
|
176 |
"text": "Scan Enabled - No Email Notification"
|
177 |
}
|
178 |
],
|
179 |
-
"link_info": "https://
|
180 |
-
"link_blog": "https://
|
181 |
"name": "Vulnerability Scanner",
|
182 |
"summary": "Enable The Vulnerability Scanner",
|
183 |
"description": "Scan all your WordPress assets for known security vulnerabilities."
|
@@ -239,8 +239,8 @@
|
|
239 |
"text": "Scan Enabled - No Email Notification"
|
240 |
}
|
241 |
],
|
242 |
-
"link_info": "https://
|
243 |
-
"link_blog": "https://
|
244 |
"name": "Abandoned Plugin Scanner",
|
245 |
"summary": "Enable The Abandoned Plugin Scanner",
|
246 |
"description": "Scan your WordPress.org assets for whether they've been abandoned."
|
@@ -250,8 +250,8 @@
|
|
250 |
"section": "section_scan_wcf",
|
251 |
"default": "Y",
|
252 |
"type": "checkbox",
|
253 |
-
"link_info": "https://
|
254 |
-
"link_blog": "https://
|
255 |
"name": "WP Core File Scanner",
|
256 |
"summary": "Automatically Scans WordPress Core Files For Alterations",
|
257 |
"description": "Compares all WordPress core files on your site against the official WordPress files. WordPress Core files should never be altered for any reason."
|
@@ -261,8 +261,8 @@
|
|
261 |
"section": "section_scan_wcf",
|
262 |
"default": "N",
|
263 |
"type": "checkbox",
|
264 |
-
"link_info": "https://
|
265 |
-
"link_blog": "https://
|
266 |
"name": "Auto Repair",
|
267 |
"summary": "Automatically Repair WordPress Core Files That Have Been Altered",
|
268 |
"description": "Attempts to automatically repair WordPress Core files with the official WordPress file data, for files that have been altered or are missing."
|
@@ -307,7 +307,7 @@
|
|
307 |
"text": "24 Times (scan every hour)"
|
308 |
}
|
309 |
],
|
310 |
-
"link_info": "https://
|
311 |
"link_blog": "",
|
312 |
"name": "Scan Frequency",
|
313 |
"summary": "Number Of Times To Automatically Scan Core Files In 24 Hours",
|
@@ -361,8 +361,8 @@
|
|
361 |
"text": "Scan Enabled - Delete Files and Send Email Notification"
|
362 |
}
|
363 |
],
|
364 |
-
"link_info": "https://
|
365 |
-
"link_blog": "https://
|
366 |
"name": "Unrecognised Files Scanner",
|
367 |
"summary": "Scans Core Directories For Unrecognised Files",
|
368 |
"description": "Scans for, and automatically deletes, any files in your core WordPress folders that are not part of your WordPress installation."
|
@@ -372,7 +372,7 @@
|
|
372 |
"section": "section_scan_ufc",
|
373 |
"default": "N",
|
374 |
"type": "checkbox",
|
375 |
-
"link_info": "https://
|
376 |
"link_blog": "",
|
377 |
"name": "Scan Uploads",
|
378 |
"summary": "Scan Uploads Folder For PHP and Javascript",
|
@@ -392,8 +392,8 @@
|
|
392 |
"mail.log"
|
393 |
],
|
394 |
"type": "array",
|
395 |
-
"link_info": "https://
|
396 |
-
"link_blog": "https://
|
397 |
"name": "File Exclusions",
|
398 |
"summary": "Provide A List Of Files To Be Excluded From The Scan",
|
399 |
"description": "Take a new line for each file you wish to exclude from the scan. No commas are necessary."
|
@@ -436,8 +436,8 @@
|
|
436 |
"text": "Automatic Scan Enabled"
|
437 |
}
|
438 |
],
|
439 |
-
"link_info": "https://
|
440 |
-
"link_blog": "https://
|
441 |
"name": "Automatic Malware Scan",
|
442 |
"summary": "Enable Malware File Scanner",
|
443 |
"description": "When enabled the Malware scanner will run automatically."
|
@@ -470,8 +470,8 @@
|
|
470 |
"text": "Full"
|
471 |
}
|
472 |
],
|
473 |
-
"link_info": "https://
|
474 |
-
"link_blog": "https://
|
475 |
"name": "Automatic Malware Scan",
|
476 |
"summary": "Enable Malware File Scanner",
|
477 |
"description": "When enabled the Malware scanner will run automatically."
|
@@ -528,8 +528,8 @@
|
|
528 |
"text": "Scan Enabled"
|
529 |
}
|
530 |
],
|
531 |
-
"link_info": "https://
|
532 |
-
"link_blog": "https://
|
533 |
"name": "Enable/Disable Guard",
|
534 |
"summary": "Enable The Guard For Plugin And Theme Files",
|
535 |
"description": "When enabled the Guard will automatically scan for changes to your Plugin and Theme files."
|
@@ -541,8 +541,8 @@
|
|
541 |
"type": "integer",
|
542 |
"default": 1,
|
543 |
"min": 0,
|
544 |
-
"link_info": "https://
|
545 |
-
"link_blog": "https://
|
546 |
"name": "Guard/Scan Depth",
|
547 |
"summary": "How Deep Into The Plugin Directories To Scan And Guard",
|
548 |
"description": "The Guard normally operates scan only the top level of a plugin folder. Increasing depth increases scan times."
|
@@ -559,7 +559,7 @@
|
|
559 |
"htaccess"
|
560 |
],
|
561 |
"type": "array",
|
562 |
-
"link_info": "https://
|
563 |
"link_blog": "",
|
564 |
"name": "File Types",
|
565 |
"summary": "The File Types Included In The Scan",
|
@@ -571,7 +571,7 @@
|
|
571 |
"premium": true,
|
572 |
"type": "checkbox",
|
573 |
"default": "Y",
|
574 |
-
"link_info": "https://
|
575 |
"link_blog": "",
|
576 |
"name": "Show Re-Install Links",
|
577 |
"summary": "Show Re-Install Links For Plugins",
|
138 |
"section": "section_enable_plugin_feature_hack_protection_tools",
|
139 |
"default": "Y",
|
140 |
"type": "checkbox",
|
141 |
+
"link_info": "https://shsec.io/wpsf38",
|
142 |
+
"link_blog": "https://shsec.io/9x",
|
143 |
"name": "Enable Hack Guard",
|
144 |
"summary": "Enable (or Disable) The Hack Guard Module",
|
145 |
"description": "Un-Checking this option will completely disable the Hack Guard module"
|
176 |
"text": "Scan Enabled - No Email Notification"
|
177 |
}
|
178 |
],
|
179 |
+
"link_info": "https://shsec.io/du",
|
180 |
+
"link_blog": "https://shsec.io/ah",
|
181 |
"name": "Vulnerability Scanner",
|
182 |
"summary": "Enable The Vulnerability Scanner",
|
183 |
"description": "Scan all your WordPress assets for known security vulnerabilities."
|
239 |
"text": "Scan Enabled - No Email Notification"
|
240 |
}
|
241 |
],
|
242 |
+
"link_info": "https://shsec.io/ew",
|
243 |
+
"link_blog": "https://shsec.io/eo",
|
244 |
"name": "Abandoned Plugin Scanner",
|
245 |
"summary": "Enable The Abandoned Plugin Scanner",
|
246 |
"description": "Scan your WordPress.org assets for whether they've been abandoned."
|
250 |
"section": "section_scan_wcf",
|
251 |
"default": "Y",
|
252 |
"type": "checkbox",
|
253 |
+
"link_info": "https://shsec.io/wpsf36",
|
254 |
+
"link_blog": "https://shsec.io/wpsf37",
|
255 |
"name": "WP Core File Scanner",
|
256 |
"summary": "Automatically Scans WordPress Core Files For Alterations",
|
257 |
"description": "Compares all WordPress core files on your site against the official WordPress files. WordPress Core files should never be altered for any reason."
|
261 |
"section": "section_scan_wcf",
|
262 |
"default": "N",
|
263 |
"type": "checkbox",
|
264 |
+
"link_info": "https://shsec.io/wpsf36",
|
265 |
+
"link_blog": "https://shsec.io/wpsf37",
|
266 |
"name": "Auto Repair",
|
267 |
"summary": "Automatically Repair WordPress Core Files That Have Been Altered",
|
268 |
"description": "Attempts to automatically repair WordPress Core files with the official WordPress file data, for files that have been altered or are missing."
|
307 |
"text": "24 Times (scan every hour)"
|
308 |
}
|
309 |
],
|
310 |
+
"link_info": "https://shsec.io/b2",
|
311 |
"link_blog": "",
|
312 |
"name": "Scan Frequency",
|
313 |
"summary": "Number Of Times To Automatically Scan Core Files In 24 Hours",
|
361 |
"text": "Scan Enabled - Delete Files and Send Email Notification"
|
362 |
}
|
363 |
],
|
364 |
+
"link_info": "https://shsec.io/9y",
|
365 |
+
"link_blog": "https://shsec.io/95",
|
366 |
"name": "Unrecognised Files Scanner",
|
367 |
"summary": "Scans Core Directories For Unrecognised Files",
|
368 |
"description": "Scans for, and automatically deletes, any files in your core WordPress folders that are not part of your WordPress installation."
|
372 |
"section": "section_scan_ufc",
|
373 |
"default": "N",
|
374 |
"type": "checkbox",
|
375 |
+
"link_info": "https://shsec.io/95",
|
376 |
"link_blog": "",
|
377 |
"name": "Scan Uploads",
|
378 |
"summary": "Scan Uploads Folder For PHP and Javascript",
|
392 |
"mail.log"
|
393 |
],
|
394 |
"type": "array",
|
395 |
+
"link_info": "https://shsec.io/9z",
|
396 |
+
"link_blog": "https://shsec.io/95",
|
397 |
"name": "File Exclusions",
|
398 |
"summary": "Provide A List Of Files To Be Excluded From The Scan",
|
399 |
"description": "Take a new line for each file you wish to exclude from the scan. No commas are necessary."
|
436 |
"text": "Automatic Scan Enabled"
|
437 |
}
|
438 |
],
|
439 |
+
"link_info": "https://shsec.io/fp",
|
440 |
+
"link_blog": "https://shsec.io/fx",
|
441 |
"name": "Automatic Malware Scan",
|
442 |
"summary": "Enable Malware File Scanner",
|
443 |
"description": "When enabled the Malware scanner will run automatically."
|
470 |
"text": "Full"
|
471 |
}
|
472 |
],
|
473 |
+
"link_info": "https://shsec.io/fp",
|
474 |
+
"link_blog": "https://shsec.io/fz",
|
475 |
"name": "Automatic Malware Scan",
|
476 |
"summary": "Enable Malware File Scanner",
|
477 |
"description": "When enabled the Malware scanner will run automatically."
|
528 |
"text": "Scan Enabled"
|
529 |
}
|
530 |
],
|
531 |
+
"link_info": "https://shsec.io/bl",
|
532 |
+
"link_blog": "https://shsec.io/bm",
|
533 |
"name": "Enable/Disable Guard",
|
534 |
"summary": "Enable The Guard For Plugin And Theme Files",
|
535 |
"description": "When enabled the Guard will automatically scan for changes to your Plugin and Theme files."
|
541 |
"type": "integer",
|
542 |
"default": 1,
|
543 |
"min": 0,
|
544 |
+
"link_info": "https://shsec.io/bn",
|
545 |
+
"link_blog": "https://shsec.io/bm",
|
546 |
"name": "Guard/Scan Depth",
|
547 |
"summary": "How Deep Into The Plugin Directories To Scan And Guard",
|
548 |
"description": "The Guard normally operates scan only the top level of a plugin folder. Increasing depth increases scan times."
|
559 |
"htaccess"
|
560 |
],
|
561 |
"type": "array",
|
562 |
+
"link_info": "https://shsec.io/bo",
|
563 |
"link_blog": "",
|
564 |
"name": "File Types",
|
565 |
"summary": "The File Types Included In The Scan",
|
571 |
"premium": true,
|
572 |
"type": "checkbox",
|
573 |
"default": "Y",
|
574 |
+
"link_info": "https://shsec.io/bp",
|
575 |
"link_blog": "",
|
576 |
"name": "Show Re-Install Links",
|
577 |
"summary": "Show Re-Install Links For Plugins",
|
src/config/feature-headers.php
CHANGED
@@ -55,8 +55,8 @@
|
|
55 |
"section": "section_enable_plugin_feature_headers",
|
56 |
"default": "Y",
|
57 |
"type": "checkbox",
|
58 |
-
"link_info": "https://
|
59 |
-
"link_blog": "https://
|
60 |
"name": "Enable HTTP Headers",
|
61 |
"summary": "Enable (or Disable) The HTTP Headers module",
|
62 |
"description": "Un-Checking this option will completely disable the HTTP Headers module"
|
@@ -80,8 +80,8 @@
|
|
80 |
"text": "On: Block All iFrames"
|
81 |
}
|
82 |
],
|
83 |
-
"link_info": "https://
|
84 |
-
"link_blog": "https://
|
85 |
"name": "Block iFrames",
|
86 |
"summary": "Block Remote iFrames Of This Site",
|
87 |
"description": "The setting prevents any external website from embedding your site in an iFrame. This is useful for preventing so-called ClickJack attacks."
|
@@ -91,8 +91,8 @@
|
|
91 |
"section": "section_security_headers",
|
92 |
"default": "Y",
|
93 |
"type": "checkbox",
|
94 |
-
"link_info": "https://
|
95 |
-
"link_blog": "https://
|
96 |
"name": "XSS Protection",
|
97 |
"summary": "Employ Built-In Browser XSS Protection",
|
98 |
"description": "Directs compatible browsers to block what they detect as Reflective XSS attacks."
|
@@ -102,8 +102,8 @@
|
|
102 |
"section": "section_security_headers",
|
103 |
"default": "Y",
|
104 |
"type": "checkbox",
|
105 |
-
"link_info": "https://
|
106 |
-
"link_blog": "https://
|
107 |
"name": "Prevent Mime-Sniff",
|
108 |
"summary": "Turn-Off Browser Mime-Sniff",
|
109 |
"description": "Reduces visitor exposure to malicious user-uploaded content."
|
@@ -156,7 +156,7 @@
|
|
156 |
"text": "Disabled - Don't Send This Header"
|
157 |
}
|
158 |
],
|
159 |
-
"link_info": "https://
|
160 |
"link_blog": "",
|
161 |
"name": "Referrer Policy",
|
162 |
"summary": "Referrer Policy Header",
|
@@ -167,8 +167,8 @@
|
|
167 |
"section": "section_content_security_policy",
|
168 |
"default": "N",
|
169 |
"type": "checkbox",
|
170 |
-
"link_info": "https://
|
171 |
-
"link_blog": "https://
|
172 |
"name": "Enable Content Security Policy",
|
173 |
"summary": "Enable (or Disable) The Content Security Policy module",
|
174 |
"description": "Allows for permission and restriction of all resources loaded on your site."
|
55 |
"section": "section_enable_plugin_feature_headers",
|
56 |
"default": "Y",
|
57 |
"type": "checkbox",
|
58 |
+
"link_info": "https://shsec.io/aj",
|
59 |
+
"link_blog": "https://shsec.io/7c",
|
60 |
"name": "Enable HTTP Headers",
|
61 |
"summary": "Enable (or Disable) The HTTP Headers module",
|
62 |
"description": "Un-Checking this option will completely disable the HTTP Headers module"
|
80 |
"text": "On: Block All iFrames"
|
81 |
}
|
82 |
],
|
83 |
+
"link_info": "https://shsec.io/78",
|
84 |
+
"link_blog": "https://shsec.io/7c",
|
85 |
"name": "Block iFrames",
|
86 |
"summary": "Block Remote iFrames Of This Site",
|
87 |
"description": "The setting prevents any external website from embedding your site in an iFrame. This is useful for preventing so-called ClickJack attacks."
|
91 |
"section": "section_security_headers",
|
92 |
"default": "Y",
|
93 |
"type": "checkbox",
|
94 |
+
"link_info": "https://shsec.io/79",
|
95 |
+
"link_blog": "https://shsec.io/7c",
|
96 |
"name": "XSS Protection",
|
97 |
"summary": "Employ Built-In Browser XSS Protection",
|
98 |
"description": "Directs compatible browsers to block what they detect as Reflective XSS attacks."
|
102 |
"section": "section_security_headers",
|
103 |
"default": "Y",
|
104 |
"type": "checkbox",
|
105 |
+
"link_info": "https://shsec.io/7a",
|
106 |
+
"link_blog": "https://shsec.io/7c",
|
107 |
"name": "Prevent Mime-Sniff",
|
108 |
"summary": "Turn-Off Browser Mime-Sniff",
|
109 |
"description": "Reduces visitor exposure to malicious user-uploaded content."
|
156 |
"text": "Disabled - Don't Send This Header"
|
157 |
}
|
158 |
],
|
159 |
+
"link_info": "https://shsec.io/a5",
|
160 |
"link_blog": "",
|
161 |
"name": "Referrer Policy",
|
162 |
"summary": "Referrer Policy Header",
|
167 |
"section": "section_content_security_policy",
|
168 |
"default": "N",
|
169 |
"type": "checkbox",
|
170 |
+
"link_info": "https://shsec.io/7d",
|
171 |
+
"link_blog": "https://shsec.io/7c",
|
172 |
"name": "Enable Content Security Policy",
|
173 |
"summary": "Enable (or Disable) The Content Security Policy module",
|
174 |
"description": "Allows for permission and restriction of all resources loaded on your site."
|
src/config/feature-ips.php
CHANGED
@@ -112,8 +112,8 @@
|
|
112 |
"section": "section_enable_plugin_feature_ips",
|
113 |
"default": "Y",
|
114 |
"type": "checkbox",
|
115 |
-
"link_info": "https://
|
116 |
-
"link_blog": "https://
|
117 |
"name": "Enable IP Manager",
|
118 |
"summary": "Enable (or Disable) The IP Manager module",
|
119 |
"description": "Un-Checking this option will completely disable the IP Manager module"
|
@@ -123,8 +123,8 @@
|
|
123 |
"section": "section_auto_black_list",
|
124 |
"default": 10,
|
125 |
"type": "integer",
|
126 |
-
"link_info": "https://
|
127 |
-
"link_blog": "https://
|
128 |
"name": "Offense Limit",
|
129 |
"summary": "Visitor IP address will be Black Listed after X bad actions on your site",
|
130 |
"description": "A black mark is set against an IP address each time a visitor trips the defenses of the Shield plugin. When the number of these offenses exceeds specified limit, they are automatically blocked from accessing the site. Set this to 0 to turn off the Automatic IP Black List feature."
|
@@ -156,8 +156,8 @@
|
|
156 |
"text": "Month"
|
157 |
}
|
158 |
],
|
159 |
-
"link_info": "https://
|
160 |
-
"link_blog": "https://
|
161 |
"name": "Auto Block Expiration",
|
162 |
"summary": "After 1 'X' a black listed IP will be removed from the black list",
|
163 |
"description": "Permanent and lengthy IP Black Lists are harmful to performance. You should allow IP addresses on the black list to be eventually removed over time. Shorter IP black lists are more efficient and a more intelligent use of an IP-based blocking system."
|
@@ -178,7 +178,7 @@
|
|
178 |
"text": "With Shield Bot Protection"
|
179 |
}
|
180 |
],
|
181 |
-
"link_info": "https://
|
182 |
"link_blog": "",
|
183 |
"name": "User Auto Unblock",
|
184 |
"summary": "Allow Visitors To Unblock Their IP",
|
@@ -191,7 +191,7 @@
|
|
191 |
"premium": true,
|
192 |
"default": "default",
|
193 |
"type": "text",
|
194 |
-
"link_info": "https://
|
195 |
"link_blog": "",
|
196 |
"name": "Login Failed",
|
197 |
"summary": "Visitor Triggers The IP Offenses System Through A Failed Login",
|
@@ -225,8 +225,8 @@
|
|
225 |
"text": "Immediate Block"
|
226 |
}
|
227 |
],
|
228 |
-
"link_info": "https://
|
229 |
-
"link_blog": "https://
|
230 |
"name": "404 Detect",
|
231 |
"summary": "Identify A Bot When It Hits A 404",
|
232 |
"description": "Detect When A Visitor Browses To A Non-Existent Page."
|
@@ -259,8 +259,8 @@
|
|
259 |
"text": "Immediate Block"
|
260 |
}
|
261 |
],
|
262 |
-
"link_info": "https://
|
263 |
-
"link_blog": "https://
|
264 |
"name": "Link Cheese",
|
265 |
"summary": "Tempt A Bot With A Fake Link To Follow",
|
266 |
"description": "Detect A Bot That Follows A 'no-follow' Link."
|
@@ -268,8 +268,8 @@
|
|
268 |
{
|
269 |
"key": "track_xmlrpc",
|
270 |
"section": "section_probes",
|
271 |
-
"default": "log",
|
272 |
"premium": true,
|
|
|
273 |
"type": "select",
|
274 |
"value_options": [
|
275 |
{
|
@@ -293,8 +293,8 @@
|
|
293 |
"text": "Immediate Block"
|
294 |
}
|
295 |
],
|
296 |
-
"link_info": "https://
|
297 |
-
"link_blog": "https://
|
298 |
"name": "XML-RPC Access",
|
299 |
"summary": "Identify A Bot When It Accesses XML-RPC",
|
300 |
"description": "If you don't use XML-RPC, why would anyone access it?"
|
@@ -304,6 +304,7 @@
|
|
304 |
"section": "section_logins",
|
305 |
"default": "transgression-single",
|
306 |
"type": "select",
|
|
|
307 |
"value_options": [
|
308 |
{
|
309 |
"value_key": "disabled",
|
@@ -326,8 +327,8 @@
|
|
326 |
"text": "Immediate Block"
|
327 |
}
|
328 |
],
|
329 |
-
"link_info": "https://
|
330 |
-
"link_blog": "https://
|
331 |
"name": "Failed Login",
|
332 |
"summary": "Detect Failed Login Attempts By Valid Usernames",
|
333 |
"description": "Penalise a visitor who fails to login using a valid username."
|
@@ -360,8 +361,8 @@
|
|
360 |
"text": "Immediate Block"
|
361 |
}
|
362 |
],
|
363 |
-
"link_info": "https://
|
364 |
-
"link_blog": "https://
|
365 |
"name": "Invalid Usernames",
|
366 |
"summary": "Detect Invalid Username Logins",
|
367 |
"description": "Identify A Bot When It Tries To Login With A Non-Existent Username."
|
@@ -394,8 +395,8 @@
|
|
394 |
"text": "Immediate Block"
|
395 |
}
|
396 |
],
|
397 |
-
"link_info": "https://
|
398 |
-
"link_blog": "https://
|
399 |
"name": "Fake Web Crawler",
|
400 |
"summary": "Detect Fake Search Engine Crawlers",
|
401 |
"description": "Identify a Bot when it presents as an official web crawler, but analysis shows it's fake."
|
@@ -428,8 +429,8 @@
|
|
428 |
"text": "Immediate Block"
|
429 |
}
|
430 |
],
|
431 |
-
"link_info": "https://
|
432 |
-
"link_blog": "https://
|
433 |
"name": "Empty User Agents",
|
434 |
"summary": "Detect Requests With Empty User Agents",
|
435 |
"description": "Identify a request as a bot if the user agent is not provided."
|
@@ -441,7 +442,7 @@
|
|
441 |
"premium": true,
|
442 |
"default": "default",
|
443 |
"type": "text",
|
444 |
-
"link_info": "https://
|
445 |
"link_blog": "",
|
446 |
"name": "Remaining Offenses",
|
447 |
"summary": "Visitor Triggers The IP Offenses System Through A Firewall Block",
|
112 |
"section": "section_enable_plugin_feature_ips",
|
113 |
"default": "Y",
|
114 |
"type": "checkbox",
|
115 |
+
"link_info": "https://shsec.io/ea",
|
116 |
+
"link_blog": "https://shsec.io/wpsf26",
|
117 |
"name": "Enable IP Manager",
|
118 |
"summary": "Enable (or Disable) The IP Manager module",
|
119 |
"description": "Un-Checking this option will completely disable the IP Manager module"
|
123 |
"section": "section_auto_black_list",
|
124 |
"default": 10,
|
125 |
"type": "integer",
|
126 |
+
"link_info": "https://shsec.io/wpsf24",
|
127 |
+
"link_blog": "https://shsec.io/wpsf26",
|
128 |
"name": "Offense Limit",
|
129 |
"summary": "Visitor IP address will be Black Listed after X bad actions on your site",
|
130 |
"description": "A black mark is set against an IP address each time a visitor trips the defenses of the Shield plugin. When the number of these offenses exceeds specified limit, they are automatically blocked from accessing the site. Set this to 0 to turn off the Automatic IP Black List feature."
|
156 |
"text": "Month"
|
157 |
}
|
158 |
],
|
159 |
+
"link_info": "https://shsec.io/wpsf25",
|
160 |
+
"link_blog": "https://shsec.io/wpsf26",
|
161 |
"name": "Auto Block Expiration",
|
162 |
"summary": "After 1 'X' a black listed IP will be removed from the black list",
|
163 |
"description": "Permanent and lengthy IP Black Lists are harmful to performance. You should allow IP addresses on the black list to be eventually removed over time. Shorter IP black lists are more efficient and a more intelligent use of an IP-based blocking system."
|
178 |
"text": "With Shield Bot Protection"
|
179 |
}
|
180 |
],
|
181 |
+
"link_info": "https://shsec.io/f8",
|
182 |
"link_blog": "",
|
183 |
"name": "User Auto Unblock",
|
184 |
"summary": "Allow Visitors To Unblock Their IP",
|
191 |
"premium": true,
|
192 |
"default": "default",
|
193 |
"type": "text",
|
194 |
+
"link_info": "https://shsec.io/e8",
|
195 |
"link_blog": "",
|
196 |
"name": "Login Failed",
|
197 |
"summary": "Visitor Triggers The IP Offenses System Through A Failed Login",
|
225 |
"text": "Immediate Block"
|
226 |
}
|
227 |
],
|
228 |
+
"link_info": "https://shsec.io/fo",
|
229 |
+
"link_blog": "https://shsec.io/f7",
|
230 |
"name": "404 Detect",
|
231 |
"summary": "Identify A Bot When It Hits A 404",
|
232 |
"description": "Detect When A Visitor Browses To A Non-Existent Page."
|
259 |
"text": "Immediate Block"
|
260 |
}
|
261 |
],
|
262 |
+
"link_info": "https://shsec.io/fo",
|
263 |
+
"link_blog": "https://shsec.io/f6",
|
264 |
"name": "Link Cheese",
|
265 |
"summary": "Tempt A Bot With A Fake Link To Follow",
|
266 |
"description": "Detect A Bot That Follows A 'no-follow' Link."
|
268 |
{
|
269 |
"key": "track_xmlrpc",
|
270 |
"section": "section_probes",
|
|
|
271 |
"premium": true,
|
272 |
+
"default": "log",
|
273 |
"type": "select",
|
274 |
"value_options": [
|
275 |
{
|
293 |
"text": "Immediate Block"
|
294 |
}
|
295 |
],
|
296 |
+
"link_info": "https://shsec.io/fo",
|
297 |
+
"link_blog": "https://shsec.io/f7",
|
298 |
"name": "XML-RPC Access",
|
299 |
"summary": "Identify A Bot When It Accesses XML-RPC",
|
300 |
"description": "If you don't use XML-RPC, why would anyone access it?"
|
304 |
"section": "section_logins",
|
305 |
"default": "transgression-single",
|
306 |
"type": "select",
|
307 |
+
"default": "log",
|
308 |
"value_options": [
|
309 |
{
|
310 |
"value_key": "disabled",
|
327 |
"text": "Immediate Block"
|
328 |
}
|
329 |
],
|
330 |
+
"link_info": "https://shsec.io/fn",
|
331 |
+
"link_blog": "https://shsec.io/f7",
|
332 |
"name": "Failed Login",
|
333 |
"summary": "Detect Failed Login Attempts By Valid Usernames",
|
334 |
"description": "Penalise a visitor who fails to login using a valid username."
|
361 |
"text": "Immediate Block"
|
362 |
}
|
363 |
],
|
364 |
+
"link_info": "https://shsec.io/fn",
|
365 |
+
"link_blog": "https://shsec.io/f7",
|
366 |
"name": "Invalid Usernames",
|
367 |
"summary": "Detect Invalid Username Logins",
|
368 |
"description": "Identify A Bot When It Tries To Login With A Non-Existent Username."
|
395 |
"text": "Immediate Block"
|
396 |
}
|
397 |
],
|
398 |
+
"link_info": "https://shsec.io/f5",
|
399 |
+
"link_blog": "https://shsec.io/f7",
|
400 |
"name": "Fake Web Crawler",
|
401 |
"summary": "Detect Fake Search Engine Crawlers",
|
402 |
"description": "Identify a Bot when it presents as an official web crawler, but analysis shows it's fake."
|
429 |
"text": "Immediate Block"
|
430 |
}
|
431 |
],
|
432 |
+
"link_info": "https://shsec.io/fi",
|
433 |
+
"link_blog": "https://shsec.io/f7",
|
434 |
"name": "Empty User Agents",
|
435 |
"summary": "Detect Requests With Empty User Agents",
|
436 |
"description": "Identify a request as a bot if the user agent is not provided."
|
442 |
"premium": true,
|
443 |
"default": "default",
|
444 |
"type": "text",
|
445 |
+
"link_info": "https://shsec.io/e9",
|
446 |
"link_blog": "",
|
447 |
"name": "Remaining Offenses",
|
448 |
"summary": "Visitor Triggers The IP Offenses System Through A Firewall Block",
|
src/config/feature-license.php
CHANGED
@@ -115,7 +115,7 @@
|
|
115 |
],
|
116 |
"definitions": {
|
117 |
"license_store_url": "https://onedollarplugin.com/edd-sl/",
|
118 |
-
"keyless_cp": "https://
|
119 |
"license_item_name": "Shield Security Pro",
|
120 |
"license_item_id": "6047",
|
121 |
"license_item_name_sc": "Shield Security Pro (via Shield Central)",
|
115 |
],
|
116 |
"definitions": {
|
117 |
"license_store_url": "https://onedollarplugin.com/edd-sl/",
|
118 |
+
"keyless_cp": "https://shsec.io/c5",
|
119 |
"license_item_name": "Shield Security Pro",
|
120 |
"license_item_id": "6047",
|
121 |
"license_item_name_sc": "Shield Security Pro (via Shield Central)",
|
src/config/feature-lockdown.php
CHANGED
@@ -64,7 +64,7 @@
|
|
64 |
"section": "section_enable_plugin_feature_wordpress_lockdown",
|
65 |
"default": "Y",
|
66 |
"type": "checkbox",
|
67 |
-
"link_info": "https://
|
68 |
"link_blog": "",
|
69 |
"name": "Enable Lockdown",
|
70 |
"summary": "Enable (or Disable) The Lockdown module",
|
@@ -75,8 +75,8 @@
|
|
75 |
"section": "section_apixml",
|
76 |
"default": "N",
|
77 |
"type": "checkbox",
|
78 |
-
"link_info": "https://
|
79 |
-
"link_blog": "https://
|
80 |
"name": "Disable XML-RPC",
|
81 |
"summary": "Disable The XML-RPC System",
|
82 |
"description": "Checking this option will completely turn off the whole XML-RPC system."
|
@@ -112,7 +112,7 @@
|
|
112 |
"section": "section_permission_access_options",
|
113 |
"default": "N",
|
114 |
"type": "checkbox",
|
115 |
-
"link_info": "https://
|
116 |
"link_blog": "",
|
117 |
"name": "Disable File Editing",
|
118 |
"summary": "Disable Ability To Edit Files From Within WordPress",
|
@@ -123,7 +123,7 @@
|
|
123 |
"section": "section_permission_access_options",
|
124 |
"default": "N",
|
125 |
"type": "checkbox",
|
126 |
-
"link_info": "https://
|
127 |
"link_blog": "",
|
128 |
"name": "Force SSL Admin",
|
129 |
"summary": "Forces WordPress Admin Dashboard To Be Delivered Over SSL",
|
@@ -134,7 +134,7 @@
|
|
134 |
"section": "section_wordpress_obscurity_options",
|
135 |
"default": "",
|
136 |
"type": "text",
|
137 |
-
"link_info": "https://
|
138 |
"link_blog": "",
|
139 |
"name": "Mask WordPress Version",
|
140 |
"summary": "Prevents Public Display Of Your WordPress Version",
|
@@ -156,7 +156,7 @@
|
|
156 |
"section": "section_wordpress_obscurity_options",
|
157 |
"default": "Y",
|
158 |
"type": "checkbox",
|
159 |
-
"link_info": "https://
|
160 |
"link_blog": "",
|
161 |
"name": "Block Username Fishing",
|
162 |
"summary": "Block the ability to discover WordPress usernames based on author IDs",
|
64 |
"section": "section_enable_plugin_feature_wordpress_lockdown",
|
65 |
"default": "Y",
|
66 |
"type": "checkbox",
|
67 |
+
"link_info": "https://shsec.io/4r",
|
68 |
"link_blog": "",
|
69 |
"name": "Enable Lockdown",
|
70 |
"summary": "Enable (or Disable) The Lockdown module",
|
75 |
"section": "section_apixml",
|
76 |
"default": "N",
|
77 |
"type": "checkbox",
|
78 |
+
"link_info": "https://shsec.io/e6",
|
79 |
+
"link_blog": "https://shsec.io/fb",
|
80 |
"name": "Disable XML-RPC",
|
81 |
"summary": "Disable The XML-RPC System",
|
82 |
"description": "Checking this option will completely turn off the whole XML-RPC system."
|
112 |
"section": "section_permission_access_options",
|
113 |
"default": "N",
|
114 |
"type": "checkbox",
|
115 |
+
"link_info": "https://shsec.io/4q",
|
116 |
"link_blog": "",
|
117 |
"name": "Disable File Editing",
|
118 |
"summary": "Disable Ability To Edit Files From Within WordPress",
|
123 |
"section": "section_permission_access_options",
|
124 |
"default": "N",
|
125 |
"type": "checkbox",
|
126 |
+
"link_info": "https://shsec.io/4t",
|
127 |
"link_blog": "",
|
128 |
"name": "Force SSL Admin",
|
129 |
"summary": "Forces WordPress Admin Dashboard To Be Delivered Over SSL",
|
134 |
"section": "section_wordpress_obscurity_options",
|
135 |
"default": "",
|
136 |
"type": "text",
|
137 |
+
"link_info": "https://shsec.io/43",
|
138 |
"link_blog": "",
|
139 |
"name": "Mask WordPress Version",
|
140 |
"summary": "Prevents Public Display Of Your WordPress Version",
|
156 |
"section": "section_wordpress_obscurity_options",
|
157 |
"default": "Y",
|
158 |
"type": "checkbox",
|
159 |
+
"link_info": "https://shsec.io/wpsf23",
|
160 |
"link_blog": "",
|
161 |
"name": "Block Username Fishing",
|
162 |
"summary": "Block the ability to discover WordPress usernames based on author IDs",
|
src/config/feature-login_protect.php
CHANGED
@@ -122,8 +122,8 @@
|
|
122 |
"section": "section_enable_plugin_feature_login_protection",
|
123 |
"default": "Y",
|
124 |
"type": "checkbox",
|
125 |
-
"link_info": "https://
|
126 |
-
"link_blog": "https://
|
127 |
"name": "Enable Login Guard",
|
128 |
"summary": "Enable (or Disable) The Login Guard Module",
|
129 |
"description": "Un-Checking this option will completely disable the Login Guard module"
|
@@ -134,8 +134,8 @@
|
|
134 |
"sensitive": true,
|
135 |
"default": "",
|
136 |
"type": "text",
|
137 |
-
"link_info": "https://
|
138 |
-
"link_blog": "https://
|
139 |
"name": "Hide Login Page",
|
140 |
"summary": "Rename The WordPress Login Page",
|
141 |
"description": "Creating a path here will disable your 'wp-login.php'. Only letters and numbers are permitted: abc123"
|
@@ -145,8 +145,8 @@
|
|
145 |
"section": "section_multifactor_authentication",
|
146 |
"default": "N",
|
147 |
"type": "checkbox",
|
148 |
-
"link_info": "https://
|
149 |
-
"link_blog": "https://
|
150 |
"name": "Multi-Factor Authentication",
|
151 |
"summary": "Require All Active Authentication Factors",
|
152 |
"description": "When enabled, all multi-factor authentication methods will be applied to a user login. Disable to only require one to pass."
|
@@ -158,7 +158,7 @@
|
|
158 |
"default": 0,
|
159 |
"min": 0,
|
160 |
"type": "integer",
|
161 |
-
"link_info": "https://
|
162 |
"link_blog": "",
|
163 |
"name": "Multi-Factor By-Pass",
|
164 |
"summary": "A User Can By-Pass Multi-Factor Authentication (MFA) For The Set Number Of Days",
|
@@ -170,8 +170,8 @@
|
|
170 |
"premium": true,
|
171 |
"default": "N",
|
172 |
"type": "checkbox",
|
173 |
-
"link_info": "https://
|
174 |
-
"link_blog": "https://
|
175 |
"name": "Allow Backup Codes",
|
176 |
"summary": "Allow Users To Generate A Backup Code",
|
177 |
"description": "Allow users to generate a backup code that can be used to login if MFA factors are unavailable."
|
@@ -181,8 +181,8 @@
|
|
181 |
"section": "section_2fa_ga",
|
182 |
"default": "N",
|
183 |
"type": "checkbox",
|
184 |
-
"link_info": "https://
|
185 |
-
"link_blog": "https://
|
186 |
"name": "Enable Google Authenticator",
|
187 |
"summary": "Allow Users To Use Google Authenticator",
|
188 |
"description": "When enabled, users will have the option to add Google Authenticator to their WordPress user profile."
|
@@ -192,8 +192,8 @@
|
|
192 |
"section": "section_2fa_email",
|
193 |
"default": "N",
|
194 |
"type": "checkbox",
|
195 |
-
"link_info": "https://
|
196 |
-
"link_blog": "https://
|
197 |
"name": "Enable Email Authentication",
|
198 |
"summary": "Two-Factor Login Authentication By Email",
|
199 |
"description": "All users will be required to verify their login by email-based two-factor authentication."
|
@@ -250,7 +250,7 @@
|
|
250 |
"text": "[EDD] Customer"
|
251 |
}
|
252 |
],
|
253 |
-
"link_info": "https://
|
254 |
"link_blog": "",
|
255 |
"name": "Enforce - Email Authentication",
|
256 |
"summary": "All User Roles Subject To Email Authentication",
|
@@ -281,7 +281,7 @@
|
|
281 |
"text": "Checkout (WooCommerce)"
|
282 |
}
|
283 |
],
|
284 |
-
"link_info": "https://
|
285 |
"link_blog": "",
|
286 |
"name": "Protection Locations",
|
287 |
"summary": "How Google reCAPTCHA Will Be Displayed",
|
@@ -293,8 +293,8 @@
|
|
293 |
"default": "10",
|
294 |
"min": 0,
|
295 |
"type": "integer",
|
296 |
-
"link_info": "https://
|
297 |
-
"link_blog": "https://
|
298 |
"name": "Login Cooldown Interval",
|
299 |
"summary": "Limit login attempts to every X seconds",
|
300 |
"description": "WordPress will process only ONE login attempt for every number of seconds specified. Zero (0) turns this off."
|
@@ -304,8 +304,8 @@
|
|
304 |
"section": "section_brute_force_login_protection",
|
305 |
"default": "N",
|
306 |
"type": "checkbox",
|
307 |
-
"link_info": "https://
|
308 |
-
"link_blog": "https://
|
309 |
"name": "Bot Protection",
|
310 |
"summary": "Protect WP Login From Automated Login Attempts By Bots",
|
311 |
"description": "Adds a dynamically (Javascript) generated checkbox to the login form that prevents bots using automated login techniques. Recommended: ON."
|
@@ -337,8 +337,8 @@
|
|
337 |
"text": "Invisible"
|
338 |
}
|
339 |
],
|
340 |
-
"link_info": "https://
|
341 |
-
"link_blog": "https://
|
342 |
"name": "Google reCAPTCHA",
|
343 |
"summary": "Enable Google reCAPTCHA",
|
344 |
"description": "Use Google reCAPTCHA on the login screen."
|
@@ -349,7 +349,7 @@
|
|
349 |
"premium": true,
|
350 |
"default": "N",
|
351 |
"type": "checkbox",
|
352 |
-
"link_info": "https://
|
353 |
"link_blog": "",
|
354 |
"name": "AntiBot JS",
|
355 |
"summary": "Load Anti-Bot JS For 3rd Party Login Forms",
|
@@ -374,8 +374,8 @@
|
|
374 |
"section": "section_yubikey_authentication",
|
375 |
"default": "N",
|
376 |
"type": "checkbox",
|
377 |
-
"link_info": "https://
|
378 |
-
"link_blog": "https://
|
379 |
"name": "Enable Yubikey Authentication",
|
380 |
"summary": "Turn On / Off Yubikey Authentication On This Site",
|
381 |
"description": "Combined with your Yubikey API Key (below) this will form the basis of your Yubikey Authentication."
|
@@ -386,7 +386,7 @@
|
|
386 |
"sensitive": true,
|
387 |
"default": "",
|
388 |
"type": "text",
|
389 |
-
"link_info": "https://
|
390 |
"link_blog": "",
|
391 |
"name": "Yubikey App ID",
|
392 |
"summary": "Your Unique Yubikey App ID",
|
@@ -398,7 +398,7 @@
|
|
398 |
"sensitive": true,
|
399 |
"default": "",
|
400 |
"type": "text",
|
401 |
-
"link_info": "https://
|
402 |
"link_blog": "",
|
403 |
"name": "Yubikey API Key",
|
404 |
"summary": "Your Unique Yubikey App API Key",
|
@@ -411,7 +411,7 @@
|
|
411 |
"premium": true,
|
412 |
"default": "default",
|
413 |
"type": "text",
|
414 |
-
"link_info": "https://
|
415 |
"link_blog": "",
|
416 |
"name": "GASP Checkbox Text",
|
417 |
"summary": "The Message Displayed Next To The GASP Checkbox",
|
@@ -424,7 +424,7 @@
|
|
424 |
"premium": true,
|
425 |
"default": "default",
|
426 |
"type": "text",
|
427 |
-
"link_info": "https://
|
428 |
"link_blog": "",
|
429 |
"name": "GASP Alert Text",
|
430 |
"summary": "The Message Displayed If The User Doesn't Check The Box",
|
122 |
"section": "section_enable_plugin_feature_login_protection",
|
123 |
"default": "Y",
|
124 |
"type": "checkbox",
|
125 |
+
"link_info": "https://shsec.io/51",
|
126 |
+
"link_blog": "https://shsec.io/wpsf03",
|
127 |
"name": "Enable Login Guard",
|
128 |
"summary": "Enable (or Disable) The Login Guard Module",
|
129 |
"description": "Un-Checking this option will completely disable the Login Guard module"
|
134 |
"sensitive": true,
|
135 |
"default": "",
|
136 |
"type": "text",
|
137 |
+
"link_info": "https://shsec.io/5q",
|
138 |
+
"link_blog": "https://shsec.io/5r",
|
139 |
"name": "Hide Login Page",
|
140 |
"summary": "Rename The WordPress Login Page",
|
141 |
"description": "Creating a path here will disable your 'wp-login.php'. Only letters and numbers are permitted: abc123"
|
145 |
"section": "section_multifactor_authentication",
|
146 |
"default": "N",
|
147 |
"type": "checkbox",
|
148 |
+
"link_info": "https://shsec.io/9r",
|
149 |
+
"link_blog": "https://shsec.io/84",
|
150 |
"name": "Multi-Factor Authentication",
|
151 |
"summary": "Require All Active Authentication Factors",
|
152 |
"description": "When enabled, all multi-factor authentication methods will be applied to a user login. Disable to only require one to pass."
|
158 |
"default": 0,
|
159 |
"min": 0,
|
160 |
"type": "integer",
|
161 |
+
"link_info": "https://shsec.io/b1",
|
162 |
"link_blog": "",
|
163 |
"name": "Multi-Factor By-Pass",
|
164 |
"summary": "A User Can By-Pass Multi-Factor Authentication (MFA) For The Set Number Of Days",
|
170 |
"premium": true,
|
171 |
"default": "N",
|
172 |
"type": "checkbox",
|
173 |
+
"link_info": "https://shsec.io/dx",
|
174 |
+
"link_blog": "https://shsec.io/dy",
|
175 |
"name": "Allow Backup Codes",
|
176 |
"summary": "Allow Users To Generate A Backup Code",
|
177 |
"description": "Allow users to generate a backup code that can be used to login if MFA factors are unavailable."
|
181 |
"section": "section_2fa_ga",
|
182 |
"default": "N",
|
183 |
"type": "checkbox",
|
184 |
+
"link_info": "https://shsec.io/shld7",
|
185 |
+
"link_blog": "https://shsec.io/shld6",
|
186 |
"name": "Enable Google Authenticator",
|
187 |
"summary": "Allow Users To Use Google Authenticator",
|
188 |
"description": "When enabled, users will have the option to add Google Authenticator to their WordPress user profile."
|
192 |
"section": "section_2fa_email",
|
193 |
"default": "N",
|
194 |
"type": "checkbox",
|
195 |
+
"link_info": "https://shsec.io/3t",
|
196 |
+
"link_blog": "https://shsec.io/9q",
|
197 |
"name": "Enable Email Authentication",
|
198 |
"summary": "Two-Factor Login Authentication By Email",
|
199 |
"description": "All users will be required to verify their login by email-based two-factor authentication."
|
250 |
"text": "[EDD] Customer"
|
251 |
}
|
252 |
],
|
253 |
+
"link_info": "https://shsec.io/4v",
|
254 |
"link_blog": "",
|
255 |
"name": "Enforce - Email Authentication",
|
256 |
"summary": "All User Roles Subject To Email Authentication",
|
281 |
"text": "Checkout (WooCommerce)"
|
282 |
}
|
283 |
],
|
284 |
+
"link_info": "https://shsec.io/dv",
|
285 |
"link_blog": "",
|
286 |
"name": "Protection Locations",
|
287 |
"summary": "How Google reCAPTCHA Will Be Displayed",
|
293 |
"default": "10",
|
294 |
"min": 0,
|
295 |
"type": "integer",
|
296 |
+
"link_info": "https://shsec.io/3q",
|
297 |
+
"link_blog": "https://shsec.io/9o",
|
298 |
"name": "Login Cooldown Interval",
|
299 |
"summary": "Limit login attempts to every X seconds",
|
300 |
"description": "WordPress will process only ONE login attempt for every number of seconds specified. Zero (0) turns this off."
|
304 |
"section": "section_brute_force_login_protection",
|
305 |
"default": "N",
|
306 |
"type": "checkbox",
|
307 |
+
"link_info": "https://shsec.io/3r",
|
308 |
+
"link_blog": "https://shsec.io/9n",
|
309 |
"name": "Bot Protection",
|
310 |
"summary": "Protect WP Login From Automated Login Attempts By Bots",
|
311 |
"description": "Adds a dynamically (Javascript) generated checkbox to the login form that prevents bots using automated login techniques. Recommended: ON."
|
337 |
"text": "Invisible"
|
338 |
}
|
339 |
],
|
340 |
+
"link_info": "https://shsec.io/9m",
|
341 |
+
"link_blog": "https://shsec.io/shld5",
|
342 |
"name": "Google reCAPTCHA",
|
343 |
"summary": "Enable Google reCAPTCHA",
|
344 |
"description": "Use Google reCAPTCHA on the login screen."
|
349 |
"premium": true,
|
350 |
"default": "N",
|
351 |
"type": "checkbox",
|
352 |
+
"link_info": "https://shsec.io/dw",
|
353 |
"link_blog": "",
|
354 |
"name": "AntiBot JS",
|
355 |
"summary": "Load Anti-Bot JS For 3rd Party Login Forms",
|
374 |
"section": "section_yubikey_authentication",
|
375 |
"default": "N",
|
376 |
"type": "checkbox",
|
377 |
+
"link_info": "https://shsec.io/4f",
|
378 |
+
"link_blog": "https://shsec.io/9t",
|
379 |
"name": "Enable Yubikey Authentication",
|
380 |
"summary": "Turn On / Off Yubikey Authentication On This Site",
|
381 |
"description": "Combined with your Yubikey API Key (below) this will form the basis of your Yubikey Authentication."
|
386 |
"sensitive": true,
|
387 |
"default": "",
|
388 |
"type": "text",
|
389 |
+
"link_info": "https://shsec.io/4g",
|
390 |
"link_blog": "",
|
391 |
"name": "Yubikey App ID",
|
392 |
"summary": "Your Unique Yubikey App ID",
|
398 |
"sensitive": true,
|
399 |
"default": "",
|
400 |
"type": "text",
|
401 |
+
"link_info": "https://shsec.io/4g",
|
402 |
"link_blog": "",
|
403 |
"name": "Yubikey API Key",
|
404 |
"summary": "Your Unique Yubikey App API Key",
|
411 |
"premium": true,
|
412 |
"default": "default",
|
413 |
"type": "text",
|
414 |
+
"link_info": "https://shsec.io/dz",
|
415 |
"link_blog": "",
|
416 |
"name": "GASP Checkbox Text",
|
417 |
"summary": "The Message Displayed Next To The GASP Checkbox",
|
424 |
"premium": true,
|
425 |
"default": "default",
|
426 |
"type": "text",
|
427 |
+
"link_info": "https://shsec.io/dz",
|
428 |
"link_blog": "",
|
429 |
"name": "GASP Alert Text",
|
430 |
"summary": "The Message Displayed If The User Doesn't Check The Box",
|
src/config/feature-plugin.php
CHANGED
@@ -25,6 +25,15 @@
|
|
25 |
"can_dismiss": false,
|
26 |
"type": "error"
|
27 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
"wizard_welcome": {
|
29 |
"id": "wizard_welcome",
|
30 |
"per_user": false,
|
@@ -104,7 +113,7 @@
|
|
104 |
"section": "section_general_plugin_options",
|
105 |
"default": "N",
|
106 |
"type": "checkbox",
|
107 |
-
"link_info": "https://
|
108 |
"link_blog": "",
|
109 |
"name": "Enable Information Gathering",
|
110 |
"summary": "Permit Anonymous Usage Information Gathering",
|
@@ -162,7 +171,7 @@
|
|
162 |
"text": "HTTP_CLIENT_IP"
|
163 |
}
|
164 |
],
|
165 |
-
"link_info": "https://
|
166 |
"link_blog": "",
|
167 |
"name": "Visitor IP Address",
|
168 |
"summary": "Which Address Is Yours",
|
@@ -196,8 +205,8 @@
|
|
196 |
"section": "section_general_plugin_options",
|
197 |
"default": "N",
|
198 |
"type": "checkbox",
|
199 |
-
"link_info": "https://
|
200 |
-
"link_blog": "https://
|
201 |
"name": "Show Plugin Badge",
|
202 |
"summary": "Display Plugin Badge On Your Site",
|
203 |
"description": "Enabling this option helps support the plugin by spreading the word about it on your website. The plugin badge also demonstrates to visitors that you take your website security seriously."
|
@@ -219,8 +228,8 @@
|
|
219 |
"premium": true,
|
220 |
"default": "Y",
|
221 |
"type": "checkbox",
|
222 |
-
"link_info": "https://
|
223 |
-
"link_blog": "https://
|
224 |
"name": "Allow Import/Export",
|
225 |
"summary": "Allow Import Of Options To, And Export Of Options From, This Site",
|
226 |
"description": "Uncheck this box to completely disable import and export of options."
|
@@ -305,7 +314,7 @@
|
|
305 |
"text": "Invisible"
|
306 |
}
|
307 |
],
|
308 |
-
"link_info": "https://
|
309 |
"link_blog": "",
|
310 |
"name": "reCAPTCHA Style",
|
311 |
"summary": "How Google reCAPTCHA Will Be Displayed By Default",
|
@@ -317,7 +326,7 @@
|
|
317 |
"sensitive": true,
|
318 |
"default": "",
|
319 |
"type": "text",
|
320 |
-
"link_info": "https://
|
321 |
"link_blog": "",
|
322 |
"name": "reCAPTCHA Site Key",
|
323 |
"summary": "Google reCAPTCHA Site Key - Only v2 or Invisible. v3 NOT supported.",
|
@@ -329,7 +338,7 @@
|
|
329 |
"sensitive": true,
|
330 |
"default": "",
|
331 |
"type": "text",
|
332 |
-
"link_info": "https://
|
333 |
"link_blog": "",
|
334 |
"name": "reCAPTCHA Secret",
|
335 |
"summary": "Google reCAPTCHA Secret Key - Only v2 or Invisible. v3 NOT supported.",
|
@@ -419,7 +428,7 @@
|
|
419 |
"tracking_cron_handle": "plugin_tracking_cron",
|
420 |
"tracking_post_url": "https://tracking.icontrolwp.com/track/plugin/shield",
|
421 |
"importexport_cron_name": "autoimport",
|
422 |
-
"href_privacy_policy": "https://
|
423 |
"db_classes": {
|
424 |
"geoip": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\GeoIp\\Handler",
|
425 |
"notes": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AdminNotes\\Handler"
|
25 |
"can_dismiss": false,
|
26 |
"type": "error"
|
27 |
},
|
28 |
+
"compat-sgoptimize": {
|
29 |
+
"id": "compat-sgoptimize",
|
30 |
+
"schedule": "conditions",
|
31 |
+
"valid_admin": true,
|
32 |
+
"plugin_admin": "ignore",
|
33 |
+
"plugin_page_only": false,
|
34 |
+
"can_dismiss": false,
|
35 |
+
"type": "warning"
|
36 |
+
},
|
37 |
"wizard_welcome": {
|
38 |
"id": "wizard_welcome",
|
39 |
"per_user": false,
|
113 |
"section": "section_general_plugin_options",
|
114 |
"default": "N",
|
115 |
"type": "checkbox",
|
116 |
+
"link_info": "https://shsec.io/7i",
|
117 |
"link_blog": "",
|
118 |
"name": "Enable Information Gathering",
|
119 |
"summary": "Permit Anonymous Usage Information Gathering",
|
171 |
"text": "HTTP_CLIENT_IP"
|
172 |
}
|
173 |
],
|
174 |
+
"link_info": "https://shsec.io/dn",
|
175 |
"link_blog": "",
|
176 |
"name": "Visitor IP Address",
|
177 |
"summary": "Which Address Is Yours",
|
205 |
"section": "section_general_plugin_options",
|
206 |
"default": "N",
|
207 |
"type": "checkbox",
|
208 |
+
"link_info": "https://shsec.io/5v",
|
209 |
+
"link_blog": "https://shsec.io/wpsf20",
|
210 |
"name": "Show Plugin Badge",
|
211 |
"summary": "Display Plugin Badge On Your Site",
|
212 |
"description": "Enabling this option helps support the plugin by spreading the word about it on your website. The plugin badge also demonstrates to visitors that you take your website security seriously."
|
228 |
"premium": true,
|
229 |
"default": "Y",
|
230 |
"type": "checkbox",
|
231 |
+
"link_info": "https://shsec.io/do",
|
232 |
+
"link_blog": "https://shsec.io/dp",
|
233 |
"name": "Allow Import/Export",
|
234 |
"summary": "Allow Import Of Options To, And Export Of Options From, This Site",
|
235 |
"description": "Uncheck this box to completely disable import and export of options."
|
314 |
"text": "Invisible"
|
315 |
}
|
316 |
],
|
317 |
+
"link_info": "https://shsec.io/dq",
|
318 |
"link_blog": "",
|
319 |
"name": "reCAPTCHA Style",
|
320 |
"summary": "How Google reCAPTCHA Will Be Displayed By Default",
|
326 |
"sensitive": true,
|
327 |
"default": "",
|
328 |
"type": "text",
|
329 |
+
"link_info": "https://shsec.io/shld5",
|
330 |
"link_blog": "",
|
331 |
"name": "reCAPTCHA Site Key",
|
332 |
"summary": "Google reCAPTCHA Site Key - Only v2 or Invisible. v3 NOT supported.",
|
338 |
"sensitive": true,
|
339 |
"default": "",
|
340 |
"type": "text",
|
341 |
+
"link_info": "https://shsec.io/shld5",
|
342 |
"link_blog": "",
|
343 |
"name": "reCAPTCHA Secret",
|
344 |
"summary": "Google reCAPTCHA Secret Key - Only v2 or Invisible. v3 NOT supported.",
|
428 |
"tracking_cron_handle": "plugin_tracking_cron",
|
429 |
"tracking_post_url": "https://tracking.icontrolwp.com/track/plugin/shield",
|
430 |
"importexport_cron_name": "autoimport",
|
431 |
+
"href_privacy_policy": "https://shsec.io/wpshieldprivacypolicy",
|
432 |
"db_classes": {
|
433 |
"geoip": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\GeoIp\\Handler",
|
434 |
"notes": "\\FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\AdminNotes\\Handler"
|
src/config/feature-traffic.php
CHANGED
@@ -60,8 +60,8 @@
|
|
60 |
"section": "section_enable_plugin_feature_traffic",
|
61 |
"default": "N",
|
62 |
"type": "checkbox",
|
63 |
-
"link_info": "https://
|
64 |
-
"link_blog": "https://
|
65 |
"name": "Enable Traffic Watch",
|
66 |
"summary": "Enable (or Disable) The Traffic Watch Module",
|
67 |
"description": "Un-Checking this option will completely disable the Traffic Watch module."
|
@@ -106,7 +106,7 @@
|
|
106 |
"text": "Uptime Monitoring Services"
|
107 |
}
|
108 |
],
|
109 |
-
"link_info": "https://
|
110 |
"link_blog": "",
|
111 |
"name": "Traffic Log Exclusions",
|
112 |
"summary": "Select Which Types Of Requests To Exclude",
|
@@ -117,7 +117,7 @@
|
|
117 |
"section": "section_traffic_options",
|
118 |
"default": [],
|
119 |
"type": "array",
|
120 |
-
"link_info": "https://
|
121 |
"link_blog": "",
|
122 |
"name": "Custom Exclusions",
|
123 |
"summary": "Provide Custom Traffic Exclusions",
|
60 |
"section": "section_enable_plugin_feature_traffic",
|
61 |
"default": "N",
|
62 |
"type": "checkbox",
|
63 |
+
"link_info": "https://shsec.io/ed",
|
64 |
+
"link_blog": "https://shsec.io/ee",
|
65 |
"name": "Enable Traffic Watch",
|
66 |
"summary": "Enable (or Disable) The Traffic Watch Module",
|
67 |
"description": "Un-Checking this option will completely disable the Traffic Watch module."
|
106 |
"text": "Uptime Monitoring Services"
|
107 |
}
|
108 |
],
|
109 |
+
"link_info": "https://shsec.io/eb",
|
110 |
"link_blog": "",
|
111 |
"name": "Traffic Log Exclusions",
|
112 |
"summary": "Select Which Types Of Requests To Exclude",
|
117 |
"section": "section_traffic_options",
|
118 |
"default": [],
|
119 |
"type": "array",
|
120 |
+
"link_info": "https://shsec.io/ec",
|
121 |
"link_blog": "",
|
122 |
"name": "Custom Exclusions",
|
123 |
"summary": "Provide Custom Traffic Exclusions",
|
src/config/feature-user_management.php
CHANGED
@@ -75,7 +75,7 @@
|
|
75 |
"section": "section_enable_plugin_feature_user_accounts_management",
|
76 |
"default": "Y",
|
77 |
"type": "checkbox",
|
78 |
-
"link_info": "https://
|
79 |
"link_blog": "",
|
80 |
"name": "Enable User Management",
|
81 |
"summary": "Enable (or Disable) The User Management module",
|
@@ -88,7 +88,7 @@
|
|
88 |
"sensitive": false,
|
89 |
"default": "N",
|
90 |
"type": "checkbox",
|
91 |
-
"link_info": "https://
|
92 |
"link_blog": "",
|
93 |
"name": "User Login Notification Email",
|
94 |
"summary": "Send Email Notification To Each User Upon Successful Login",
|
@@ -158,8 +158,8 @@
|
|
158 |
"section": "section_passwords",
|
159 |
"type": "checkbox",
|
160 |
"default": "N",
|
161 |
-
"link_info": "https://
|
162 |
-
"link_blog": "https://
|
163 |
"name": "Enable Password Policies",
|
164 |
"summary": "Enable The Password Policies Below",
|
165 |
"description": "Turn on/off all password policies."
|
@@ -169,7 +169,7 @@
|
|
169 |
"section": "section_passwords",
|
170 |
"type": "checkbox",
|
171 |
"default": "Y",
|
172 |
-
"link_info": "https://
|
173 |
"link_blog": "",
|
174 |
"name": "Prevent Pwned Passwords",
|
175 |
"summary": "Prevent Use Of Pwned Passwords",
|
@@ -252,8 +252,8 @@
|
|
252 |
"premium": true,
|
253 |
"type": "checkbox",
|
254 |
"default": "N",
|
255 |
-
"link_info": "https://
|
256 |
-
"link_blog": "https://
|
257 |
"name": "Allow Manual User Suspension",
|
258 |
"summary": "Manually Suspend User Accounts To Prevent Login",
|
259 |
"description": "Users may be suspended by administrators to prevent login."
|
@@ -264,8 +264,8 @@
|
|
264 |
"premium": true,
|
265 |
"type": "checkbox",
|
266 |
"default": "Y",
|
267 |
-
"link_info": "https://
|
268 |
-
"link_blog": "https://
|
269 |
"name": "Auto-Suspend Expired Passwords",
|
270 |
"summary": "Automatically Suspend Users With Expired Passwords",
|
271 |
"description": "Suspend login by users and require password reset to unsuspend."
|
@@ -277,8 +277,8 @@
|
|
277 |
"type": "integer",
|
278 |
"default": 0,
|
279 |
"min": 0,
|
280 |
-
"link_info": "https://
|
281 |
-
"link_blog": "https://
|
282 |
"name": "Auto-Suspend Idle Users",
|
283 |
"summary": "Automatically Suspend Idle User Accounts",
|
284 |
"description": "Prevent login by idle users and require password reset to unsuspend."
|
@@ -293,7 +293,7 @@
|
|
293 |
"editor",
|
294 |
"author"
|
295 |
],
|
296 |
-
"link_info": "https://
|
297 |
"link_blog": "",
|
298 |
"name": "Auto-Suspend Idle Users",
|
299 |
"summary": "Automatically Suspend Idle User Accounts",
|
75 |
"section": "section_enable_plugin_feature_user_accounts_management",
|
76 |
"default": "Y",
|
77 |
"type": "checkbox",
|
78 |
+
"link_info": "https://shsec.io/e3",
|
79 |
"link_blog": "",
|
80 |
"name": "Enable User Management",
|
81 |
"summary": "Enable (or Disable) The User Management module",
|
88 |
"sensitive": false,
|
89 |
"default": "N",
|
90 |
"type": "checkbox",
|
91 |
+
"link_info": "https://shsec.io/e2",
|
92 |
"link_blog": "",
|
93 |
"name": "User Login Notification Email",
|
94 |
"summary": "Send Email Notification To Each User Upon Successful Login",
|
158 |
"section": "section_passwords",
|
159 |
"type": "checkbox",
|
160 |
"default": "N",
|
161 |
+
"link_info": "https://shsec.io/e1",
|
162 |
+
"link_blog": "https://shsec.io/c4",
|
163 |
"name": "Enable Password Policies",
|
164 |
"summary": "Enable The Password Policies Below",
|
165 |
"description": "Turn on/off all password policies."
|
169 |
"section": "section_passwords",
|
170 |
"type": "checkbox",
|
171 |
"default": "Y",
|
172 |
+
"link_info": "https://shsec.io/by",
|
173 |
"link_blog": "",
|
174 |
"name": "Prevent Pwned Passwords",
|
175 |
"summary": "Prevent Use Of Pwned Passwords",
|
252 |
"premium": true,
|
253 |
"type": "checkbox",
|
254 |
"default": "N",
|
255 |
+
"link_info": "https://shsec.io/fq",
|
256 |
+
"link_blog": "https://shsec.io/fr",
|
257 |
"name": "Allow Manual User Suspension",
|
258 |
"summary": "Manually Suspend User Accounts To Prevent Login",
|
259 |
"description": "Users may be suspended by administrators to prevent login."
|
264 |
"premium": true,
|
265 |
"type": "checkbox",
|
266 |
"default": "Y",
|
267 |
+
"link_info": "https://shsec.io/fs",
|
268 |
+
"link_blog": "https://shsec.io/fr",
|
269 |
"name": "Auto-Suspend Expired Passwords",
|
270 |
"summary": "Automatically Suspend Users With Expired Passwords",
|
271 |
"description": "Suspend login by users and require password reset to unsuspend."
|
277 |
"type": "integer",
|
278 |
"default": 0,
|
279 |
"min": 0,
|
280 |
+
"link_info": "https://shsec.io/ft",
|
281 |
+
"link_blog": "https://shsec.io/fr",
|
282 |
"name": "Auto-Suspend Idle Users",
|
283 |
"summary": "Automatically Suspend Idle User Accounts",
|
284 |
"description": "Prevent login by idle users and require password reset to unsuspend."
|
293 |
"editor",
|
294 |
"author"
|
295 |
],
|
296 |
+
"link_info": "https://shsec.io/ft",
|
297 |
"link_blog": "",
|
298 |
"name": "Auto-Suspend Idle Users",
|
299 |
"summary": "Automatically Suspend Idle User Accounts",
|
src/features/admin_access_restriction.php
CHANGED
@@ -504,83 +504,4 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
|
|
504 |
protected function getNamespaceBase() {
|
505 |
return 'SecurityAdmin';
|
506 |
}
|
507 |
-
|
508 |
-
/**
|
509 |
-
* @return string
|
510 |
-
* @deprecated 8.1
|
511 |
-
*/
|
512 |
-
protected function getAccessKeyHash() {
|
513 |
-
return $this->getOpt( 'admin_access_key' );
|
514 |
-
}
|
515 |
-
|
516 |
-
/**
|
517 |
-
* @return bool
|
518 |
-
* @deprecated 8.1
|
519 |
-
*/
|
520 |
-
public function getAdminAccessArea_Options() {
|
521 |
-
return $this->isOpt( 'admin_access_restrict_options', 'Y' );
|
522 |
-
}
|
523 |
-
|
524 |
-
/**
|
525 |
-
* @return array
|
526 |
-
* @deprecated 8.1
|
527 |
-
*/
|
528 |
-
public function getAdminAccessArea_Plugins() {
|
529 |
-
return $this->getAdminAccessArea( 'plugins' );
|
530 |
-
}
|
531 |
-
|
532 |
-
/**
|
533 |
-
* @return array
|
534 |
-
* @deprecated 8.1
|
535 |
-
*/
|
536 |
-
public function getAdminAccessArea_Themes() {
|
537 |
-
return $this->getAdminAccessArea( 'themes' );
|
538 |
-
}
|
539 |
-
|
540 |
-
/**
|
541 |
-
* @return array
|
542 |
-
* @deprecated 8.1
|
543 |
-
*/
|
544 |
-
public function getAdminAccessArea_Posts() {
|
545 |
-
return $this->getAdminAccessArea( 'posts' );
|
546 |
-
}
|
547 |
-
|
548 |
-
/**
|
549 |
-
* @param string $sArea one of plugins, themes
|
550 |
-
* @return array
|
551 |
-
* @deprecated 8.1
|
552 |
-
*/
|
553 |
-
public function getAdminAccessArea( $sArea = 'plugins' ) {
|
554 |
-
$aSettings = $this->getOpt( 'admin_access_restrict_'.$sArea, [] );
|
555 |
-
return !is_array( $aSettings ) ? [] : $aSettings;
|
556 |
-
}
|
557 |
-
|
558 |
-
/**
|
559 |
-
* TODO: Bug where if $sType is defined, it'll be set to 'wp' anyway
|
560 |
-
* @param string $sType - wp or wpms
|
561 |
-
* @return array
|
562 |
-
* @deprecated 8.1
|
563 |
-
*/
|
564 |
-
public function getOptionsToRestrict( $sType = '' ) {
|
565 |
-
$sType = empty( $sType ) ? ( Services::WpGeneral()->isMultisite() ? 'wpms' : 'wp' ) : 'wp';
|
566 |
-
$aOptions = $this->getRestrictedOptions();
|
567 |
-
return ( isset( $aOptions[ $sType.'_options' ] ) && is_array( $aOptions[ $sType.'_options' ] ) ) ? $aOptions[ $sType.'_options' ] : [];
|
568 |
-
}
|
569 |
-
|
570 |
-
/**
|
571 |
-
* @return array
|
572 |
-
* @deprecated 8.1
|
573 |
-
*/
|
574 |
-
public function getRestrictedOptions() {
|
575 |
-
$aOptions = $this->getDef( 'options_to_restrict' );
|
576 |
-
return is_array( $aOptions ) ? $aOptions : [];
|
577 |
-
}
|
578 |
-
|
579 |
-
/**
|
580 |
-
* @return bool
|
581 |
-
* @deprecated 8.1
|
582 |
-
*/
|
583 |
-
public function isAdminAccessAdminUsersEnabled() {
|
584 |
-
return $this->isOpt( 'admin_access_restrict_admin_users', 'Y' );
|
585 |
-
}
|
586 |
}
|
504 |
protected function getNamespaceBase() {
|
505 |
return 'SecurityAdmin';
|
506 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
507 |
}
|
src/features/audit_trail.php
CHANGED
@@ -23,16 +23,6 @@ class ICWP_WPSF_FeatureHandler_AuditTrail extends ICWP_WPSF_FeatureHandler_BaseW
|
|
23 |
&& parent::isReadyToExecute();
|
24 |
}
|
25 |
|
26 |
-
/**
|
27 |
-
* @return int
|
28 |
-
* @deprecated 8.1 - TODO: Need to handle isPremium() within Options class
|
29 |
-
*/
|
30 |
-
public function getMaxEntries() {
|
31 |
-
/** @var AuditTrail\Options $oOpts */
|
32 |
-
$oOpts = $this->getOptions();
|
33 |
-
return $this->isPremium() ? (int)$oOpts->getOpt( 'audit_trail_max_entries' ) : $oOpts->getDefaultMaxEntries();
|
34 |
-
}
|
35 |
-
|
36 |
/**
|
37 |
* @return array
|
38 |
*/
|
@@ -146,7 +136,7 @@ class ICWP_WPSF_FeatureHandler_AuditTrail extends ICWP_WPSF_FeatureHandler_BaseW
|
|
146 |
$oOpts->isAuditThemes() ? $aAudit[] = __( 'themes', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'themes', 'wp-simple-firewall' );
|
147 |
$oOpts->isAuditPosts() ? $aAudit[] = __( 'posts', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'posts', 'wp-simple-firewall' );
|
148 |
$oOpts->isAuditEmails() ? $aAudit[] = __( 'emails', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'emails', 'wp-simple-firewall' );
|
149 |
-
$
|
150 |
|
151 |
if ( empty( $aNonAudit ) ) {
|
152 |
$aThis[ 'key_opts' ][ 'audit' ] = [
|
@@ -195,108 +185,4 @@ class ICWP_WPSF_FeatureHandler_AuditTrail extends ICWP_WPSF_FeatureHandler_BaseW
|
|
195 |
protected function getNamespaceBase() {
|
196 |
return 'AuditTrail';
|
197 |
}
|
198 |
-
|
199 |
-
/**
|
200 |
-
* @return bool
|
201 |
-
* @deprecated 8.1
|
202 |
-
*/
|
203 |
-
public function isAuditEmails() {
|
204 |
-
return $this->isOpt( 'enable_audit_context_emails', 'Y' );
|
205 |
-
}
|
206 |
-
|
207 |
-
/**
|
208 |
-
* @return bool
|
209 |
-
* @deprecated 8.1
|
210 |
-
*/
|
211 |
-
public function isAuditPlugins() {
|
212 |
-
return $this->isOpt( 'enable_audit_context_plugins', 'Y' );
|
213 |
-
}
|
214 |
-
|
215 |
-
/**
|
216 |
-
* @return bool
|
217 |
-
* @deprecated 8.1
|
218 |
-
*/
|
219 |
-
public function isAuditPosts() {
|
220 |
-
return $this->isOpt( 'enable_audit_context_posts', 'Y' );
|
221 |
-
}
|
222 |
-
|
223 |
-
/**
|
224 |
-
* @return bool
|
225 |
-
* @deprecated 8.1
|
226 |
-
*/
|
227 |
-
public function isAuditShield() {
|
228 |
-
return $this->isOpt( 'enable_audit_context_wpsf', 'Y' );
|
229 |
-
}
|
230 |
-
|
231 |
-
/**
|
232 |
-
* @return bool
|
233 |
-
* @deprecated 8.1
|
234 |
-
*/
|
235 |
-
public function isAuditThemes() {
|
236 |
-
return $this->isOpt( 'enable_audit_context_themes', 'Y' );
|
237 |
-
}
|
238 |
-
|
239 |
-
/**
|
240 |
-
* @return bool
|
241 |
-
* @deprecated 8.1
|
242 |
-
*/
|
243 |
-
public function isAuditUsers() {
|
244 |
-
return $this->isOpt( 'enable_audit_context_users', 'Y' );
|
245 |
-
}
|
246 |
-
|
247 |
-
/**
|
248 |
-
* @return bool
|
249 |
-
* @deprecated 8.1
|
250 |
-
*/
|
251 |
-
public function isAuditWp() {
|
252 |
-
return $this->isOpt( 'enable_audit_context_wordpress', 'Y' );
|
253 |
-
}
|
254 |
-
|
255 |
-
/**
|
256 |
-
* @return int
|
257 |
-
* @deprecated 8.1
|
258 |
-
*/
|
259 |
-
public function getAutoCleanDays() {
|
260 |
-
return (int)$this->getOpt( 'audit_trail_auto_clean' );
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
* @return bool
|
265 |
-
* @deprecated 8.1
|
266 |
-
*/
|
267 |
-
public function isEnabledAuditing() {
|
268 |
-
/** @var AuditTrail\Options $oOpts */
|
269 |
-
$oOpts = $this->getOptions();
|
270 |
-
return $oOpts->isAuditEmails()
|
271 |
-
|| $oOpts->isAuditPlugins()
|
272 |
-
|| $oOpts->isAuditThemes()
|
273 |
-
|| $oOpts->isAuditPosts()
|
274 |
-
|| $oOpts->isAuditShield()
|
275 |
-
|| $oOpts->isAuditUsers()
|
276 |
-
|| $oOpts->isAuditWp();
|
277 |
-
}
|
278 |
-
|
279 |
-
/**
|
280 |
-
* @return bool
|
281 |
-
* @deprecated 8.1
|
282 |
-
*/
|
283 |
-
public function isEnabledChangeTracking() {
|
284 |
-
return !$this->isOpt( 'enable_change_tracking', 'disabled' );
|
285 |
-
}
|
286 |
-
|
287 |
-
/**
|
288 |
-
* @return int
|
289 |
-
* @deprecated 8.1
|
290 |
-
*/
|
291 |
-
public function getDefaultMaxEntries() {
|
292 |
-
return $this->getDef( 'audit_trail_default_max_entries' );
|
293 |
-
}
|
294 |
-
|
295 |
-
/**
|
296 |
-
* @return Shield\Databases\AuditTrail\Handler
|
297 |
-
* @deprecated 8.1.2
|
298 |
-
*/
|
299 |
-
protected function loadDbHandler() {
|
300 |
-
return new Shield\Databases\AuditTrail\Handler();
|
301 |
-
}
|
302 |
}
|
23 |
&& parent::isReadyToExecute();
|
24 |
}
|
25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
/**
|
27 |
* @return array
|
28 |
*/
|
136 |
$oOpts->isAuditThemes() ? $aAudit[] = __( 'themes', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'themes', 'wp-simple-firewall' );
|
137 |
$oOpts->isAuditPosts() ? $aAudit[] = __( 'posts', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'posts', 'wp-simple-firewall' );
|
138 |
$oOpts->isAuditEmails() ? $aAudit[] = __( 'emails', 'wp-simple-firewall' ) : $aNonAudit[] = __( 'emails', 'wp-simple-firewall' );
|
139 |
+
$oOpts->isAuditWp() ? $aAudit[] = 'WP' : $aNonAudit[] = 'WP';
|
140 |
|
141 |
if ( empty( $aNonAudit ) ) {
|
142 |
$aThis[ 'key_opts' ][ 'audit' ] = [
|
185 |
protected function getNamespaceBase() {
|
186 |
return 'AuditTrail';
|
187 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
}
|
src/features/autoupdates.php
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
4 |
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
@@ -15,144 +16,14 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
|
|
15 |
}
|
16 |
}
|
17 |
|
18 |
-
/**
|
19 |
-
* @return string[]
|
20 |
-
*/
|
21 |
-
public function getAutoupdatePlugins() {
|
22 |
-
$aSelected = [];
|
23 |
-
if ( $this->isAutoupdateIndividualPlugins() ) {
|
24 |
-
$aSelected = $this->getOpt( 'selected_plugins', [] );
|
25 |
-
if ( !is_array( $aSelected ) ) {
|
26 |
-
$aSelected = [];
|
27 |
-
}
|
28 |
-
}
|
29 |
-
return $aSelected;
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @return array
|
34 |
-
*/
|
35 |
-
public function getDelayTracking() {
|
36 |
-
$aTracking = $this->getOpt( 'delay_tracking', [] );
|
37 |
-
if ( !is_array( $aTracking ) ) {
|
38 |
-
$aTracking = [];
|
39 |
-
}
|
40 |
-
$aTracking = $this->loadDP()->mergeArraysRecursive(
|
41 |
-
[
|
42 |
-
'core' => [],
|
43 |
-
'plugins' => [],
|
44 |
-
'themes' => [],
|
45 |
-
],
|
46 |
-
$aTracking
|
47 |
-
);
|
48 |
-
$this->setOpt( 'delay_tracking', $aTracking );
|
49 |
-
|
50 |
-
return $aTracking;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* @return int
|
55 |
-
*/
|
56 |
-
public function getDelayUpdatesPeriod() {
|
57 |
-
return $this->isPremium() ? $this->getOpt( 'update_delay', 0 )*DAY_IN_SECONDS : 0;
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* @param array $aTrackingInfo
|
62 |
-
* @return $this
|
63 |
-
*/
|
64 |
-
public function setDelayTracking( $aTrackingInfo ) {
|
65 |
-
return $this->setOpt( 'delay_tracking', $aTrackingInfo );
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* @return bool
|
70 |
-
*/
|
71 |
-
public function isDisableAllAutoUpdates() {
|
72 |
-
return $this->isOpt( 'enable_autoupdate_disable_all', 'Y' );
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* @return bool
|
77 |
-
*/
|
78 |
-
public function isAutoupdateAllPlugins() {
|
79 |
-
return $this->isOpt( 'enable_autoupdate_plugins', 'Y' );
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* @premium
|
84 |
-
* @return bool
|
85 |
-
*/
|
86 |
-
public function isAutoupdateIndividualPlugins() {
|
87 |
-
return $this->isOpt( 'enable_individual_autoupdate_plugins', 'Y' );
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* @return bool
|
92 |
-
*/
|
93 |
-
public function isDelayUpdates() {
|
94 |
-
return $this->getDelayUpdatesPeriod() > 0;
|
95 |
-
}
|
96 |
-
|
97 |
-
/**
|
98 |
-
* @param string $sPluginFile
|
99 |
-
* @return bool
|
100 |
-
*/
|
101 |
-
public function isPluginSetToAutoupdate( $sPluginFile ) {
|
102 |
-
return in_array( $sPluginFile, $this->getAutoupdatePlugins() );
|
103 |
-
}
|
104 |
-
|
105 |
-
/**
|
106 |
-
* @return bool
|
107 |
-
*/
|
108 |
-
public function isSendAutoupdatesNotificationEmail() {
|
109 |
-
return $this->isOpt( 'enable_upgrade_notification_email', 'Y' );
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* @return string
|
114 |
-
*/
|
115 |
-
public function getSelfAutoUpdateOpt() {
|
116 |
-
return $this->getOpt( 'autoupdate_plugin_self' );
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* @return bool
|
121 |
-
*/
|
122 |
-
public function isAutoUpdateCoreMinor() {
|
123 |
-
return !$this->isOpt( 'autoupdate_core', 'core_never' );
|
124 |
-
}
|
125 |
-
|
126 |
-
/**
|
127 |
-
* @return bool
|
128 |
-
*/
|
129 |
-
public function isAutoUpdateCoreMajor() {
|
130 |
-
return $this->isOpt( 'autoupdate_core', 'core_major' );
|
131 |
-
}
|
132 |
-
|
133 |
-
/**
|
134 |
-
* @param string $sPluginFile
|
135 |
-
* @return $this
|
136 |
-
*/
|
137 |
-
public function setPluginToAutoUpdate( $sPluginFile ) {
|
138 |
-
$aPlugins = $this->getAutoupdatePlugins();
|
139 |
-
$nKey = array_search( $sPluginFile, $aPlugins );
|
140 |
-
|
141 |
-
if ( $nKey === false ) {
|
142 |
-
$aPlugins[] = $sPluginFile;
|
143 |
-
}
|
144 |
-
else {
|
145 |
-
unset( $aPlugins[ $nKey ] );
|
146 |
-
}
|
147 |
-
|
148 |
-
return $this->setOpt( 'selected_plugins', $aPlugins );
|
149 |
-
}
|
150 |
-
|
151 |
/**
|
152 |
* @param array $aAllNotices
|
153 |
* @return array
|
154 |
*/
|
155 |
public function addInsightsNoticeData( $aAllNotices ) {
|
|
|
|
|
|
|
156 |
$aNotices = [
|
157 |
'title' => __( 'Automatic Updates', 'wp-simple-firewall' ),
|
158 |
'messages' => []
|
@@ -160,7 +31,7 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
|
|
160 |
{ //really disabled?
|
161 |
$oWp = Services::WpGeneral();
|
162 |
if ( $this->isModOptEnabled() ) {
|
163 |
-
if ( $
|
164 |
$aNotices[ 'messages' ][ 'disabled_auto' ] = [
|
165 |
'title' => 'Auto Updates Not Really Disabled',
|
166 |
'message' => __( 'Automatic Updates Are Not Disabled As Expected.', 'wp-simple-firewall' ),
|
@@ -184,6 +55,9 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
|
|
184 |
* @return array
|
185 |
*/
|
186 |
public function addInsightsConfigData( $aAllData ) {
|
|
|
|
|
|
|
187 |
$aThis = [
|
188 |
'strings' => [
|
189 |
'title' => __( 'Automatic Updates', 'wp-simple-firewall' ),
|
@@ -198,7 +72,7 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
|
|
198 |
}
|
199 |
else {
|
200 |
|
201 |
-
$bAllDisabled = $
|
202 |
if ( $bAllDisabled ) {
|
203 |
$aThis[ 'key_opts' ][ 'disabled' ] = [
|
204 |
'name' => __( 'Disabled All', 'wp-simple-firewall' ),
|
@@ -222,7 +96,7 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
|
|
222 |
'href' => $this->getUrl_DirectLinkToOption( 'autoupdate_core' ),
|
223 |
];
|
224 |
|
225 |
-
$bHasDelay = $this->isModOptEnabled() && $
|
226 |
$aThis[ 'key_opts' ][ 'delay' ] = [
|
227 |
'name' => __( 'Update Delay', 'wp-simple-firewall' ),
|
228 |
'enabled' => $bHasDelay,
|
@@ -235,7 +109,7 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
|
|
235 |
|
236 |
$sName = $this->getCon()->getHumanName();
|
237 |
$bSelfAuto = $this->isModOptEnabled()
|
238 |
-
&& in_array( $
|
239 |
$aThis[ 'key_opts' ][ 'self' ] = [
|
240 |
'name' => __( 'Self Auto-Update', 'wp-simple-firewall' ),
|
241 |
'enabled' => $bSelfAuto,
|
@@ -258,4 +132,151 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
|
|
258 |
protected function getNamespaceBase() {
|
259 |
return 'Autoupdates';
|
260 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
261 |
}
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Autoupdates;
|
5 |
use FernleafSystems\Wordpress\Services\Services;
|
6 |
|
7 |
class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
16 |
}
|
17 |
}
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
/**
|
20 |
* @param array $aAllNotices
|
21 |
* @return array
|
22 |
*/
|
23 |
public function addInsightsNoticeData( $aAllNotices ) {
|
24 |
+
/** @var Autoupdates\Options $oOpts */
|
25 |
+
$oOpts = $this->getOptions();
|
26 |
+
|
27 |
$aNotices = [
|
28 |
'title' => __( 'Automatic Updates', 'wp-simple-firewall' ),
|
29 |
'messages' => []
|
31 |
{ //really disabled?
|
32 |
$oWp = Services::WpGeneral();
|
33 |
if ( $this->isModOptEnabled() ) {
|
34 |
+
if ( $oOpts->isDisableAllAutoUpdates() && !$oWp->getWpAutomaticUpdater()->is_disabled() ) {
|
35 |
$aNotices[ 'messages' ][ 'disabled_auto' ] = [
|
36 |
'title' => 'Auto Updates Not Really Disabled',
|
37 |
'message' => __( 'Automatic Updates Are Not Disabled As Expected.', 'wp-simple-firewall' ),
|
55 |
* @return array
|
56 |
*/
|
57 |
public function addInsightsConfigData( $aAllData ) {
|
58 |
+
/** @var Autoupdates\Options $oOpts */
|
59 |
+
$oOpts = $this->getOptions();
|
60 |
+
|
61 |
$aThis = [
|
62 |
'strings' => [
|
63 |
'title' => __( 'Automatic Updates', 'wp-simple-firewall' ),
|
72 |
}
|
73 |
else {
|
74 |
|
75 |
+
$bAllDisabled = $oOpts->isDisableAllAutoUpdates();
|
76 |
if ( $bAllDisabled ) {
|
77 |
$aThis[ 'key_opts' ][ 'disabled' ] = [
|
78 |
'name' => __( 'Disabled All', 'wp-simple-firewall' ),
|
96 |
'href' => $this->getUrl_DirectLinkToOption( 'autoupdate_core' ),
|
97 |
];
|
98 |
|
99 |
+
$bHasDelay = $this->isModOptEnabled() && $oOpts->getDelayUpdatesPeriod();
|
100 |
$aThis[ 'key_opts' ][ 'delay' ] = [
|
101 |
'name' => __( 'Update Delay', 'wp-simple-firewall' ),
|
102 |
'enabled' => $bHasDelay,
|
109 |
|
110 |
$sName = $this->getCon()->getHumanName();
|
111 |
$bSelfAuto = $this->isModOptEnabled()
|
112 |
+
&& in_array( $oOpts->getSelfAutoUpdateOpt(), [ 'auto', 'immediate' ] );
|
113 |
$aThis[ 'key_opts' ][ 'self' ] = [
|
114 |
'name' => __( 'Self Auto-Update', 'wp-simple-firewall' ),
|
115 |
'enabled' => $bSelfAuto,
|
132 |
protected function getNamespaceBase() {
|
133 |
return 'Autoupdates';
|
134 |
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @return bool
|
138 |
+
* @deprecated 8.4
|
139 |
+
*/
|
140 |
+
public function isSendAutoupdatesNotificationEmail() {
|
141 |
+
return $this->isOpt( 'enable_upgrade_notification_email', 'Y' );
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @return bool
|
146 |
+
* @deprecated 8.4
|
147 |
+
*/
|
148 |
+
public function isDisableAllAutoUpdates() {
|
149 |
+
return $this->isOpt( 'enable_autoupdate_disable_all', 'Y' );
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* @return bool
|
154 |
+
* @deprecated 8.4
|
155 |
+
*/
|
156 |
+
public function isAutoUpdateCoreMajor() {
|
157 |
+
return $this->isOpt( 'autoupdate_core', 'core_major' );
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* @return bool
|
162 |
+
* @deprecated 8.4
|
163 |
+
*/
|
164 |
+
public function isAutoUpdateCoreMinor() {
|
165 |
+
return !$this->isOpt( 'autoupdate_core', 'core_never' );
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @return string
|
170 |
+
* @deprecated 8.4
|
171 |
+
*/
|
172 |
+
public function getSelfAutoUpdateOpt() {
|
173 |
+
return $this->getOpt( 'autoupdate_plugin_self' );
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* @return array
|
178 |
+
* @deprecated 8.4
|
179 |
+
*/
|
180 |
+
public function getDelayTracking() {
|
181 |
+
$aTracking = $this->getOpt( 'delay_tracking', [] );
|
182 |
+
if ( !is_array( $aTracking ) ) {
|
183 |
+
$aTracking = [];
|
184 |
+
}
|
185 |
+
$aTracking = Services::DataManipulation()->mergeArraysRecursive(
|
186 |
+
[
|
187 |
+
'core' => [],
|
188 |
+
'plugins' => [],
|
189 |
+
'themes' => [],
|
190 |
+
],
|
191 |
+
$aTracking
|
192 |
+
);
|
193 |
+
$this->setOpt( 'delay_tracking', $aTracking );
|
194 |
+
|
195 |
+
return $aTracking;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* @return string[]
|
200 |
+
* @deprecated 8.4
|
201 |
+
*/
|
202 |
+
public function getAutoupdatePlugins() {
|
203 |
+
$aSelected = [];
|
204 |
+
if ( $this->isAutoupdateIndividualPlugins() ) {
|
205 |
+
$aSelected = $this->getOpt( 'selected_plugins', [] );
|
206 |
+
if ( !is_array( $aSelected ) ) {
|
207 |
+
$aSelected = [];
|
208 |
+
}
|
209 |
+
}
|
210 |
+
return $aSelected;
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* @return int
|
215 |
+
* @deprecated 8.4
|
216 |
+
*/
|
217 |
+
public function getDelayUpdatesPeriod() {
|
218 |
+
return $this->isPremium() ? $this->getOpt( 'update_delay', 0 )*DAY_IN_SECONDS : 0;
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* @param array $aTrackingInfo
|
223 |
+
* @return $this
|
224 |
+
* @deprecated 8.4
|
225 |
+
*/
|
226 |
+
public function setDelayTracking( $aTrackingInfo ) {
|
227 |
+
return $this->setOpt( 'delay_tracking', $aTrackingInfo );
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* @return bool
|
232 |
+
* @deprecated 8.4
|
233 |
+
*/
|
234 |
+
public function isAutoupdateAllPlugins() {
|
235 |
+
return $this->isOpt( 'enable_autoupdate_plugins', 'Y' );
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* @premium
|
240 |
+
* @return bool
|
241 |
+
* @deprecated 8.4
|
242 |
+
*/
|
243 |
+
public function isAutoupdateIndividualPlugins() {
|
244 |
+
return $this->isOpt( 'enable_individual_autoupdate_plugins', 'Y' );
|
245 |
+
}
|
246 |
+
|
247 |
+
/**
|
248 |
+
* @return bool
|
249 |
+
* @deprecated 8.4
|
250 |
+
*/
|
251 |
+
public function isDelayUpdates() {
|
252 |
+
return $this->getDelayUpdatesPeriod() > 0;
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* @param string $sPluginFile
|
257 |
+
* @return bool
|
258 |
+
* @deprecated 8.4
|
259 |
+
*/
|
260 |
+
public function isPluginSetToAutoupdate( $sPluginFile ) {
|
261 |
+
return in_array( $sPluginFile, $this->getAutoupdatePlugins() );
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* @param string $sPluginFile
|
266 |
+
* @return $this
|
267 |
+
* @deprecated 8.4
|
268 |
+
*/
|
269 |
+
public function setPluginToAutoUpdate( $sPluginFile ) {
|
270 |
+
$aPlugins = $this->getAutoupdatePlugins();
|
271 |
+
$nKey = array_search( $sPluginFile, $aPlugins );
|
272 |
+
|
273 |
+
if ( $nKey === false ) {
|
274 |
+
$aPlugins[] = $sPluginFile;
|
275 |
+
}
|
276 |
+
else {
|
277 |
+
unset( $aPlugins[ $nKey ] );
|
278 |
+
}
|
279 |
+
|
280 |
+
return $this->setOpt( 'selected_plugins', $aPlugins );
|
281 |
+
}
|
282 |
}
|
src/features/base.php
CHANGED
@@ -28,7 +28,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
28 |
private static $oEmailHandler;
|
29 |
|
30 |
/**
|
31 |
-
* @var
|
32 |
*/
|
33 |
private $oProcessor;
|
34 |
|
@@ -37,11 +37,6 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
37 |
*/
|
38 |
private $oWizard;
|
39 |
|
40 |
-
/**
|
41 |
-
* @var Shield\Databases\Base\Handler
|
42 |
-
*/
|
43 |
-
private $oDbh;
|
44 |
-
|
45 |
/**
|
46 |
* @var Shield\Modules\Base\Strings
|
47 |
*/
|
@@ -130,6 +125,9 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
130 |
add_filter( $this->prefix( 'is_event_supported' ), function ( $bSupported, $sEventTag ) {
|
131 |
return $bSupported || $this->isSupportedEvent( $sEventTag );
|
132 |
}, 10, 2 );
|
|
|
|
|
|
|
133 |
|
134 |
add_action( 'admin_enqueue_scripts', [ $this, 'onWpEnqueueAdminJs' ], 100 );
|
135 |
|
@@ -1012,15 +1010,6 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
1012 |
return $this->oWizard;
|
1013 |
}
|
1014 |
|
1015 |
-
/**
|
1016 |
-
* Saves the options to the WordPress Options store.
|
1017 |
-
* @return void
|
1018 |
-
* @deprecated 8.1
|
1019 |
-
*/
|
1020 |
-
public function savePluginOptions() {
|
1021 |
-
$this->saveModOptions();
|
1022 |
-
}
|
1023 |
-
|
1024 |
/**
|
1025 |
* @return $this
|
1026 |
*/
|
@@ -1533,8 +1522,8 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
1533 |
'has_wizard' => $this->hasWizard(),
|
1534 |
],
|
1535 |
'hrefs' => [
|
1536 |
-
'go_pro' => 'https://
|
1537 |
-
'goprofooter' => 'https://
|
1538 |
'wizard_link' => $this->getUrl_WizardLanding(),
|
1539 |
'wizard_landing' => $this->getUrl_WizardLanding()
|
1540 |
],
|
@@ -1924,53 +1913,21 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
1924 |
return !empty( $sId );
|
1925 |
}
|
1926 |
|
1927 |
-
/**
|
1928 |
-
* @param string $sOpt
|
1929 |
-
* @param int $nAt
|
1930 |
-
* @return $this
|
1931 |
-
* @deprecated 8.1 - TODO: Be careful when updating to use `Options` as this is newly-added in 8.1
|
1932 |
-
*/
|
1933 |
-
protected function setOptAt( $sOpt, $nAt = null ) {
|
1934 |
-
$nAt = is_null( $nAt ) ? Services::Request()->ts() : max( 0, (int)$nAt );
|
1935 |
-
return $this->setOpt( $sOpt, $nAt );
|
1936 |
-
}
|
1937 |
-
|
1938 |
/**
|
1939 |
* @return null|Shield\Modules\Base\ShieldOptions|mixed
|
1940 |
*/
|
1941 |
public function getOptions() {
|
1942 |
if ( !isset( $this->oOpts ) ) {
|
1943 |
-
|
1944 |
-
if ( @class_exists( '\FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Options' ) ) {
|
1945 |
-
$oOpts = $this->loadOptions()->setMod( $this );;
|
1946 |
-
}
|
1947 |
-
else {
|
1948 |
-
$oOpts = new \ICWP_WPSF_OptionsVO();
|
1949 |
-
}
|
1950 |
-
|
1951 |
$oCon = $this->getCon();
|
1952 |
-
$this->oOpts = $
|
1953 |
-
|
1954 |
-
|
1955 |
-
|
|
|
1956 |
}
|
1957 |
return $this->oOpts;
|
1958 |
}
|
1959 |
|
1960 |
-
/**
|
1961 |
-
* The primary DB for the
|
1962 |
-
* @return null|Shield\Databases\Base\Handler|mixed
|
1963 |
-
* @deprecated 8.1.2
|
1964 |
-
*/
|
1965 |
-
public function getDbHandler() {
|
1966 |
-
// TODO: remove this IF, as it's a stop-gap for the newer implementation (below)
|
1967 |
-
if ( $this->oDbh instanceof Shield\Databases\Base\Handler ) {
|
1968 |
-
return $this->oDbh;
|
1969 |
-
}
|
1970 |
-
|
1971 |
-
return $this->getPrimaryDbHandler();
|
1972 |
-
}
|
1973 |
-
|
1974 |
/**
|
1975 |
* The primary DB for the
|
1976 |
* @return null|Shield\Databases\Base\Handler|mixed
|
@@ -2051,23 +2008,17 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends Shield\Deprecated\Foundatio
|
|
2051 |
}
|
2052 |
|
2053 |
/**
|
2054 |
-
*
|
2055 |
-
* @
|
2056 |
-
|
2057 |
-
public function getOptionsVo() {
|
2058 |
-
return $this->getOptions();
|
2059 |
-
}
|
2060 |
-
|
2061 |
-
/**
|
2062 |
-
* @deprecated 8.1
|
2063 |
*/
|
2064 |
-
|
2065 |
-
$this->
|
2066 |
}
|
2067 |
|
2068 |
/**
|
2069 |
* @return Shield\Databases\Base\Handler|mixed|false
|
2070 |
-
* @deprecated 8.
|
2071 |
*/
|
2072 |
protected function loadDbHandler() {
|
2073 |
return false;
|
28 |
private static $oEmailHandler;
|
29 |
|
30 |
/**
|
31 |
+
* @var Shield\Modules\Base\BaseProcessor
|
32 |
*/
|
33 |
private $oProcessor;
|
34 |
|
37 |
*/
|
38 |
private $oWizard;
|
39 |
|
|
|
|
|
|
|
|
|
|
|
40 |
/**
|
41 |
* @var Shield\Modules\Base\Strings
|
42 |
*/
|
125 |
add_filter( $this->prefix( 'is_event_supported' ), function ( $bSupported, $sEventTag ) {
|
126 |
return $bSupported || $this->isSupportedEvent( $sEventTag );
|
127 |
}, 10, 2 );
|
128 |
+
add_filter( $this->prefix( 'get_all_events' ), function ( $aEvents ) {
|
129 |
+
return array_merge( $aEvents, $this->getEvents() );
|
130 |
+
} );
|
131 |
|
132 |
add_action( 'admin_enqueue_scripts', [ $this, 'onWpEnqueueAdminJs' ], 100 );
|
133 |
|
1010 |
return $this->oWizard;
|
1011 |
}
|
1012 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1013 |
/**
|
1014 |
* @return $this
|
1015 |
*/
|
1522 |
'has_wizard' => $this->hasWizard(),
|
1523 |
],
|
1524 |
'hrefs' => [
|
1525 |
+
'go_pro' => 'https://shsec.io/shieldgoprofeature',
|
1526 |
+
'goprofooter' => 'https://shsec.io/goprofooter',
|
1527 |
'wizard_link' => $this->getUrl_WizardLanding(),
|
1528 |
'wizard_landing' => $this->getUrl_WizardLanding()
|
1529 |
],
|
1913 |
return !empty( $sId );
|
1914 |
}
|
1915 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1916 |
/**
|
1917 |
* @return null|Shield\Modules\Base\ShieldOptions|mixed
|
1918 |
*/
|
1919 |
public function getOptions() {
|
1920 |
if ( !isset( $this->oOpts ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1921 |
$oCon = $this->getCon();
|
1922 |
+
$this->oOpts = $this->loadOptions()->setMod( $this );
|
1923 |
+
$this->oOpts->setPathToConfig( $oCon->getPath_ConfigFile( $this->getSlug() ) )
|
1924 |
+
->setRebuildFromFile( $oCon->getIsRebuildOptionsFromFile() )
|
1925 |
+
->setOptionsStorageKey( $this->getOptionsStorageKey() )
|
1926 |
+
->setIfLoadOptionsFromStorage( !$oCon->getIsResetPlugin() );
|
1927 |
}
|
1928 |
return $this->oOpts;
|
1929 |
}
|
1930 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1931 |
/**
|
1932 |
* The primary DB for the
|
1933 |
* @return null|Shield\Databases\Base\Handler|mixed
|
2008 |
}
|
2009 |
|
2010 |
/**
|
2011 |
+
* Saves the options to the WordPress Options store.
|
2012 |
+
* @return void
|
2013 |
+
* @deprecated 8.4
|
|
|
|
|
|
|
|
|
|
|
|
|
2014 |
*/
|
2015 |
+
public function savePluginOptions() {
|
2016 |
+
$this->saveModOptions();
|
2017 |
}
|
2018 |
|
2019 |
/**
|
2020 |
* @return Shield\Databases\Base\Handler|mixed|false
|
2021 |
+
* @deprecated 8.4
|
2022 |
*/
|
2023 |
protected function loadDbHandler() {
|
2024 |
return false;
|
src/features/base_wpsf.php
CHANGED
@@ -283,7 +283,7 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
|
|
283 |
* @return array
|
284 |
*/
|
285 |
protected function getBaseDisplayData() {
|
286 |
-
$sHelpUrl = $this->isWlEnabled() ? $this->getCon()->getLabels()[ 'AuthorURI' ] : 'https://
|
287 |
|
288 |
return Services::DataManipulation()->mergeArraysRecursive(
|
289 |
parent::getBaseDisplayData(),
|
@@ -333,11 +333,13 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
|
|
333 |
*/
|
334 |
public function isVisitorWhitelisted() {
|
335 |
if ( !isset( $this->bVisitorIsWhitelisted ) ) {
|
336 |
-
|
337 |
-
$
|
338 |
-
|
339 |
-
|
340 |
-
|
|
|
|
|
341 |
}
|
342 |
return $this->bVisitorIsWhitelisted;
|
343 |
}
|
283 |
* @return array
|
284 |
*/
|
285 |
protected function getBaseDisplayData() {
|
286 |
+
$sHelpUrl = $this->isWlEnabled() ? $this->getCon()->getLabels()[ 'AuthorURI' ] : 'https://shsec.io/b5';
|
287 |
|
288 |
return Services::DataManipulation()->mergeArraysRecursive(
|
289 |
parent::getBaseDisplayData(),
|
333 |
*/
|
334 |
public function isVisitorWhitelisted() {
|
335 |
if ( !isset( $this->bVisitorIsWhitelisted ) ) {
|
336 |
+
$oIpMod = $this->getCon()->getModule_IPs();
|
337 |
+
$oIp = ( new Shield\Modules\IPs\Components\LookupIpOnList() )
|
338 |
+
->setMod( $oIpMod )
|
339 |
+
->setIp( Services::IP()->getRequestIp() )
|
340 |
+
->setList( $oIpMod::LIST_MANUAL_WHITE )
|
341 |
+
->lookup();
|
342 |
+
$this->bVisitorIsWhitelisted = $oIp instanceof Shield\Databases\IPs\EntryVO;
|
343 |
}
|
344 |
return $this->bVisitorIsWhitelisted;
|
345 |
}
|
src/features/events.php
CHANGED
@@ -30,7 +30,7 @@ class ICWP_WPSF_FeatureHandler_Events extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
30 |
|
31 |
/**
|
32 |
* @return Shield\Databases\Events\Handler
|
33 |
-
* @deprecated 8.
|
34 |
*/
|
35 |
protected function loadDbHandler() {
|
36 |
return new Shield\Databases\Events\Handler();
|
30 |
|
31 |
/**
|
32 |
* @return Shield\Databases\Events\Handler
|
33 |
+
* @deprecated 8.4
|
34 |
*/
|
35 |
protected function loadDbHandler() {
|
36 |
return new Shield\Databases\Events\Handler();
|
src/features/hack_protect.php
CHANGED
@@ -1057,7 +1057,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
1057 |
|
1058 |
/**
|
1059 |
* @return bool
|
1060 |
-
* @deprecated 8.
|
1061 |
*/
|
1062 |
public function isMalScanEnabled() {
|
1063 |
return !$this->isOpt( 'mal_scan_enable', 'disabled' );
|
@@ -1065,7 +1065,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
1065 |
|
1066 |
/**
|
1067 |
* @return bool
|
1068 |
-
* @deprecated 8.
|
1069 |
*/
|
1070 |
public function isMalAutoRepairPlugins() {
|
1071 |
return $this->isOpt( 'mal_autorepair_plugins', 'Y' );
|
@@ -1073,7 +1073,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
1073 |
|
1074 |
/**
|
1075 |
* @return bool
|
1076 |
-
* @deprecated 8.
|
1077 |
*/
|
1078 |
public function isMalScanAutoRepair() {
|
1079 |
/** @var HackGuard\Options $oOpts */
|
@@ -1083,7 +1083,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
1083 |
|
1084 |
/**
|
1085 |
* @return bool
|
1086 |
-
* @deprecated 8.
|
1087 |
*/
|
1088 |
public function isMalAutoRepairCore() {
|
1089 |
return $this->isOpt( 'mal_autorepair_core', 'Y' );
|
@@ -1091,7 +1091,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
1091 |
|
1092 |
/**
|
1093 |
* @return bool
|
1094 |
-
* @deprecated 8.
|
1095 |
*/
|
1096 |
public function isMalAutoRepairSurgical() {
|
1097 |
return $this->isOpt( 'mal_autorepair_surgical', 'Y' );
|
@@ -1103,37 +1103,4 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
|
|
1103 |
protected function getNamespaceBase() {
|
1104 |
return 'HackGuard';
|
1105 |
}
|
1106 |
-
|
1107 |
-
/**
|
1108 |
-
* @return Shield\Databases\Scanner\Handler
|
1109 |
-
* @deprecated 8.1.2
|
1110 |
-
*/
|
1111 |
-
protected function loadDbHandler() {
|
1112 |
-
return new Shield\Databases\Scanner\Handler();
|
1113 |
-
}
|
1114 |
-
|
1115 |
-
/**
|
1116 |
-
* @return int
|
1117 |
-
* @deprecated 8.1
|
1118 |
-
*/
|
1119 |
-
public function getScanFrequency() {
|
1120 |
-
return (int)$this->getOpt( 'scan_frequency', 1 );
|
1121 |
-
}
|
1122 |
-
|
1123 |
-
/**
|
1124 |
-
* @return string
|
1125 |
-
* @deprecated 8.1
|
1126 |
-
*/
|
1127 |
-
public function getScansTempDir() {
|
1128 |
-
$sDir = $this->getCon()->getPluginCachePath( 'scans' );
|
1129 |
-
return Services::WpFs()->mkdir( $sDir ) ? $sDir : false;
|
1130 |
-
}
|
1131 |
-
|
1132 |
-
/**
|
1133 |
-
* @return string[]
|
1134 |
-
* @deprecated 8.1
|
1135 |
-
*/
|
1136 |
-
public function getAllScanSlugs() {
|
1137 |
-
return $this->getDef( 'all_scan_slugs' );
|
1138 |
-
}
|
1139 |
}
|
1057 |
|
1058 |
/**
|
1059 |
* @return bool
|
1060 |
+
* @deprecated 8.4
|
1061 |
*/
|
1062 |
public function isMalScanEnabled() {
|
1063 |
return !$this->isOpt( 'mal_scan_enable', 'disabled' );
|
1065 |
|
1066 |
/**
|
1067 |
* @return bool
|
1068 |
+
* @deprecated 8.4
|
1069 |
*/
|
1070 |
public function isMalAutoRepairPlugins() {
|
1071 |
return $this->isOpt( 'mal_autorepair_plugins', 'Y' );
|
1073 |
|
1074 |
/**
|
1075 |
* @return bool
|
1076 |
+
* @deprecated 8.4
|
1077 |
*/
|
1078 |
public function isMalScanAutoRepair() {
|
1079 |
/** @var HackGuard\Options $oOpts */
|
1083 |
|
1084 |
/**
|
1085 |
* @return bool
|
1086 |
+
* @deprecated 8.4
|
1087 |
*/
|
1088 |
public function isMalAutoRepairCore() {
|
1089 |
return $this->isOpt( 'mal_autorepair_core', 'Y' );
|
1091 |
|
1092 |
/**
|
1093 |
* @return bool
|
1094 |
+
* @deprecated 8.4
|
1095 |
*/
|
1096 |
public function isMalAutoRepairSurgical() {
|
1097 |
return $this->isOpt( 'mal_autorepair_surgical', 'Y' );
|
1103 |
protected function getNamespaceBase() {
|
1104 |
return 'HackGuard';
|
1105 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1106 |
}
|
src/features/headers.php
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
4 |
|
5 |
class ICWP_WPSF_FeatureHandler_Headers extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
6 |
|
@@ -63,7 +64,7 @@ class ICWP_WPSF_FeatureHandler_Headers extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
63 |
protected function doExtraSubmitProcessing() {
|
64 |
$aDomains = $this->getCspHosts();
|
65 |
if ( !empty( $aDomains ) && is_array( $aDomains ) ) {
|
66 |
-
$oDP =
|
67 |
$aValidDomains = [];
|
68 |
foreach ( $aDomains as $sDomain ) {
|
69 |
$bValidDomain = false;
|
1 |
<?php
|
2 |
|
3 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
+
use FernleafSystems\Wordpress\Services\Services;
|
5 |
|
6 |
class ICWP_WPSF_FeatureHandler_Headers extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
7 |
|
64 |
protected function doExtraSubmitProcessing() {
|
65 |
$aDomains = $this->getCspHosts();
|
66 |
if ( !empty( $aDomains ) && is_array( $aDomains ) ) {
|
67 |
+
$oDP = Services::Data();
|
68 |
$aValidDomains = [];
|
69 |
foreach ( $aDomains as $sDomain ) {
|
70 |
$bValidDomain = false;
|
src/features/insights.php
CHANGED
@@ -29,7 +29,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
29 |
$nNoticesCount += isset( $aNoticeSection[ 'count' ] ) ? $aNoticeSection[ 'count' ] : 0;
|
30 |
}
|
31 |
|
32 |
-
$sNavSection = $oReq->query( 'inav' );
|
33 |
$sSubNavSection = $oReq->query( 'subnav' );
|
34 |
|
35 |
/** @var ICWP_WPSF_FeatureHandler_Traffic $oTrafficMod */
|
@@ -63,6 +63,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
63 |
$oModPlugin = $oCon->getModule_Plugin();
|
64 |
/** @var ICWP_WPSF_Processor_Plugin $oProPlugin */
|
65 |
$oProPlugin = $oModPlugin->getProcessor();
|
|
|
66 |
|
67 |
$bIsPro = $this->isPremium();
|
68 |
$oCarbon = $oReq->carbon();
|
@@ -108,7 +109,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
108 |
'strings' => [
|
109 |
'trans_limit' => sprintf(
|
110 |
__( 'Offenses required for IP block: %s', 'wp-simple-firewall' ),
|
111 |
-
sprintf( '<a href="%s" target="_blank">%s</a>', $oIpMod->getUrl_DirectLinkToOption( 'transgression_limit' ), $
|
112 |
),
|
113 |
'auto_expire' => sprintf(
|
114 |
__( 'Black listed IPs auto-expire after: %s', 'wp-simple-firewall' ),
|
@@ -233,10 +234,10 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
233 |
];
|
234 |
break;
|
235 |
|
236 |
-
case '
|
237 |
case 'index':
|
238 |
default:
|
239 |
-
$sNavSection = '
|
240 |
$aData = [
|
241 |
'vars' => [
|
242 |
'config_cards' => $this->getConfigCardsData(),
|
@@ -252,10 +253,12 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
252 |
'maxlength' => $this->getDef( 'license_key_length' ),
|
253 |
]
|
254 |
],
|
255 |
-
'ajax' => [
|
|
|
|
|
256 |
'hrefs' => [
|
257 |
-
'shield_pro_url' => 'https://
|
258 |
-
'shield_pro_more_info_url' => 'https://
|
259 |
],
|
260 |
'flags' => [
|
261 |
'show_ads' => false,
|
@@ -286,7 +289,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
286 |
|
287 |
$aTopNav = [
|
288 |
'settings' => __( 'Settings', 'wp-simple-firewall' ),
|
289 |
-
'
|
290 |
'scans' => __( 'Scans', 'wp-simple-firewall' ),
|
291 |
'ips' => __( 'IP Lists', 'wp-simple-firewall' ),
|
292 |
'audit' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
@@ -343,7 +346,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
343 |
'show_guided_tour' => $oModPlugin->getIfShowIntroVideo(),
|
344 |
],
|
345 |
'hrefs' => [
|
346 |
-
'go_pro' => 'https://
|
347 |
'nav_home' => $this->getUrl_AdminPage(),
|
348 |
'top_nav' => $aTopNav,
|
349 |
'img_banner' => $oCon->getPluginUrl_Image( 'pluginlogo_banner-170x40.png' )
|
@@ -366,7 +369,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
366 |
|
367 |
$oCon = $this->getCon();
|
368 |
$aStdDepsJs = [ $this->prefix( 'plugin' ) ];
|
369 |
-
$sNav = Services::Request()->query( 'inav' );
|
370 |
switch ( $sNav ) {
|
371 |
|
372 |
case 'importexport':
|
@@ -383,6 +386,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
383 |
wp_enqueue_script( $sUnique );
|
384 |
break;
|
385 |
|
|
|
386 |
case 'reports':
|
387 |
|
388 |
$aDeps = $aStdDepsJs;
|
@@ -765,58 +769,84 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
765 |
*/
|
766 |
protected function getStats() {
|
767 |
$oCon = $this->getCon();
|
768 |
-
/** @var Shield\Databases\Events\Handler $oDbhEvents */
|
769 |
-
$oDbhEvents = $oCon->getModule_Events()->getDbHandler_Events();
|
770 |
/** @var Shield\Databases\Events\Select $oSelEvents */
|
771 |
-
$oSelEvents = $
|
|
|
|
|
772 |
|
773 |
/** @var Shield\Databases\IPs\Select $oSelectIp */
|
774 |
$oSelectIp = $oCon->getModule_IPs()
|
775 |
->getDbHandler_IPs()
|
776 |
->getQuerySelector();
|
777 |
|
778 |
-
|
779 |
'login' => [
|
780 |
-
'
|
781 |
-
'
|
782 |
-
'
|
|
|
|
|
783 |
],
|
784 |
-
'firewall' => [
|
785 |
-
'
|
786 |
-
'
|
787 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
788 |
],
|
789 |
'comments' => [
|
790 |
-
'
|
791 |
-
'
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
|
|
|
|
797 |
],
|
798 |
'transgressions' => [
|
799 |
-
'
|
800 |
-
'
|
801 |
-
'
|
|
|
|
|
802 |
],
|
803 |
-
'
|
804 |
-
'
|
805 |
-
'
|
806 |
-
'
|
|
|
|
|
807 |
],
|
808 |
-
'
|
809 |
-
'
|
810 |
-
'
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
|
|
|
|
818 |
],
|
819 |
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
820 |
}
|
821 |
|
822 |
/**
|
29 |
$nNoticesCount += isset( $aNoticeSection[ 'count' ] ) ? $aNoticeSection[ 'count' ] : 0;
|
30 |
}
|
31 |
|
32 |
+
$sNavSection = $oReq->query( 'inav', 'overview' );
|
33 |
$sSubNavSection = $oReq->query( 'subnav' );
|
34 |
|
35 |
/** @var ICWP_WPSF_FeatureHandler_Traffic $oTrafficMod */
|
63 |
$oModPlugin = $oCon->getModule_Plugin();
|
64 |
/** @var ICWP_WPSF_Processor_Plugin $oProPlugin */
|
65 |
$oProPlugin = $oModPlugin->getProcessor();
|
66 |
+
$oEvtsMod = $oCon->getModule_Events();
|
67 |
|
68 |
$bIsPro = $this->isPremium();
|
69 |
$oCarbon = $oReq->carbon();
|
109 |
'strings' => [
|
110 |
'trans_limit' => sprintf(
|
111 |
__( 'Offenses required for IP block: %s', 'wp-simple-firewall' ),
|
112 |
+
sprintf( '<a href="%s" target="_blank">%s</a>', $oIpMod->getUrl_DirectLinkToOption( 'transgression_limit' ), $oIpOpts->getOffenseLimit() )
|
113 |
),
|
114 |
'auto_expire' => sprintf(
|
115 |
__( 'Black listed IPs auto-expire after: %s', 'wp-simple-firewall' ),
|
234 |
];
|
235 |
break;
|
236 |
|
237 |
+
case 'overview':
|
238 |
case 'index':
|
239 |
default:
|
240 |
+
$sNavSection = 'overview';
|
241 |
$aData = [
|
242 |
'vars' => [
|
243 |
'config_cards' => $this->getConfigCardsData(),
|
253 |
'maxlength' => $this->getDef( 'license_key_length' ),
|
254 |
]
|
255 |
],
|
256 |
+
'ajax' => [
|
257 |
+
'render_chart_post' => $oEvtsMod->getAjaxActionData( 'render_chart_post', true ),
|
258 |
+
],
|
259 |
'hrefs' => [
|
260 |
+
'shield_pro_url' => 'https://shsec.io/shieldpro',
|
261 |
+
'shield_pro_more_info_url' => 'https://shsec.io/shld1',
|
262 |
],
|
263 |
'flags' => [
|
264 |
'show_ads' => false,
|
289 |
|
290 |
$aTopNav = [
|
291 |
'settings' => __( 'Settings', 'wp-simple-firewall' ),
|
292 |
+
'overview' => __( 'Overview', 'wp-simple-firewall' ),
|
293 |
'scans' => __( 'Scans', 'wp-simple-firewall' ),
|
294 |
'ips' => __( 'IP Lists', 'wp-simple-firewall' ),
|
295 |
'audit' => __( 'Audit Trail', 'wp-simple-firewall' ),
|
346 |
'show_guided_tour' => $oModPlugin->getIfShowIntroVideo(),
|
347 |
],
|
348 |
'hrefs' => [
|
349 |
+
'go_pro' => 'https://shsec.io/shieldgoprofeature',
|
350 |
'nav_home' => $this->getUrl_AdminPage(),
|
351 |
'top_nav' => $aTopNav,
|
352 |
'img_banner' => $oCon->getPluginUrl_Image( 'pluginlogo_banner-170x40.png' )
|
369 |
|
370 |
$oCon = $this->getCon();
|
371 |
$aStdDepsJs = [ $this->prefix( 'plugin' ) ];
|
372 |
+
$sNav = Services::Request()->query( 'inav', 'overview' );
|
373 |
switch ( $sNav ) {
|
374 |
|
375 |
case 'importexport':
|
386 |
wp_enqueue_script( $sUnique );
|
387 |
break;
|
388 |
|
389 |
+
case 'overview':
|
390 |
case 'reports':
|
391 |
|
392 |
$aDeps = $aStdDepsJs;
|
769 |
*/
|
770 |
protected function getStats() {
|
771 |
$oCon = $this->getCon();
|
|
|
|
|
772 |
/** @var Shield\Databases\Events\Select $oSelEvents */
|
773 |
+
$oSelEvents = $oCon->getModule_Events()
|
774 |
+
->getDbHandler_Events()
|
775 |
+
->getQuerySelector();
|
776 |
|
777 |
/** @var Shield\Databases\IPs\Select $oSelectIp */
|
778 |
$oSelectIp = $oCon->getModule_IPs()
|
779 |
->getDbHandler_IPs()
|
780 |
->getQuerySelector();
|
781 |
|
782 |
+
$aStatsData = [
|
783 |
'login' => [
|
784 |
+
'id' => 'login_block',
|
785 |
+
'title' => __( 'Login Blocks', 'wp-simple-firewall' ),
|
786 |
+
'val' => sprintf( '%s: %s', __( 'Lifetime Total' ),
|
787 |
+
$oSelEvents->clearWheres()->sumEvent( 'login_block' ) ),
|
788 |
+
'tooltip_p' => __( 'Total login attempts blocked.', 'wp-simple-firewall' ),
|
789 |
],
|
790 |
+
// 'firewall' => [
|
791 |
+
// 'id' => 'firewall_block',
|
792 |
+
// 'title' => __( 'Firewall Blocks', 'wp-simple-firewall' ),
|
793 |
+
// 'val' => $oSelEvents->clearWheres()->sumEvent( 'firewall_block' ),
|
794 |
+
// 'tooltip' => __( 'Total requests blocked by firewall rules.', 'wp-simple-firewall' )
|
795 |
+
// ],
|
796 |
+
'bot_blocks' => [
|
797 |
+
'id' => 'bot_blocks',
|
798 |
+
'title' => __( 'Bot Detection', 'wp-simple-firewall' ),
|
799 |
+
'val' => sprintf( '%s: %s', __( 'Lifetime Total' ),
|
800 |
+
$oSelEvents->clearWheres()->sumEventsLike( 'bottrack_' ) ),
|
801 |
+
'tooltip_p' => __( 'Total requests identified as bots.', 'wp-simple-firewall' ),
|
802 |
],
|
803 |
'comments' => [
|
804 |
+
'id' => 'comment_block',
|
805 |
+
'title' => __( 'Comment Blocks', 'wp-simple-firewall' ),
|
806 |
+
'val' => sprintf( '%s: %s', __( 'Lifetime Total' ),
|
807 |
+
$oSelEvents->clearWheres()->sumEvents( [
|
808 |
+
'spam_block_bot',
|
809 |
+
'spam_block_human',
|
810 |
+
'spam_block_recaptcha'
|
811 |
+
] ) ),
|
812 |
+
'tooltip_p' => __( 'Total SPAM comments blocked.', 'wp-simple-firewall' ),
|
813 |
],
|
814 |
'transgressions' => [
|
815 |
+
'id' => 'ip_offense',
|
816 |
+
'title' => __( 'Offenses', 'wp-simple-firewall' ),
|
817 |
+
'val' => sprintf( '%s: %s', __( 'Lifetime Total' ),
|
818 |
+
$oSelEvents->clearWheres()->sumEvent( 'ip_offense' ) ),
|
819 |
+
'tooltip_p' => __( 'Total offenses against the site.', 'wp-simple-firewall' ),
|
820 |
],
|
821 |
+
'conn_kills' => [
|
822 |
+
'id' => 'conn_kill',
|
823 |
+
'title' => __( 'Connection Killed', 'wp-simple-firewall' ),
|
824 |
+
'val' => sprintf( '%s: %s', __( 'Lifetime Total' ),
|
825 |
+
$oSelEvents->clearWheres()->sumEvent( 'conn_kill' ) ),
|
826 |
+
'tooltip_p' => __( 'Total connections blocked/killed after too many offenses.', 'wp-simple-firewall' ),
|
827 |
],
|
828 |
+
'ip_blocked' => [
|
829 |
+
'id' => 'ip_blocked',
|
830 |
+
'title' => __( 'IP Blocked', 'wp-simple-firewall' ),
|
831 |
+
'val' => sprintf( '%s: %s', __( 'Now' ),
|
832 |
+
$oSelectIp
|
833 |
+
->filterByLists(
|
834 |
+
[
|
835 |
+
ICWP_WPSF_FeatureHandler_Ips::LIST_AUTO_BLACK,
|
836 |
+
ICWP_WPSF_FeatureHandler_Ips::LIST_MANUAL_BLACK
|
837 |
+
]
|
838 |
+
)->count() ),
|
839 |
+
'tooltip_p' => __( 'IP address exceeds offense limit and is blocked.', 'wp-simple-firewall' ),
|
840 |
],
|
841 |
];
|
842 |
+
|
843 |
+
foreach ( $aStatsData as $sKey => $sStatData ) {
|
844 |
+
$sSub = sprintf( __( 'previous %s %s', 'wp-simple-firewall' ), 7, __( 'days', 'wp-simple-firewall' ) );
|
845 |
+
$aStatsData[ $sKey ][ 'title_sub' ] = $sSub;
|
846 |
+
$aStatsData[ $sKey ][ 'tooltip_chart' ] = sprintf( '%s: %s.', __( 'Stats', 'wp-simple-firewall' ), $sSub );
|
847 |
+
}
|
848 |
+
|
849 |
+
return $aStatsData;
|
850 |
}
|
851 |
|
852 |
/**
|
src/features/ips.php
CHANGED
@@ -173,7 +173,7 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
|
173 |
$aIps = apply_filters( 'icwp_simple_firewall_whitelist_ips', $aIps );
|
174 |
|
175 |
if ( !empty( $aIps ) && is_array( $aIps ) ) {
|
176 |
-
/** @var ICWP_WPSF_Processor_Ips $oPro */
|
177 |
$oPro = $this->getProcessor();
|
178 |
|
179 |
$aWhiteIps = $oPro->getWhitelistIps();
|
@@ -191,122 +191,4 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
|
191 |
protected function getNamespaceBase() {
|
192 |
return 'IPs';
|
193 |
}
|
194 |
-
|
195 |
-
/**
|
196 |
-
* @return string
|
197 |
-
* @deprecated 8.1
|
198 |
-
*/
|
199 |
-
public function getOptTransgressionLimit() {
|
200 |
-
return $this->getOpt( 'transgression_limit' );
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* @return bool
|
205 |
-
* @deprecated 8.1
|
206 |
-
*/
|
207 |
-
public function isAutoBlackListEnabled() {
|
208 |
-
return ( $this->getOptTransgressionLimit() > 0 );
|
209 |
-
}
|
210 |
-
|
211 |
-
/**
|
212 |
-
* @return bool
|
213 |
-
* @deprecated 8.1
|
214 |
-
*/
|
215 |
-
public function isEnabledTrack404() {
|
216 |
-
return $this->isSelectOptionEnabled( 'track_404' );
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* @return bool
|
221 |
-
* @deprecated 8.1
|
222 |
-
*/
|
223 |
-
public function isEnabledTrackFakeWebCrawler() {
|
224 |
-
return $this->isSelectOptionEnabled( 'track_fakewebcrawler' );
|
225 |
-
}
|
226 |
-
|
227 |
-
/**
|
228 |
-
* @return bool
|
229 |
-
* @deprecated 8.1
|
230 |
-
*/
|
231 |
-
public function isEnabledTrackLoginInvalid() {
|
232 |
-
return $this->isSelectOptionEnabled( 'track_logininvalid' );
|
233 |
-
}
|
234 |
-
|
235 |
-
/**
|
236 |
-
* @return bool
|
237 |
-
* @deprecated 8.1
|
238 |
-
*/
|
239 |
-
public function isEnabledTrackLoginFailed() {
|
240 |
-
return $this->isSelectOptionEnabled( 'track_loginfailed' );
|
241 |
-
}
|
242 |
-
|
243 |
-
/**
|
244 |
-
* @return bool
|
245 |
-
* @deprecated 8.1
|
246 |
-
*/
|
247 |
-
public function isEnabledTrackLinkCheese() {
|
248 |
-
return $this->isSelectOptionEnabled( 'track_linkcheese' );
|
249 |
-
}
|
250 |
-
|
251 |
-
/**
|
252 |
-
* @return bool
|
253 |
-
* @deprecated 8.1
|
254 |
-
*/
|
255 |
-
public function isEnabledTrackXmlRpc() {
|
256 |
-
return $this->isSelectOptionEnabled( 'track_xmlrpc' );
|
257 |
-
}
|
258 |
-
|
259 |
-
/**
|
260 |
-
* @param string $sOptionKey
|
261 |
-
* @return bool
|
262 |
-
* @deprecated 8.1
|
263 |
-
*/
|
264 |
-
public function isTrackOptTransgression( $sOptionKey ) {
|
265 |
-
return strpos( $this->getOpt( $sOptionKey ), 'transgression' ) !== false;
|
266 |
-
}
|
267 |
-
|
268 |
-
/**
|
269 |
-
* @param string $sOptionKey
|
270 |
-
* @return bool
|
271 |
-
* @deprecated 8.1
|
272 |
-
*/
|
273 |
-
public function isTrackOptDoubleTransgression( $sOptionKey ) {
|
274 |
-
return $this->isOpt( $sOptionKey, 'transgression-double' );
|
275 |
-
}
|
276 |
-
|
277 |
-
/**
|
278 |
-
* @param string $sOptionKey
|
279 |
-
* @return bool
|
280 |
-
* @deprecated 8.1
|
281 |
-
*/
|
282 |
-
public function isTrackOptImmediateBlock( $sOptionKey ) {
|
283 |
-
return $this->isOpt( $sOptionKey, 'block' );
|
284 |
-
}
|
285 |
-
|
286 |
-
/**
|
287 |
-
* @param string $sOptionKey
|
288 |
-
* @return bool
|
289 |
-
* @deprecated 8.1
|
290 |
-
*/
|
291 |
-
protected function isSelectOptionEnabled( $sOptionKey ) {
|
292 |
-
$bOptPrem = $this->getOptions()->isOptPremium( $sOptionKey );
|
293 |
-
return ( !$bOptPrem || $this->getCon()->isPremiumActive() ) && !$this->isOpt( $sOptionKey, 'disabled' );
|
294 |
-
}
|
295 |
-
|
296 |
-
/**
|
297 |
-
* @return int
|
298 |
-
* @deprecated 8.1
|
299 |
-
*/
|
300 |
-
public function getAutoExpireTime() {
|
301 |
-
$sConstant = strtoupper( $this->getOpt( 'auto_expire' ).'_IN_SECONDS' );
|
302 |
-
return defined( $sConstant ) ? constant( $sConstant ) : ( DAY_IN_SECONDS*30 );
|
303 |
-
}
|
304 |
-
|
305 |
-
/**
|
306 |
-
* @return Shield\Databases\IPs\Handler
|
307 |
-
* @deprecated 8.1.2
|
308 |
-
*/
|
309 |
-
protected function loadDbHandler() {
|
310 |
-
return new Shield\Databases\IPs\Handler();
|
311 |
-
}
|
312 |
}
|
173 |
$aIps = apply_filters( 'icwp_simple_firewall_whitelist_ips', $aIps );
|
174 |
|
175 |
if ( !empty( $aIps ) && is_array( $aIps ) ) {
|
176 |
+
/** @var \ICWP_WPSF_Processor_Ips $oPro */
|
177 |
$oPro = $this->getProcessor();
|
178 |
|
179 |
$aWhiteIps = $oPro->getWhitelistIps();
|
191 |
protected function getNamespaceBase() {
|
192 |
return 'IPs';
|
193 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
}
|
src/features/license.php
CHANGED
@@ -578,8 +578,8 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
578 |
'connection_debug' => $this->getAjaxActionData( 'connection_debug' )
|
579 |
],
|
580 |
'aHrefs' => [
|
581 |
-
'shield_pro_url' => 'https://
|
582 |
-
'shield_pro_more_info_url' => 'https://
|
583 |
'iframe_url' => $this->getDef( 'landing_page_url' ),
|
584 |
'keyless_cp' => $this->getDef( 'keyless_cp' ),
|
585 |
],
|
578 |
'connection_debug' => $this->getAjaxActionData( 'connection_debug' )
|
579 |
],
|
580 |
'aHrefs' => [
|
581 |
+
'shield_pro_url' => 'https://shsec.io/shieldpro',
|
582 |
+
'shield_pro_more_info_url' => 'https://shsec.io/shld1',
|
583 |
'iframe_url' => $this->getDef( 'landing_page_url' ),
|
584 |
'keyless_cp' => $this->getDef( 'keyless_cp' ),
|
585 |
],
|
src/features/login_protect.php
CHANGED
@@ -184,7 +184,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
184 |
|
185 |
/**
|
186 |
* @return int
|
187 |
-
* @deprecated 8.
|
188 |
*/
|
189 |
public function getCooldownInterval() {
|
190 |
return (int)$this->getOpt( 'login_limit_interval' );
|
@@ -502,7 +502,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
502 |
$aWarnings[] =
|
503 |
__( '2FA by email demands that your WP site is properly configured to send email.', 'wp-simple-firewall' )
|
504 |
.'<br/>'.__( 'This is a common problem and you may get locked out in the future if you ignore this.', 'wp-simple-firewall' )
|
505 |
-
.' '.sprintf( '<a href="%s" target="_blank" class="alert-link">%s</a>', 'https://
|
506 |
}
|
507 |
|
508 |
return $aWarnings;
|
@@ -646,7 +646,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
|
|
646 |
|
647 |
/**
|
648 |
* @return bool
|
649 |
-
* @deprecated 8.
|
650 |
*/
|
651 |
public function isCooldownEnabled() {
|
652 |
return $this->getCooldownInterval() > 0;
|
184 |
|
185 |
/**
|
186 |
* @return int
|
187 |
+
* @deprecated 8.4
|
188 |
*/
|
189 |
public function getCooldownInterval() {
|
190 |
return (int)$this->getOpt( 'login_limit_interval' );
|
502 |
$aWarnings[] =
|
503 |
__( '2FA by email demands that your WP site is properly configured to send email.', 'wp-simple-firewall' )
|
504 |
.'<br/>'.__( 'This is a common problem and you may get locked out in the future if you ignore this.', 'wp-simple-firewall' )
|
505 |
+
.' '.sprintf( '<a href="%s" target="_blank" class="alert-link">%s</a>', 'https://shsec.io/dd', __( 'Learn More.', 'wp-simple-firewall' ) );
|
506 |
}
|
507 |
|
508 |
return $aWarnings;
|
646 |
|
647 |
/**
|
648 |
* @return bool
|
649 |
+
* @deprecated 8.4
|
650 |
*/
|
651 |
public function isCooldownEnabled() {
|
652 |
return $this->getCooldownInterval() > 0;
|
src/features/plugin.php
CHANGED
@@ -585,12 +585,12 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
585 |
* @return $this
|
586 |
*/
|
587 |
public function addUrlToImportExportWhitelistUrls( $sUrl ) {
|
588 |
-
$sUrl =
|
589 |
if ( $sUrl !== false ) {
|
590 |
$aWhitelistUrls = $this->getImportExportWhitelist();
|
591 |
$aWhitelistUrls[] = $sUrl;
|
592 |
-
$this->setOpt( 'importexport_whitelist', $aWhitelistUrls )
|
593 |
-
|
594 |
}
|
595 |
return $this;
|
596 |
}
|
@@ -600,15 +600,15 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
600 |
* @return $this
|
601 |
*/
|
602 |
public function removeUrlFromImportExportWhitelistUrls( $sUrl ) {
|
603 |
-
$sUrl =
|
604 |
if ( $sUrl !== false ) {
|
605 |
$aWhitelistUrls = $this->getImportExportWhitelist();
|
606 |
$sKey = array_search( $sUrl, $aWhitelistUrls );
|
607 |
if ( $sKey !== false ) {
|
608 |
unset( $aWhitelistUrls[ $sKey ] );
|
609 |
}
|
610 |
-
$this->setOpt( 'importexport_whitelist', $aWhitelistUrls )
|
611 |
-
|
612 |
}
|
613 |
return $this;
|
614 |
}
|
@@ -625,7 +625,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
625 |
* @return $this
|
626 |
*/
|
627 |
protected function cleanImportExportWhitelistUrls() {
|
628 |
-
$oDP =
|
629 |
|
630 |
$aCleaned = [];
|
631 |
$aWhitelistUrls = $this->getImportExportWhitelist();
|
@@ -643,7 +643,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
643 |
* @return $this
|
644 |
*/
|
645 |
protected function cleanImportExportMasterImportUrl() {
|
646 |
-
$sUrl =
|
647 |
if ( $sUrl === false ) {
|
648 |
$sUrl = '';
|
649 |
}
|
@@ -654,9 +654,8 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
654 |
* @return $this
|
655 |
*/
|
656 |
public function startImportExportHandshake() {
|
657 |
-
$this->setOpt( 'importexport_handshake_expires_at', Services::Request()->ts() + 30 )
|
658 |
-
|
659 |
-
return $this;
|
660 |
}
|
661 |
|
662 |
/**
|
@@ -794,7 +793,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
794 |
|
795 |
/**
|
796 |
* @return int
|
797 |
-
* @deprecated 8.
|
798 |
*/
|
799 |
public function getLastCheckServerIpAt() {
|
800 |
return $this->getOpt( 'this_server_ip_last_check_at', 0 );
|
585 |
* @return $this
|
586 |
*/
|
587 |
public function addUrlToImportExportWhitelistUrls( $sUrl ) {
|
588 |
+
$sUrl = Services::Data()->validateSimpleHttpUrl( $sUrl );
|
589 |
if ( $sUrl !== false ) {
|
590 |
$aWhitelistUrls = $this->getImportExportWhitelist();
|
591 |
$aWhitelistUrls[] = $sUrl;
|
592 |
+
$this->setOpt( 'importexport_whitelist', $aWhitelistUrls );
|
593 |
+
$this->saveModOptions();
|
594 |
}
|
595 |
return $this;
|
596 |
}
|
600 |
* @return $this
|
601 |
*/
|
602 |
public function removeUrlFromImportExportWhitelistUrls( $sUrl ) {
|
603 |
+
$sUrl = Services::Data()->validateSimpleHttpUrl( $sUrl );
|
604 |
if ( $sUrl !== false ) {
|
605 |
$aWhitelistUrls = $this->getImportExportWhitelist();
|
606 |
$sKey = array_search( $sUrl, $aWhitelistUrls );
|
607 |
if ( $sKey !== false ) {
|
608 |
unset( $aWhitelistUrls[ $sKey ] );
|
609 |
}
|
610 |
+
$this->setOpt( 'importexport_whitelist', $aWhitelistUrls );
|
611 |
+
$this->saveModOptions();
|
612 |
}
|
613 |
return $this;
|
614 |
}
|
625 |
* @return $this
|
626 |
*/
|
627 |
protected function cleanImportExportWhitelistUrls() {
|
628 |
+
$oDP = Services::Data();
|
629 |
|
630 |
$aCleaned = [];
|
631 |
$aWhitelistUrls = $this->getImportExportWhitelist();
|
643 |
* @return $this
|
644 |
*/
|
645 |
protected function cleanImportExportMasterImportUrl() {
|
646 |
+
$sUrl = Services::Data()->validateSimpleHttpUrl( $this->getImportExportMasterImportUrl() );
|
647 |
if ( $sUrl === false ) {
|
648 |
$sUrl = '';
|
649 |
}
|
654 |
* @return $this
|
655 |
*/
|
656 |
public function startImportExportHandshake() {
|
657 |
+
$this->setOpt( 'importexport_handshake_expires_at', Services::Request()->ts() + 30 );
|
658 |
+
return $this->saveModOptions();
|
|
|
659 |
}
|
660 |
|
661 |
/**
|
793 |
|
794 |
/**
|
795 |
* @return int
|
796 |
+
* @deprecated 8.4
|
797 |
*/
|
798 |
public function getLastCheckServerIpAt() {
|
799 |
return $this->getOpt( 'this_server_ip_last_check_at', 0 );
|
src/features/sessions.php
CHANGED
@@ -44,7 +44,7 @@ class ICWP_WPSF_FeatureHandler_Sessions extends ICWP_WPSF_FeatureHandler_BaseWps
|
|
44 |
|
45 |
/**
|
46 |
* @return Shield\Databases\Session\Handler
|
47 |
-
* @deprecated 8.
|
48 |
*/
|
49 |
protected function loadDbHandler() {
|
50 |
return new Shield\Databases\Session\Handler();
|
44 |
|
45 |
/**
|
46 |
* @return Shield\Databases\Session\Handler
|
47 |
+
* @deprecated 8.4
|
48 |
*/
|
49 |
protected function loadDbHandler() {
|
50 |
return new Shield\Databases\Session\Handler();
|
src/features/statistics.php
CHANGED
@@ -5,7 +5,7 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
5 |
|
6 |
/**
|
7 |
* Class ICWP_WPSF_FeatureHandler_Statistics
|
8 |
-
* @deprecated 8.
|
9 |
*/
|
10 |
class ICWP_WPSF_FeatureHandler_Statistics extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
11 |
|
5 |
|
6 |
/**
|
7 |
* Class ICWP_WPSF_FeatureHandler_Statistics
|
8 |
+
* @deprecated 8.4
|
9 |
*/
|
10 |
class ICWP_WPSF_FeatureHandler_Statistics extends ICWP_WPSF_FeatureHandler_BaseWpsf {
|
11 |
|
src/features/traffic.php
CHANGED
@@ -167,17 +167,9 @@ class ICWP_WPSF_FeatureHandler_Traffic extends ICWP_WPSF_FeatureHandler_BaseWpsf
|
|
167 |
|
168 |
/**
|
169 |
* @return Shield\Databases\Traffic\Handler
|
170 |
-
* @deprecated 8.
|
171 |
*/
|
172 |
protected function loadDbHandler() {
|
173 |
return new Shield\Databases\Traffic\Handler();
|
174 |
}
|
175 |
-
|
176 |
-
/**
|
177 |
-
* @return int
|
178 |
-
* @deprecated 8.1
|
179 |
-
*/
|
180 |
-
public function getMaxEntries() {
|
181 |
-
return (int)$this->getOpt( 'max_entries' );
|
182 |
-
}
|
183 |
}
|
167 |
|
168 |
/**
|
169 |
* @return Shield\Databases\Traffic\Handler
|
170 |
+
* @deprecated 8.4
|
171 |
*/
|
172 |
protected function loadDbHandler() {
|
173 |
return new Shield\Databases\Traffic\Handler();
|
174 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
}
|
src/features/user_management.php
CHANGED
@@ -397,13 +397,4 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends \ICWP_WPSF_FeatureHandler_
|
|
397 |
protected function getNamespaceBase() {
|
398 |
return 'UserManagement';
|
399 |
}
|
400 |
-
|
401 |
-
/**
|
402 |
-
* Should have no default email. If no email is set, no notification is sent.
|
403 |
-
* @return string
|
404 |
-
* @deprecated 8.1
|
405 |
-
*/
|
406 |
-
public function getAdminLoginNotificationEmail() {
|
407 |
-
return $this->getOpt( 'enable_admin_login_email_notification', '' );
|
408 |
-
}
|
409 |
}
|
397 |
protected function getNamespaceBase() {
|
398 |
return 'UserManagement';
|
399 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
400 |
}
|
src/lib/src/AuditTrail/Auditor.php
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\AuditTrail;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Plugin\Shield\Databases\AuditTrail\EntryVO;
|
6 |
-
use FernleafSystems\Wordpress\Services\Services;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Trait Auditor
|
10 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\AuditTrail
|
11 |
-
* @deprecated 8.1
|
12 |
-
*/
|
13 |
-
trait Auditor {
|
14 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/src/Controller/Controller.php
CHANGED
@@ -564,6 +564,13 @@ class Controller extends Shield\Deprecated\Foundation {
|
|
564 |
return $this;
|
565 |
}
|
566 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
567 |
/**
|
568 |
* Displaying all views now goes through this central function and we work out
|
569 |
* what to display based on the name of current hook/filter being processed.
|
@@ -1798,6 +1805,13 @@ class Controller extends Shield\Deprecated\Foundation {
|
|
1798 |
return $this->getModule( 'audit_trail' );
|
1799 |
}
|
1800 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1801 |
/**
|
1802 |
* @return \ICWP_WPSF_FeatureHandler_Events
|
1803 |
*/
|
564 |
return $this;
|
565 |
}
|
566 |
|
567 |
+
/**
|
568 |
+
* @return array
|
569 |
+
*/
|
570 |
+
public function getAllEvents() {
|
571 |
+
return apply_filters( $this->prefix( 'get_all_events' ), [] );
|
572 |
+
}
|
573 |
+
|
574 |
/**
|
575 |
* Displaying all views now goes through this central function and we work out
|
576 |
* what to display based on the name of current hook/filter being processed.
|
1805 |
return $this->getModule( 'audit_trail' );
|
1806 |
}
|
1807 |
|
1808 |
+
/**
|
1809 |
+
* @return \ICWP_WPSF_FeatureHandler_CommentsFilter
|
1810 |
+
*/
|
1811 |
+
public function getModule_Comments() {
|
1812 |
+
return $this->getModule( 'comments_filter' );
|
1813 |
+
}
|
1814 |
+
|
1815 |
/**
|
1816 |
* @return \ICWP_WPSF_FeatureHandler_Events
|
1817 |
*/
|
src/lib/src/Databases/AuditTrail/Handler.php
CHANGED
@@ -9,10 +9,8 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
9 |
class Handler extends Base\Handler {
|
10 |
|
11 |
public function autoCleanDb() {
|
12 |
-
/** @var \ICWP_WPSF_FeatureHandler_AuditTrail $oMod */
|
13 |
-
$oMod = $this->getMod();
|
14 |
/** @var Options $oOpts */
|
15 |
-
$oOpts = $
|
16 |
$this->cleanDb( $oOpts->getAutoCleanDays() );
|
17 |
$this->trimDb( $oOpts->getMaxEntries() );
|
18 |
}
|
9 |
class Handler extends Base\Handler {
|
10 |
|
11 |
public function autoCleanDb() {
|
|
|
|
|
12 |
/** @var Options $oOpts */
|
13 |
+
$oOpts = $this->getMod()->getOptions();
|
14 |
$this->cleanDb( $oOpts->getAutoCleanDays() );
|
15 |
$this->trimDb( $oOpts->getMaxEntries() );
|
16 |
}
|
src/lib/src/Databases/AuditTrail/Select.php
CHANGED
@@ -83,16 +83,4 @@ class Select extends Base\Select {
|
|
83 |
public function filterByUsername( $sUsername ) {
|
84 |
return $this->addWhereEquals( 'wp_username', trim( $sUsername ) );
|
85 |
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* @param string $sContext
|
89 |
-
* @return $this
|
90 |
-
* @deprecated 8.1
|
91 |
-
*/
|
92 |
-
public function filterByContext( $sContext ) {
|
93 |
-
if ( !empty( $sContext ) && strtolower( $sContext ) != 'all' ) {
|
94 |
-
$this->addWhereEquals( 'context', $sContext );
|
95 |
-
}
|
96 |
-
return $this;
|
97 |
-
}
|
98 |
}
|
83 |
public function filterByUsername( $sUsername ) {
|
84 |
return $this->addWhereEquals( 'wp_username', trim( $sUsername ) );
|
85 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
}
|
src/lib/src/Databases/Base/BaseQuery.php
CHANGED
@@ -104,6 +104,17 @@ abstract class BaseQuery {
|
|
104 |
return $this;
|
105 |
}
|
106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
/**
|
108 |
* @param int $nNewerThanTimeStamp
|
109 |
* @param string $sColumn
|
@@ -216,8 +227,28 @@ abstract class BaseQuery {
|
|
216 |
*/
|
217 |
public function filterByBoundary_Day( $nTs ) {
|
218 |
$oCbn = ( new Carbon() )->setTimestamp( $nTs );
|
219 |
-
return $this->filterByCreatedAt( $oCbn->
|
220 |
-
->filterByCreatedAt( $oCbn->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
}
|
222 |
|
223 |
/**
|
@@ -226,8 +257,18 @@ abstract class BaseQuery {
|
|
226 |
*/
|
227 |
public function filterByBoundary_Week( $nTs ) {
|
228 |
$oCbn = ( new Carbon() )->setTimestamp( $nTs );
|
229 |
-
return $this->filterByCreatedAt( $oCbn->
|
230 |
-
->filterByCreatedAt( $oCbn->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
}
|
232 |
|
233 |
/**
|
104 |
return $this;
|
105 |
}
|
106 |
|
107 |
+
/**
|
108 |
+
* @param string $sColumn
|
109 |
+
* @param string $sLike
|
110 |
+
* @param string $sLeft
|
111 |
+
* @param string $sRight
|
112 |
+
* @return $this
|
113 |
+
*/
|
114 |
+
public function addWhereLike( $sColumn, $sLike, $sLeft = '%', $sRight = '%' ) {
|
115 |
+
return $this->addWhere( $sColumn, $sLeft.$sLike.$sRight, 'LIKE' );
|
116 |
+
}
|
117 |
+
|
118 |
/**
|
119 |
* @param int $nNewerThanTimeStamp
|
120 |
* @param string $sColumn
|
227 |
*/
|
228 |
public function filterByBoundary_Day( $nTs ) {
|
229 |
$oCbn = ( new Carbon() )->setTimestamp( $nTs );
|
230 |
+
return $this->filterByCreatedAt( $oCbn->endOfDay()->timestamp, '<=' )
|
231 |
+
->filterByCreatedAt( $oCbn->startOfDay()->timestamp, '>=' );
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* @param int $nTs
|
236 |
+
* @return $this
|
237 |
+
*/
|
238 |
+
public function filterByBoundary_Hour( $nTs ) {
|
239 |
+
$oCbn = ( new Carbon() )->setTimestamp( $nTs );
|
240 |
+
return $this->filterByCreatedAt( $oCbn->endOfHour()->timestamp, '<=' )
|
241 |
+
->filterByCreatedAt( $oCbn->startOfHour()->timestamp, '>=' );
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* @param int $nTs
|
246 |
+
* @return $this
|
247 |
+
*/
|
248 |
+
public function filterByBoundary_Month( $nTs ) {
|
249 |
+
$oCbn = ( new Carbon() )->setTimestamp( $nTs );
|
250 |
+
return $this->filterByCreatedAt( $oCbn->startOfMonth()->timestamp, '>=' )
|
251 |
+
->filterByCreatedAt( $oCbn->endOfMonth()->timestamp, '<=' );
|
252 |
}
|
253 |
|
254 |
/**
|
257 |
*/
|
258 |
public function filterByBoundary_Week( $nTs ) {
|
259 |
$oCbn = ( new Carbon() )->setTimestamp( $nTs );
|
260 |
+
return $this->filterByCreatedAt( $oCbn->endOfWeek()->timestamp, '<=' )
|
261 |
+
->filterByCreatedAt( $oCbn->startOfWeek()->timestamp, '>=' );
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* @param int $nTs
|
266 |
+
* @return $this
|
267 |
+
*/
|
268 |
+
public function filterByBoundary_Year( $nTs ) {
|
269 |
+
$oCbn = ( new Carbon() )->setTimestamp( $nTs );
|
270 |
+
return $this->filterByCreatedAt( $oCbn->startOfYear()->timestamp, '>=' )
|
271 |
+
->filterByCreatedAt( $oCbn->endOfYear()->timestamp, '<=' );
|
272 |
}
|
273 |
|
274 |
/**
|
src/lib/src/Databases/Events/Common.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Events;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Trait Filters
|
7 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Databases\Events
|
8 |
+
*/
|
9 |
+
trait Common {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param string $sEvent
|
13 |
+
* @return $this
|
14 |
+
*/
|
15 |
+
public function filterByEvent( $sEvent ) {
|
16 |
+
return $this->filterByEvents( [ $sEvent ] );
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @param string[] $aEvents
|
21 |
+
* @return $this
|
22 |
+
*/
|
23 |
+
public function filterByEvents( $aEvents ) {
|
24 |
+
return $this->addWhereIn( 'event', $aEvents );
|
25 |
+
}
|
26 |
+
}
|
src/lib/src/Databases/Events/Delete.php
CHANGED
@@ -6,4 +6,5 @@ use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
|
|
6 |
|
7 |
class Delete extends Base\Delete {
|
8 |
|
|
|
9 |
}
|
6 |
|
7 |
class Delete extends Base\Delete {
|
8 |
|
9 |
+
use Common;
|
10 |
}
|
src/lib/src/Databases/Events/Select.php
CHANGED
@@ -2,11 +2,12 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Events;
|
4 |
|
5 |
-
use Carbon\Carbon;
|
6 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
|
7 |
|
8 |
class Select extends Base\Select {
|
9 |
|
|
|
|
|
10 |
/**
|
11 |
* @param string $sEvent
|
12 |
* @return int
|
@@ -25,6 +26,16 @@ class Select extends Base\Select {
|
|
25 |
->sum();
|
26 |
}
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
/**
|
29 |
* @return int[]
|
30 |
*/
|
@@ -52,6 +63,17 @@ class Select extends Base\Select {
|
|
52 |
->first();
|
53 |
}
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
/**
|
56 |
* @return string[]
|
57 |
*/
|
@@ -100,20 +122,4 @@ class Select extends Base\Select {
|
|
100 |
public function filterByCountGreaterThan( $nGreaterThan ) {
|
101 |
return $this->addWhere( 'count', (int)$nGreaterThan, '>' );
|
102 |
}
|
103 |
-
|
104 |
-
/**
|
105 |
-
* @param string $sEvent
|
106 |
-
* @return $this
|
107 |
-
*/
|
108 |
-
public function filterByEvent( $sEvent ) {
|
109 |
-
return $this->filterByEvents( [ $sEvent ] );
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* @param string[] $aEvents
|
114 |
-
* @return $this
|
115 |
-
*/
|
116 |
-
public function filterByEvents( $aEvents ) {
|
117 |
-
return $this->addWhereIn( 'event', $aEvents );
|
118 |
-
}
|
119 |
}
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\Events;
|
4 |
|
|
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
|
6 |
|
7 |
class Select extends Base\Select {
|
8 |
|
9 |
+
use Common;
|
10 |
+
|
11 |
/**
|
12 |
* @param string $sEvent
|
13 |
* @return int
|
26 |
->sum();
|
27 |
}
|
28 |
|
29 |
+
/**
|
30 |
+
* @param string $sEvent
|
31 |
+
* @return int
|
32 |
+
*/
|
33 |
+
public function sumEventsLike( $sEvent ) {
|
34 |
+
return (int)$this->addWhereLike( 'event', $sEvent )
|
35 |
+
->setColumnsToSelect( [ 'count' ] )
|
36 |
+
->sum();
|
37 |
+
}
|
38 |
+
|
39 |
/**
|
40 |
* @return int[]
|
41 |
*/
|
63 |
->first();
|
64 |
}
|
65 |
|
66 |
+
/**
|
67 |
+
* @param string $sEvent
|
68 |
+
* @return EntryVO|null
|
69 |
+
*/
|
70 |
+
public function getOldestForEvent( $sEvent ) {
|
71 |
+
return $this->filterByEvent( $sEvent )
|
72 |
+
->setOrderBy( 'created_at', 'ASC' )
|
73 |
+
->setResultsAsVo( true )
|
74 |
+
->first();
|
75 |
+
}
|
76 |
+
|
77 |
/**
|
78 |
* @return string[]
|
79 |
*/
|
122 |
public function filterByCountGreaterThan( $nGreaterThan ) {
|
123 |
return $this->addWhere( 'count', (int)$nGreaterThan, '>' );
|
124 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
}
|
src/lib/src/Databases/IPs/CommonFilters.php
CHANGED
@@ -12,6 +12,14 @@ trait CommonFilters {
|
|
12 |
return $this->addWhereEquals( 'ip', $sIp );
|
13 |
}
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
/**
|
16 |
* @param string $nLastAccessAfter
|
17 |
* @return $this
|
12 |
return $this->addWhereEquals( 'ip', $sIp );
|
13 |
}
|
14 |
|
15 |
+
/**
|
16 |
+
* @param bool $bIsRange
|
17 |
+
* @return $this
|
18 |
+
*/
|
19 |
+
public function filterByIsRange( $bIsRange ) {
|
20 |
+
return $this->addWhereEquals( 'is_range', $bIsRange ? 1 : 0 );
|
21 |
+
}
|
22 |
+
|
23 |
/**
|
24 |
* @param string $nLastAccessAfter
|
25 |
* @return $this
|
src/lib/src/Deprecated/Foundation.php
CHANGED
@@ -21,6 +21,7 @@ class Foundation {
|
|
21 |
|
22 |
/**
|
23 |
* @return \ICWP_WPSF_DataProcessor
|
|
|
24 |
*/
|
25 |
static public function loadDP() {
|
26 |
$sKey = 'icwp-data';
|
@@ -30,52 +31,6 @@ class Foundation {
|
|
30 |
return self::getService( $sKey );
|
31 |
}
|
32 |
|
33 |
-
/**
|
34 |
-
* @return \ICWP_WPSF_WpFilesystem
|
35 |
-
*/
|
36 |
-
static public function loadFS() {
|
37 |
-
$sKey = 'icwp-wpfilesystem';
|
38 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
39 |
-
self::setService( $sKey, \ICWP_WPSF_WpFilesystem::GetInstance() );
|
40 |
-
}
|
41 |
-
return self::getService( $sKey );
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* @return \ICWP_WPSF_WpFunctions
|
46 |
-
*/
|
47 |
-
static public function loadWp() {
|
48 |
-
$sKey = 'icwp-wpfunctions';
|
49 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
50 |
-
self::setService( $sKey, \ICWP_WPSF_WpFunctions::GetInstance() );
|
51 |
-
}
|
52 |
-
return self::getService( $sKey );
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* @return \ICWP_WPSF_WpFunctions_Plugins
|
57 |
-
* @deprecated
|
58 |
-
*/
|
59 |
-
public function loadWpPlugins() {
|
60 |
-
$sKey = 'icwp-wpfunctions-plugins';
|
61 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
62 |
-
self::setService( $sKey, \ICWP_WPSF_WpFunctions_Plugins::GetInstance() );
|
63 |
-
}
|
64 |
-
return self::getService( $sKey );
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* @return \ICWP_WPSF_WpFunctions_Themes
|
69 |
-
* @deprecated
|
70 |
-
*/
|
71 |
-
public function loadWpThemes() {
|
72 |
-
$sKey = 'icwp-wpfunctions-themes';
|
73 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
74 |
-
self::setService( $sKey, \ICWP_WPSF_WpFunctions_Themes::GetInstance() );
|
75 |
-
}
|
76 |
-
return self::getService( $sKey );
|
77 |
-
}
|
78 |
-
|
79 |
/**
|
80 |
* @return \ICWP_WPSF_WpCron
|
81 |
* @deprecated
|
@@ -88,40 +43,6 @@ class Foundation {
|
|
88 |
return self::getService( $sKey );
|
89 |
}
|
90 |
|
91 |
-
/**
|
92 |
-
* @return \ICWP_WPSF_WpUpgrades
|
93 |
-
* @deprecated
|
94 |
-
*/
|
95 |
-
static public function loadWpUpgrades() {
|
96 |
-
$sKey = 'icwp-wpupgrades';
|
97 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
98 |
-
self::setService( $sKey, \ICWP_WPSF_WpUpgrades::GetInstance() );
|
99 |
-
}
|
100 |
-
return self::getService( $sKey );
|
101 |
-
}
|
102 |
-
|
103 |
-
/**
|
104 |
-
* @return \ICWP_WPSF_WpDb
|
105 |
-
*/
|
106 |
-
static public function loadDbProcessor() {
|
107 |
-
$sKey = 'icwp-wpdb';
|
108 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
109 |
-
self::setService( $sKey, \ICWP_WPSF_WpDb::GetInstance() );
|
110 |
-
}
|
111 |
-
return self::getService( $sKey );
|
112 |
-
}
|
113 |
-
|
114 |
-
/**
|
115 |
-
* @return \ICWP_WPSF_Request
|
116 |
-
*/
|
117 |
-
public function loadRequest() {
|
118 |
-
$sKey = 'icwp-request';
|
119 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
120 |
-
self::setService( $sKey, \ICWP_WPSF_Request::GetInstance() );
|
121 |
-
}
|
122 |
-
return self::getService( $sKey );
|
123 |
-
}
|
124 |
-
|
125 |
/**
|
126 |
* @return \ICWP_WPSF_ServiceProviders
|
127 |
*/
|
@@ -133,84 +54,6 @@ class Foundation {
|
|
133 |
return self::getService( $sKey );
|
134 |
}
|
135 |
|
136 |
-
/**
|
137 |
-
* @return \ICWP_WPSF_WpIncludes
|
138 |
-
* @deprecated
|
139 |
-
*/
|
140 |
-
static public function loadWpIncludes() {
|
141 |
-
$sKey = 'icwp-wpincludes';
|
142 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
143 |
-
self::setService( $sKey, \ICWP_WPSF_WpIncludes::GetInstance() );
|
144 |
-
}
|
145 |
-
return self::getService( $sKey );
|
146 |
-
}
|
147 |
-
|
148 |
-
/**
|
149 |
-
* @param string $sTemplatePath
|
150 |
-
* @return \ICWP_WPSF_Render
|
151 |
-
* @deprecated
|
152 |
-
*/
|
153 |
-
static public function loadRenderer( $sTemplatePath = '' ) {
|
154 |
-
$sKey = 'icwp-render';
|
155 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
156 |
-
self::setService( $sKey, \ICWP_WPSF_Render::GetInstance() );
|
157 |
-
}
|
158 |
-
|
159 |
-
/** @var \ICWP_WPSF_Render $oR */
|
160 |
-
$oR = self::getService( $sKey );
|
161 |
-
if ( !empty( $sTemplatePath ) ) {
|
162 |
-
$oR->setTemplateRoot( $sTemplatePath );
|
163 |
-
}
|
164 |
-
return ( clone $oR );
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* @return \ICWP_WPSF_WpAdminNotices
|
169 |
-
* @deprecated
|
170 |
-
*/
|
171 |
-
static public function loadWpNotices() {
|
172 |
-
$sKey = 'wp-admin-notices';
|
173 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
174 |
-
self::setService( $sKey, \ICWP_WPSF_WpAdminNotices::GetInstance() );
|
175 |
-
}
|
176 |
-
return self::getService( $sKey );
|
177 |
-
}
|
178 |
-
|
179 |
-
/**
|
180 |
-
* @return \ICWP_WPSF_WpUsers
|
181 |
-
* @deprecated
|
182 |
-
*/
|
183 |
-
static public function loadWpUsers() {
|
184 |
-
$sKey = 'wp-users';
|
185 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
186 |
-
self::setService( $sKey, \ICWP_WPSF_WpUsers::GetInstance() );
|
187 |
-
}
|
188 |
-
return self::getService( $sKey );
|
189 |
-
}
|
190 |
-
|
191 |
-
/**
|
192 |
-
* @return \ICWP_WPSF_WpComments
|
193 |
-
* @deprecated
|
194 |
-
*/
|
195 |
-
static public function loadWpComments() {
|
196 |
-
$sKey = 'wp-comments';
|
197 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
198 |
-
self::setService( $sKey, \ICWP_WPSF_WpComments::GetInstance() );
|
199 |
-
}
|
200 |
-
return self::getService( $sKey );
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* @return \ICWP_WPSF_Edd
|
205 |
-
*/
|
206 |
-
static public function loadEdd() {
|
207 |
-
$sKey = 'icwp-edd';
|
208 |
-
if ( !self::isServiceReady( $sKey ) ) {
|
209 |
-
self::setService( $sKey, \ICWP_WPSF_Edd::GetInstance() );
|
210 |
-
}
|
211 |
-
return self::getService( $sKey );
|
212 |
-
}
|
213 |
-
|
214 |
/**
|
215 |
* @return array
|
216 |
*/
|
@@ -248,12 +91,4 @@ class Foundation {
|
|
248 |
$aDic[ $sServiceKey ] = $oService;
|
249 |
self::$aDic = $aDic;
|
250 |
}
|
251 |
-
|
252 |
-
/**
|
253 |
-
* @return \ICWP_WPSF_WpAdminNotices
|
254 |
-
* @deprecated
|
255 |
-
*/
|
256 |
-
static public function loadAdminNoticesProcessor() {
|
257 |
-
return self::loadWpNotices();
|
258 |
-
}
|
259 |
}
|
21 |
|
22 |
/**
|
23 |
* @return \ICWP_WPSF_DataProcessor
|
24 |
+
* @deprecated 8.4.0
|
25 |
*/
|
26 |
static public function loadDP() {
|
27 |
$sKey = 'icwp-data';
|
31 |
return self::getService( $sKey );
|
32 |
}
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
/**
|
35 |
* @return \ICWP_WPSF_WpCron
|
36 |
* @deprecated
|
43 |
return self::getService( $sKey );
|
44 |
}
|
45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
/**
|
47 |
* @return \ICWP_WPSF_ServiceProviders
|
48 |
*/
|
54 |
return self::getService( $sKey );
|
55 |
}
|
56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
/**
|
58 |
* @return array
|
59 |
*/
|
91 |
$aDic[ $sServiceKey ] = $oService;
|
92 |
self::$aDic = $aDic;
|
93 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
}
|
src/lib/src/Modules/Autoupdates/AjaxHandler.php
CHANGED
@@ -29,16 +29,16 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
29 |
* @return array
|
30 |
*/
|
31 |
public function ajaxExec_TogglePluginAutoupdate() {
|
32 |
-
/** @var
|
33 |
-
$
|
34 |
$bSuccess = false;
|
35 |
$sMessage = __( 'You do not have permissions to perform this action.', 'wp-simple-firewall' );
|
36 |
|
37 |
-
if ( $
|
38 |
$oWpPlugins = Services::WpPlugins();
|
39 |
$sFile = Services::Request()->post( 'pluginfile' );
|
40 |
if ( $oWpPlugins->isInstalled( $sFile ) ) {
|
41 |
-
$
|
42 |
|
43 |
$sMessage = sprintf( __( 'Plugin "%s" will %s.', 'wp-simple-firewall' ),
|
44 |
$oWpPlugins->getPluginAsVo( $sFile )->Name,
|
29 |
* @return array
|
30 |
*/
|
31 |
public function ajaxExec_TogglePluginAutoupdate() {
|
32 |
+
/** @var Options $oOpts */
|
33 |
+
$oOpts = $this->getOptions();
|
34 |
$bSuccess = false;
|
35 |
$sMessage = __( 'You do not have permissions to perform this action.', 'wp-simple-firewall' );
|
36 |
|
37 |
+
if ( $oOpts->isAutoupdateIndividualPlugins() && $this->getCon()->isPluginAdmin() ) {
|
38 |
$oWpPlugins = Services::WpPlugins();
|
39 |
$sFile = Services::Request()->post( 'pluginfile' );
|
40 |
if ( $oWpPlugins->isInstalled( $sFile ) ) {
|
41 |
+
$oOpts->setPluginToAutoUpdate( $sFile );
|
42 |
|
43 |
$sMessage = sprintf( __( 'Plugin "%s" will %s.', 'wp-simple-firewall' ),
|
44 |
$oWpPlugins->getPluginAsVo( $sFile )->Name,
|
src/lib/src/Modules/Autoupdates/Options.php
CHANGED
@@ -3,6 +3,139 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Autoupdates;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
|
|
6 |
|
7 |
class Options extends Base\ShieldOptions {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Autoupdates;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
class Options extends Base\ShieldOptions {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @return string[]
|
12 |
+
*/
|
13 |
+
public function getAutoupdatePlugins() {
|
14 |
+
$aSelected = [];
|
15 |
+
if ( $this->isAutoupdateIndividualPlugins() ) {
|
16 |
+
$aSelected = $this->getOpt( 'selected_plugins', [] );
|
17 |
+
if ( !is_array( $aSelected ) ) {
|
18 |
+
$aSelected = [];
|
19 |
+
}
|
20 |
+
}
|
21 |
+
return $aSelected;
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @return array
|
26 |
+
*/
|
27 |
+
public function getDelayTracking() {
|
28 |
+
$aTracking = $this->getOpt( 'delay_tracking', [] );
|
29 |
+
if ( !is_array( $aTracking ) ) {
|
30 |
+
$aTracking = [];
|
31 |
+
}
|
32 |
+
$aTracking = Services::DataManipulation()->mergeArraysRecursive(
|
33 |
+
[
|
34 |
+
'core' => [],
|
35 |
+
'plugins' => [],
|
36 |
+
'themes' => [],
|
37 |
+
],
|
38 |
+
$aTracking
|
39 |
+
);
|
40 |
+
$this->setOpt( 'delay_tracking', $aTracking );
|
41 |
+
|
42 |
+
return $aTracking;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @return int
|
47 |
+
*/
|
48 |
+
public function getDelayUpdatesPeriod() {
|
49 |
+
return $this->isPremium() ? $this->getOpt( 'update_delay', 0 )*DAY_IN_SECONDS : 0;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @return string
|
54 |
+
*/
|
55 |
+
public function getSelfAutoUpdateOpt() {
|
56 |
+
return $this->getOpt( 'autoupdate_plugin_self' );
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @return bool
|
61 |
+
*/
|
62 |
+
public function isAutoUpdateCoreMajor() {
|
63 |
+
return $this->isOpt( 'autoupdate_core', 'core_major' );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @return bool
|
68 |
+
*/
|
69 |
+
public function isAutoUpdateCoreMinor() {
|
70 |
+
return !$this->isOpt( 'autoupdate_core', 'core_never' );
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @return bool
|
75 |
+
*/
|
76 |
+
public function isAutoupdateAllPlugins() {
|
77 |
+
return $this->isOpt( 'enable_autoupdate_plugins', 'Y' );
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @return bool
|
82 |
+
*/
|
83 |
+
public function isAutoupdateIndividualPlugins() {
|
84 |
+
return $this->isPremium() && $this->isOpt( 'enable_individual_autoupdate_plugins', 'Y' );
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @return bool
|
89 |
+
*/
|
90 |
+
public function isDisableAllAutoUpdates() {
|
91 |
+
return $this->isOpt( 'enable_autoupdate_disable_all', 'Y' );
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @return bool
|
96 |
+
*/
|
97 |
+
public function isDelayUpdates() {
|
98 |
+
return $this->getDelayUpdatesPeriod() > 0;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @param string $sPluginFile
|
103 |
+
* @return bool
|
104 |
+
*/
|
105 |
+
public function isPluginSetToAutoupdate( $sPluginFile ) {
|
106 |
+
return in_array( $sPluginFile, $this->getAutoupdatePlugins() );
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* @return bool
|
111 |
+
*/
|
112 |
+
public function isSendAutoupdatesNotificationEmail() {
|
113 |
+
return $this->isOpt( 'enable_upgrade_notification_email', 'Y' );
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* @param array $aTrackingInfo
|
118 |
+
* @return $this
|
119 |
+
*/
|
120 |
+
public function setDelayTracking( $aTrackingInfo ) {
|
121 |
+
return $this->setOpt( 'delay_tracking', $aTrackingInfo );
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* @param string $sPluginFile
|
126 |
+
* @return $this
|
127 |
+
*/
|
128 |
+
public function setPluginToAutoUpdate( $sPluginFile ) {
|
129 |
+
$aPlugins = $this->getAutoupdatePlugins();
|
130 |
+
$nKey = array_search( $sPluginFile, $aPlugins );
|
131 |
+
|
132 |
+
if ( $nKey === false ) {
|
133 |
+
$aPlugins[] = $sPluginFile;
|
134 |
+
}
|
135 |
+
else {
|
136 |
+
unset( $aPlugins[ $nKey ] );
|
137 |
+
}
|
138 |
+
|
139 |
+
return $this->setOpt( 'selected_plugins', $aPlugins );
|
140 |
+
}
|
141 |
}
|
src/lib/src/Modules/Base/AdminNotices.php
CHANGED
@@ -13,7 +13,7 @@ class AdminNotices {
|
|
13 |
/**
|
14 |
* @var
|
15 |
*/
|
16 |
-
static
|
17 |
|
18 |
public function run() {
|
19 |
$oMod = $this->getMod();
|
@@ -126,28 +126,28 @@ class AdminNotices {
|
|
126 |
if ( $oNtc->plugin_page_only && !$oCon->isModulePage() ) {
|
127 |
$oNtc->non_display_reason = 'plugin_page_only';
|
128 |
}
|
129 |
-
|
130 |
$oNtc->non_display_reason = 'promo_hidden';
|
131 |
}
|
132 |
-
|
133 |
$oNtc->non_display_reason = 'not_admin_area';
|
134 |
}
|
135 |
-
|
136 |
$oNtc->non_display_reason = 'not_plugin_admin';
|
137 |
}
|
138 |
-
|
139 |
$oNtc->non_display_reason = 'is_plugin_admin';
|
140 |
}
|
141 |
-
|
142 |
$oNtc->non_display_reason = 'min_install_days';
|
143 |
}
|
144 |
-
|
145 |
$oNtc->non_display_reason = 'max_nonerror_count';
|
146 |
}
|
147 |
-
|
148 |
$oNtc->non_display_reason = 'dismissed';
|
149 |
}
|
150 |
-
|
151 |
$oNtc->non_display_reason = 'not_needed';
|
152 |
}
|
153 |
else {
|
13 |
/**
|
14 |
* @var
|
15 |
*/
|
16 |
+
protected static $nCount = 0;
|
17 |
|
18 |
public function run() {
|
19 |
$oMod = $this->getMod();
|
126 |
if ( $oNtc->plugin_page_only && !$oCon->isModulePage() ) {
|
127 |
$oNtc->non_display_reason = 'plugin_page_only';
|
128 |
}
|
129 |
+
elseif ( $oNtc->type == 'promo' && !$this->getOptions()->isShowPromoAdminNotices() ) {
|
130 |
$oNtc->non_display_reason = 'promo_hidden';
|
131 |
}
|
132 |
+
elseif ( $oNtc->valid_admin && !$oCon->isValidAdminArea() ) {
|
133 |
$oNtc->non_display_reason = 'not_admin_area';
|
134 |
}
|
135 |
+
elseif ( $oNtc->plugin_admin == 'yes' && !$oCon->isPluginAdmin() ) {
|
136 |
$oNtc->non_display_reason = 'not_plugin_admin';
|
137 |
}
|
138 |
+
elseif ( $oNtc->plugin_admin == 'no' && $oCon->isPluginAdmin() ) {
|
139 |
$oNtc->non_display_reason = 'is_plugin_admin';
|
140 |
}
|
141 |
+
elseif ( $oNtc->min_install_days > 0 && $oNtc->min_install_days > $oOpts->getInstallationDays() ) {
|
142 |
$oNtc->non_display_reason = 'min_install_days';
|
143 |
}
|
144 |
+
elseif ( static::$nCount > 0 && $oNtc->type !== 'error' ) {
|
145 |
$oNtc->non_display_reason = 'max_nonerror_count';
|
146 |
}
|
147 |
+
elseif ( $oNtc->can_dismiss && $this->isNoticeDismissed( $oNtc ) ) {
|
148 |
$oNtc->non_display_reason = 'dismissed';
|
149 |
}
|
150 |
+
elseif ( !$this->isDisplayNeeded( $oNtc ) ) {
|
151 |
$oNtc->non_display_reason = 'not_needed';
|
152 |
}
|
153 |
else {
|
src/lib/src/Modules/Base/BaseModCon.php
CHANGED
@@ -133,6 +133,9 @@ class BaseModCon extends Deprecated\Foundation {
|
|
133 |
add_filter( $this->prefix( 'is_event_supported' ), function ( $bSupported, $sEventTag ) {
|
134 |
return $bSupported || $this->isSupportedEvent( $sEventTag );
|
135 |
}, 10, 2 );
|
|
|
|
|
|
|
136 |
|
137 |
add_action( 'admin_enqueue_scripts', [ $this, 'onWpEnqueueAdminJs' ], 100 );
|
138 |
|
@@ -481,14 +484,6 @@ class BaseModCon extends Deprecated\Foundation {
|
|
481 |
);
|
482 |
}
|
483 |
|
484 |
-
/**
|
485 |
-
* @return \ICWP_WPSF_OptionsVO
|
486 |
-
* @deprecated 8.1
|
487 |
-
*/
|
488 |
-
public function getOptionsVo() {
|
489 |
-
return $this->getOptions();
|
490 |
-
}
|
491 |
-
|
492 |
/**
|
493 |
* @return bool
|
494 |
*/
|
@@ -1513,8 +1508,8 @@ class BaseModCon extends Deprecated\Foundation {
|
|
1513 |
'has_wizard' => $this->hasWizard(),
|
1514 |
],
|
1515 |
'hrefs' => [
|
1516 |
-
'go_pro' => 'https://
|
1517 |
-
'goprofooter' => 'https://
|
1518 |
'wizard_link' => $this->getUrl_WizardLanding(),
|
1519 |
'wizard_landing' => $this->getUrl_WizardLanding()
|
1520 |
],
|
@@ -1904,51 +1899,21 @@ class BaseModCon extends Deprecated\Foundation {
|
|
1904 |
return !empty( $sId );
|
1905 |
}
|
1906 |
|
1907 |
-
/**
|
1908 |
-
* @param string $sOpt
|
1909 |
-
* @param int $nAt
|
1910 |
-
* @return $this
|
1911 |
-
*/
|
1912 |
-
protected function setOptAt( $sOpt, $nAt = null ) {
|
1913 |
-
$nAt = is_null( $nAt ) ? Services::Request()->ts() : max( 0, (int)$nAt );
|
1914 |
-
return $this->setOpt( $sOpt, $nAt );
|
1915 |
-
}
|
1916 |
-
|
1917 |
/**
|
1918 |
* @return null|Shield\Modules\Base\ShieldOptions|mixed
|
1919 |
*/
|
1920 |
public function getOptions() {
|
1921 |
if ( !isset( $this->oOpts ) ) {
|
1922 |
-
|
1923 |
-
$oOpts = $this->loadOptions()->setMod( $this );;
|
1924 |
-
|
1925 |
$oCon = $this->getCon();
|
1926 |
-
$this->oOpts = $
|
1927 |
-
|
1928 |
-
|
1929 |
-
|
|
|
1930 |
}
|
1931 |
return $this->oOpts;
|
1932 |
}
|
1933 |
|
1934 |
-
/**
|
1935 |
-
* @return null|Shield\Databases\Base\Handler|mixed
|
1936 |
-
*/
|
1937 |
-
public function getDbHandler() {
|
1938 |
-
if ( !isset( $this->oDbh ) ) {
|
1939 |
-
$this->oDbh = $this->loadDbHandler();
|
1940 |
-
if ( $this->oDbh instanceof Shield\Databases\Base\Handler ) {
|
1941 |
-
try {
|
1942 |
-
$this->oDbh->setMod( $this )
|
1943 |
-
->tableInit();
|
1944 |
-
}
|
1945 |
-
catch ( \Exception$oE ) {
|
1946 |
-
}
|
1947 |
-
}
|
1948 |
-
}
|
1949 |
-
return $this->oDbh;
|
1950 |
-
}
|
1951 |
-
|
1952 |
/**
|
1953 |
* @return string
|
1954 |
*/
|
133 |
add_filter( $this->prefix( 'is_event_supported' ), function ( $bSupported, $sEventTag ) {
|
134 |
return $bSupported || $this->isSupportedEvent( $sEventTag );
|
135 |
}, 10, 2 );
|
136 |
+
add_filter( $this->prefix( 'get_all_events' ), function ( $aEvents ) {
|
137 |
+
return array_merge( $aEvents, $this->getEvents() );
|
138 |
+
} );
|
139 |
|
140 |
add_action( 'admin_enqueue_scripts', [ $this, 'onWpEnqueueAdminJs' ], 100 );
|
141 |
|
484 |
);
|
485 |
}
|
486 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
487 |
/**
|
488 |
* @return bool
|
489 |
*/
|
1508 |
'has_wizard' => $this->hasWizard(),
|
1509 |
],
|
1510 |
'hrefs' => [
|
1511 |
+
'go_pro' => 'https://shsec.io/shieldgoprofeature',
|
1512 |
+
'goprofooter' => 'https://shsec.io/goprofooter',
|
1513 |
'wizard_link' => $this->getUrl_WizardLanding(),
|
1514 |
'wizard_landing' => $this->getUrl_WizardLanding()
|
1515 |
],
|
1899 |
return !empty( $sId );
|
1900 |
}
|
1901 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1902 |
/**
|
1903 |
* @return null|Shield\Modules\Base\ShieldOptions|mixed
|
1904 |
*/
|
1905 |
public function getOptions() {
|
1906 |
if ( !isset( $this->oOpts ) ) {
|
|
|
|
|
|
|
1907 |
$oCon = $this->getCon();
|
1908 |
+
$this->oOpts = $this->loadOptions()->setMod( $this );
|
1909 |
+
$this->oOpts->setPathToConfig( $oCon->getPath_ConfigFile( $this->getSlug() ) )
|
1910 |
+
->setRebuildFromFile( $oCon->getIsRebuildOptionsFromFile() )
|
1911 |
+
->setOptionsStorageKey( $this->getOptionsStorageKey() )
|
1912 |
+
->setIfLoadOptionsFromStorage( !$oCon->getIsResetPlugin() );
|
1913 |
}
|
1914 |
return $this->oOpts;
|
1915 |
}
|
1916 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1917 |
/**
|
1918 |
* @return string
|
1919 |
*/
|
src/lib/src/Modules/Base/BaseProcessor.php
CHANGED
@@ -43,7 +43,6 @@ class BaseProcessor extends Deprecated\Foundation {
|
|
43 |
add_action( $oMod->prefix( 'daily_cron' ), [ $this, 'runDailyCron' ] );
|
44 |
add_action( $oMod->prefix( 'hourly_cron' ), [ $this, 'runHourlyCron' ] );
|
45 |
add_action( $oMod->prefix( 'deactivate_plugin' ), [ $this, 'deactivatePlugin' ] );
|
46 |
-
add_action( $oMod->prefix( 'generate_admin_notices' ), [ $this, 'autoAddToAdminNotices' ] );
|
47 |
|
48 |
/**
|
49 |
* 2019-04-19:
|
@@ -74,11 +73,6 @@ class BaseProcessor extends Deprecated\Foundation {
|
|
74 |
* @param \WP_User $oUser
|
75 |
*/
|
76 |
public function onWpLogin( $sUsername, $oUser ) {
|
77 |
-
/*
|
78 |
-
if ( !$oUser instanceof WP_User ) {
|
79 |
-
$oUser = $this->loadWpUsers()->getUserByUsername( $sUsername );
|
80 |
-
}
|
81 |
-
*/
|
82 |
}
|
83 |
|
84 |
/**
|
@@ -215,26 +209,4 @@ class BaseProcessor extends Deprecated\Foundation {
|
|
215 |
protected function prefix( $sSuffix = '', $sGlue = '-' ) {
|
216 |
return $this->getMod()->prefix( $sSuffix, $sGlue );
|
217 |
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* @return string
|
221 |
-
* @deprecated
|
222 |
-
*/
|
223 |
-
protected function ip() {
|
224 |
-
return Services::IP()->getRequestIp();
|
225 |
-
}
|
226 |
-
|
227 |
-
/**
|
228 |
-
* @return int
|
229 |
-
* @deprecated 8
|
230 |
-
*/
|
231 |
-
protected function time() {
|
232 |
-
return Services::Request()->ts();
|
233 |
-
}
|
234 |
-
|
235 |
-
/**
|
236 |
-
* @deprecated
|
237 |
-
*/
|
238 |
-
public function autoAddToAdminNotices() {
|
239 |
-
}
|
240 |
}
|
43 |
add_action( $oMod->prefix( 'daily_cron' ), [ $this, 'runDailyCron' ] );
|
44 |
add_action( $oMod->prefix( 'hourly_cron' ), [ $this, 'runHourlyCron' ] );
|
45 |
add_action( $oMod->prefix( 'deactivate_plugin' ), [ $this, 'deactivatePlugin' ] );
|
|
|
46 |
|
47 |
/**
|
48 |
* 2019-04-19:
|
73 |
* @param \WP_User $oUser
|
74 |
*/
|
75 |
public function onWpLogin( $sUsername, $oUser ) {
|
|
|
|
|
|
|
|
|
|
|
76 |
}
|
77 |
|
78 |
/**
|
209 |
protected function prefix( $sSuffix = '', $sGlue = '-' ) {
|
210 |
return $this->getMod()->prefix( $sSuffix, $sGlue );
|
211 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
}
|
src/lib/src/Modules/Base/Options.php
CHANGED
@@ -1025,7 +1025,7 @@ class Options {
|
|
1025 |
/**
|
1026 |
* @param string
|
1027 |
* @return mixed|null
|
1028 |
-
* @deprecated 8.
|
1029 |
*/
|
1030 |
public function getFeatureDefinition( $sDefinition ) {
|
1031 |
return $this->getDef( $sDefinition );
|
1025 |
/**
|
1026 |
* @param string
|
1027 |
* @return mixed|null
|
1028 |
+
* @deprecated 8.4
|
1029 |
*/
|
1030 |
public function getFeatureDefinition( $sDefinition ) {
|
1031 |
return $this->getDef( $sDefinition );
|
src/lib/src/Modules/Base/Strings.php
CHANGED
@@ -66,7 +66,7 @@ class Strings {
|
|
66 |
'pro_only_feature' => __( 'This is a pro-only feature', 'wp-simple-firewall' ),
|
67 |
'go_pro' => __( 'Go Pro!', 'wp-simple-firewall' ),
|
68 |
'go_pro_option' => sprintf( '<a href="%s" target="_blank">%s</a>',
|
69 |
-
'https://
|
70 |
|
71 |
'description' => __( 'Description', 'wp-simple-firewall' ),
|
72 |
'loading' => __( 'Loading', 'wp-simple-firewall' ),
|
66 |
'pro_only_feature' => __( 'This is a pro-only feature', 'wp-simple-firewall' ),
|
67 |
'go_pro' => __( 'Go Pro!', 'wp-simple-firewall' ),
|
68 |
'go_pro_option' => sprintf( '<a href="%s" target="_blank">%s</a>',
|
69 |
+
'https://shsec.io/shieldgoprofeature', __( 'Please upgrade to Pro to control this option', 'wp-simple-firewall' ) ),
|
70 |
|
71 |
'description' => __( 'Description', 'wp-simple-firewall' ),
|
72 |
'loading' => __( 'Loading', 'wp-simple-firewall' ),
|
src/lib/src/Modules/CommentsFilter/AjaxHandler.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param string $sAction
|
12 |
+
* @return array
|
13 |
+
*/
|
14 |
+
protected function processAjaxAction( $sAction ) {
|
15 |
+
|
16 |
+
switch ( $sAction ) {
|
17 |
+
case 'comment_token'.Services::IP()->getRequestIp():
|
18 |
+
$aResponse = $this->ajaxExec_GenCommentToken();
|
19 |
+
break;
|
20 |
+
|
21 |
+
default:
|
22 |
+
$aResponse = parent::processAjaxAction( $sAction );
|
23 |
+
}
|
24 |
+
|
25 |
+
return $aResponse;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @return array
|
30 |
+
*/
|
31 |
+
private function ajaxExec_GenCommentToken() {
|
32 |
+
$oReq = Services::Request();
|
33 |
+
$sToken = ( new Shield\Modules\CommentsFilter\Token\Create() )
|
34 |
+
->setMod( $this->getMod() )
|
35 |
+
->run( $oReq->post( 'ts' ), $oReq->post( 'post_id' ) );
|
36 |
+
|
37 |
+
return [
|
38 |
+
'success' => true,
|
39 |
+
'token' => $sToken,
|
40 |
+
];
|
41 |
+
}
|
42 |
+
}
|
src/lib/src/Modules/CommentsFilter/Scan/Human.php
CHANGED
@@ -87,7 +87,7 @@ class Human {
|
|
87 |
$oFs = Services::WpFs();
|
88 |
$sBLFile = $oMod->getSpamBlacklistFile();
|
89 |
if ( !$oFs->exists( $sBLFile ) ) {
|
90 |
-
$sRawList = Services::HttpRequest()->getContent( $this->
|
91 |
$sList = '';
|
92 |
if ( !empty( $sRawList ) ) {
|
93 |
$sList = implode( "\n", array_map( 'base64_encode', array_filter( array_map( 'trim', explode( "\n", $sRawList ) ) ) ) );
|
87 |
$oFs = Services::WpFs();
|
88 |
$sBLFile = $oMod->getSpamBlacklistFile();
|
89 |
if ( !$oFs->exists( $sBLFile ) ) {
|
90 |
+
$sRawList = Services::HttpRequest()->getContent( $this->getOptions()->getDef( 'url_spam_blacklist_terms' ) );
|
91 |
$sList = '';
|
92 |
if ( !empty( $sRawList ) ) {
|
93 |
$sList = implode( "\n", array_map( 'base64_encode', array_filter( array_map( 'trim', explode( "\n", $sRawList ) ) ) ) );
|
src/lib/src/Modules/CommentsFilter/Token/Create.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\CommentsFilter\Token;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Services\Services;
|
7 |
+
|
8 |
+
class Create {
|
9 |
+
|
10 |
+
use ModConsumer;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @param int $nTs
|
14 |
+
* @param int $nPostId
|
15 |
+
* @return string
|
16 |
+
*/
|
17 |
+
public function run( $nTs, $nPostId ) {
|
18 |
+
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $oMod */
|
19 |
+
$oMod = $this->getMod();
|
20 |
+
|
21 |
+
$sToken = $this->generateNewToken( $nTs, $nPostId );
|
22 |
+
|
23 |
+
Services::WpGeneral()->setTransient(
|
24 |
+
$oMod->prefix( 'comtok-'.md5( sprintf( '%s-%s-%s', $nPostId, $nTs, Services::IP()->getRequestIp() ) ) ),
|
25 |
+
$sToken,
|
26 |
+
$oMod->getTokenExpireInterval()
|
27 |
+
);
|
28 |
+
error_log( $nTs );
|
29 |
+
error_log( $nPostId );
|
30 |
+
error_log( $sToken );
|
31 |
+
|
32 |
+
return $sToken;
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @param int $nTs
|
37 |
+
* @param string $nPostId
|
38 |
+
* @return string
|
39 |
+
*/
|
40 |
+
private function generateNewToken( $nTs, $nPostId ) {
|
41 |
+
return hash_hmac( 'sha1',
|
42 |
+
$nPostId.Services::IP()->getRequestIp().$nTs, $this->getCon()->getSiteInstallationId()
|
43 |
+
);
|
44 |
+
}
|
45 |
+
}
|
src/lib/src/Modules/Events/AjaxHandler.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Events;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
@@ -18,6 +19,10 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
18 |
$aResponse = $this->ajaxExec_RenderChart();
|
19 |
break;
|
20 |
|
|
|
|
|
|
|
|
|
21 |
default:
|
22 |
$aResponse = parent::processAjaxAction( $sAction );
|
23 |
}
|
@@ -28,42 +33,44 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
28 |
/**
|
29 |
* @return array
|
30 |
*/
|
31 |
-
|
32 |
/** @var \ICWP_WPSF_FeatureHandler_Events $oMod */
|
33 |
$oMod = $this->getMod();
|
34 |
|
35 |
$aParams = $this->getAjaxFormParams();
|
36 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
$
|
43 |
-
$
|
|
|
|
|
|
|
|
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
$
|
48 |
-
$aSeries[] = $oSelEvts->filterByBoundary_Day( $oNow->timestamp )
|
49 |
-
->sumEvent( $sEvent );
|
50 |
-
$aLabels[] = $oNow->toDateString();
|
51 |
-
$oNow->subDay();
|
52 |
-
$nDays++;
|
53 |
-
} while ( $nDays < 7 );
|
54 |
|
55 |
return [
|
56 |
'success' => true,
|
57 |
-
'message' => '
|
58 |
-
'chart' =>
|
59 |
-
'data' => [
|
60 |
-
'labels' => array_reverse( $aLabels ),
|
61 |
-
'series' => [
|
62 |
-
array_reverse( $aSeries ),
|
63 |
-
]
|
64 |
-
],
|
65 |
-
'legend_names' => [ 'Total Offenses' ],
|
66 |
-
]
|
67 |
];
|
68 |
}
|
69 |
}
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Events;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Events;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
19 |
$aResponse = $this->ajaxExec_RenderChart();
|
20 |
break;
|
21 |
|
22 |
+
case 'render_chart_post':
|
23 |
+
$aResponse = $this->ajaxExec_RenderChartPost();
|
24 |
+
break;
|
25 |
+
|
26 |
default:
|
27 |
$aResponse = parent::processAjaxAction( $sAction );
|
28 |
}
|
33 |
/**
|
34 |
* @return array
|
35 |
*/
|
36 |
+
private function ajaxExec_RenderChart() {
|
37 |
/** @var \ICWP_WPSF_FeatureHandler_Events $oMod */
|
38 |
$oMod = $this->getMod();
|
39 |
|
40 |
$aParams = $this->getAjaxFormParams();
|
41 |
+
$oReq = new Events\Charts\ChartRequestVO();
|
42 |
+
$oReq->render_location = $aParams[ 'render_location' ];
|
43 |
+
$oReq->chart_params = $aParams[ 'chart_params' ];
|
44 |
+
$aChart = ( new Events\Charts\BuildData() )
|
45 |
+
->setMod( $oMod )
|
46 |
+
->build( $oReq );
|
47 |
+
|
48 |
+
return [
|
49 |
+
'success' => true,
|
50 |
+
'message' => 'no message',
|
51 |
+
'chart' => $aChart
|
52 |
+
];
|
53 |
+
}
|
54 |
|
55 |
+
/**
|
56 |
+
* @return array
|
57 |
+
*/
|
58 |
+
private function ajaxExec_RenderChartPost() {
|
59 |
+
/** @var \ICWP_WPSF_FeatureHandler_Events $oMod */
|
60 |
+
$oMod = $this->getMod();
|
61 |
+
$oReq = Services::Request();
|
62 |
+
$oChartReq = new Events\Charts\ChartRequestVO();
|
63 |
+
$oChartReq->render_location = $oReq->post( 'render_location' );
|
64 |
+
$oChartReq->chart_params = $oReq->post( 'chart_params' );
|
65 |
|
66 |
+
$aChart = ( new Events\Charts\BuildData() )
|
67 |
+
->setMod( $oMod )
|
68 |
+
->build( $oChartReq );
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
return [
|
71 |
'success' => true,
|
72 |
+
'message' => 'no message',
|
73 |
+
'chart' => $aChart
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
];
|
75 |
}
|
76 |
}
|
src/lib/src/Modules/Events/Charts/BuildData.php
ADDED
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Events\Charts;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Events;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class BuildData {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @param ChartRequestVO $oReq
|
15 |
+
* @return array
|
16 |
+
*/
|
17 |
+
public function build( ChartRequestVO $oReq ) {
|
18 |
+
/** @var \ICWP_WPSF_FeatureHandler_Events $oMod */
|
19 |
+
$oMod = $this->getMod();
|
20 |
+
|
21 |
+
$this->preProcessRequest( $oReq );
|
22 |
+
|
23 |
+
/** @var Events\Handler $oDbhEvts */
|
24 |
+
$oDbhEvts = $oMod->getDbHandler_Events();
|
25 |
+
|
26 |
+
$nTick = 0;
|
27 |
+
$oTime = Services::Request()->carbon();
|
28 |
+
|
29 |
+
$aLabels = [];
|
30 |
+
$aSeries = [];
|
31 |
+
do {
|
32 |
+
$aLabels[] = $oTime->toDateString();
|
33 |
+
|
34 |
+
/** @var Events\Select $oSelEvts */
|
35 |
+
$oSelEvts = $oDbhEvts->getQuerySelector();
|
36 |
+
switch ( $oReq->interval ) {
|
37 |
+
case 'hourly':
|
38 |
+
$oSelEvts->filterByBoundary_Hour( $oTime->timestamp );
|
39 |
+
$oTime->subHour();
|
40 |
+
break;
|
41 |
+
case 'daily':
|
42 |
+
$oSelEvts->filterByBoundary_Day( $oTime->timestamp );
|
43 |
+
$oTime->subDay();
|
44 |
+
break;
|
45 |
+
case 'weekly':
|
46 |
+
$oSelEvts->filterByBoundary_Week( $oTime->timestamp );
|
47 |
+
$oTime->subWeek();
|
48 |
+
break;
|
49 |
+
case 'monthly':
|
50 |
+
$oSelEvts->filterByBoundary_Month( $oTime->timestamp );
|
51 |
+
$oTime->subMonth();
|
52 |
+
break;
|
53 |
+
case 'yearly':
|
54 |
+
$oSelEvts->filterByBoundary_Year( $oTime->timestamp );
|
55 |
+
$oTime->subYear();
|
56 |
+
break;
|
57 |
+
}
|
58 |
+
|
59 |
+
$aSeries[] = $oSelEvts->sumEvents( $oReq->events );
|
60 |
+
|
61 |
+
$nTick++;
|
62 |
+
} while ( $nTick < $oReq->ticks );
|
63 |
+
|
64 |
+
return [
|
65 |
+
'data' => [
|
66 |
+
'labels' => [],
|
67 |
+
'series' => [
|
68 |
+
array_reverse( $aSeries ),
|
69 |
+
]
|
70 |
+
],
|
71 |
+
'legend_names' => [],
|
72 |
+
];
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @param ChartRequestVO $oReq
|
77 |
+
*/
|
78 |
+
protected function preProcessRequest( ChartRequestVO $oReq ) {
|
79 |
+
|
80 |
+
if ( empty( $oReq->interval ) ) {
|
81 |
+
switch ( $oReq->render_location ) {
|
82 |
+
case $oReq::LOCATION_STATCARD:
|
83 |
+
$oReq->interval = 'daily';
|
84 |
+
break;
|
85 |
+
default:
|
86 |
+
$oReq->interval = 'weekly';
|
87 |
+
break;
|
88 |
+
}
|
89 |
+
}
|
90 |
+
|
91 |
+
$aAll = array_keys( $this->getCon()->getAllEvents() );
|
92 |
+
if ( !empty( $oReq->chart_params[ 'stat_id' ] ) ) {
|
93 |
+
switch ( $oReq->chart_params[ 'stat_id' ] ) {
|
94 |
+
case 'comment_block':
|
95 |
+
$oReq->events = array_filter(
|
96 |
+
$aAll,
|
97 |
+
function ( $sEvent ) {
|
98 |
+
return strpos( $sEvent, 'spam_block_' ) === 0;
|
99 |
+
}
|
100 |
+
);
|
101 |
+
break;
|
102 |
+
case 'bot_blocks':
|
103 |
+
$oReq->events = array_filter(
|
104 |
+
$aAll,
|
105 |
+
function ( $sEvent ) {
|
106 |
+
return strpos( $sEvent, 'bottrack_' ) === 0;
|
107 |
+
}
|
108 |
+
);
|
109 |
+
break;
|
110 |
+
default:
|
111 |
+
$oReq->events = (array)$oReq->chart_params[ 'stat_id' ];
|
112 |
+
break;
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
if ( empty( $oReq->ticks ) ) {
|
117 |
+
switch ( $oReq->interval ) {
|
118 |
+
case 'daily':
|
119 |
+
$oReq->ticks = 7;
|
120 |
+
break;
|
121 |
+
case 'weekly':
|
122 |
+
$oReq->ticks = 8;
|
123 |
+
break;
|
124 |
+
default:
|
125 |
+
$oReq->ticks = 12;
|
126 |
+
break;
|
127 |
+
}
|
128 |
+
}
|
129 |
+
}
|
130 |
+
}
|
src/lib/src/Modules/Events/Charts/ChartRequestVO.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Events\Charts;
|
4 |
+
|
5 |
+
use FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class ChartRequestVO
|
9 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Modules\Events\Charts
|
10 |
+
* @property string $render_location
|
11 |
+
* @property string $interval
|
12 |
+
* @property string $ticks
|
13 |
+
* @property string[] $events
|
14 |
+
* @property array $chart_params
|
15 |
+
*/
|
16 |
+
class ChartRequestVO {
|
17 |
+
|
18 |
+
const LOCATION_STATCARD = 'insights-overview-statcard';
|
19 |
+
use StdClassAdapter;
|
20 |
+
}
|
src/lib/src/Modules/Events/Consolidate/ConsolidateAllEvents.php
ADDED
@@ -0,0 +1,291 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Events\Consolidate;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\Events;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class ConsolidateAllEvents {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
public function run() {
|
14 |
+
foreach ( $this->getAllEvents() as $sEvent ) {
|
15 |
+
$this->consolidateEventIntoHourly( $sEvent );
|
16 |
+
$this->consolidateEventIntoDaily( $sEvent );
|
17 |
+
$this->consolidateEventIntoWeekly( $sEvent );
|
18 |
+
$this->consolidateEventIntoMonthly( $sEvent );
|
19 |
+
$this->consolidateEventIntoYearly( $sEvent );
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @param $sEvent
|
25 |
+
*/
|
26 |
+
protected function consolidateEventIntoHourly( $sEvent ) {
|
27 |
+
/** @var \ICWP_WPSF_FeatureHandler_Events $oMod */
|
28 |
+
$oMod = $this->getMod();
|
29 |
+
$oDbH = $oMod->getDbHandler_Events();
|
30 |
+
|
31 |
+
$oTime = Services::Request()
|
32 |
+
->carbon()
|
33 |
+
->subHour( 1 )
|
34 |
+
->startOfHour();
|
35 |
+
|
36 |
+
$nHourCount = 0;
|
37 |
+
do {
|
38 |
+
/** @var Events\Select $oSel */
|
39 |
+
$oSel = $oDbH->getQuerySelector();
|
40 |
+
$nRecords = $oSel->filterByBoundary_Hour( $oTime->timestamp )
|
41 |
+
->filterByEvent( $sEvent )
|
42 |
+
->count();
|
43 |
+
|
44 |
+
if ( $nRecords > 1 ) {
|
45 |
+
/** @var Events\Select $oSel */
|
46 |
+
$oSel = $oDbH->getQuerySelector();
|
47 |
+
/** @var Events\EntryVO[] $aRecords */
|
48 |
+
$nSum = $oSel->filterByBoundary_Hour( $oTime->timestamp )
|
49 |
+
->sumEvent( $sEvent );
|
50 |
+
if ( $nSum > 0 ) {
|
51 |
+
|
52 |
+
/** @var Events\Delete $oDel */
|
53 |
+
$oDel = $oDbH->getQueryDeleter();
|
54 |
+
$oDel->filterByBoundary_Hour( $oTime->timestamp )
|
55 |
+
->filterByEvent( $sEvent )
|
56 |
+
->query();
|
57 |
+
|
58 |
+
$oEntry = new Events\EntryVO();
|
59 |
+
$oEntry->event = $sEvent;
|
60 |
+
$oEntry->count = $nSum;
|
61 |
+
$oEntry->created_at = $oTime->timestamp + 1;
|
62 |
+
/** @var Events\Insert $oQI */
|
63 |
+
$oQI = $oDbH->getQueryInserter();
|
64 |
+
$oQI->insert( $oEntry );
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
$nHourCount++;
|
69 |
+
$oTime->subHour();
|
70 |
+
} while ( $nHourCount < 48 );
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Consolidates each event in Daily sums. Doesn't process events from the previous 48hrs.
|
75 |
+
* Processes event for the 7 days previous to the last 48 hours.
|
76 |
+
* @param $sEvent
|
77 |
+
*/
|
78 |
+
protected function consolidateEventIntoDaily( $sEvent ) {
|
79 |
+
/** @var \ICWP_WPSF_FeatureHandler_Events $oMod */
|
80 |
+
$oMod = $this->getMod();
|
81 |
+
$oDbH = $oMod->getDbHandler_Events();
|
82 |
+
|
83 |
+
$oTime = Services::Request()
|
84 |
+
->carbon()
|
85 |
+
->subDays( 2 )
|
86 |
+
->startOfDay();
|
87 |
+
|
88 |
+
$nDayCount = 0;
|
89 |
+
do {
|
90 |
+
/** @var Events\Select $oSel */
|
91 |
+
$oSel = $oDbH->getQuerySelector();
|
92 |
+
$nRecords = $oSel->filterByBoundary_Day( $oTime->timestamp )
|
93 |
+
->filterByEvent( $sEvent )
|
94 |
+
->count();
|
95 |
+
|
96 |
+
if ( $nRecords > 1 ) {
|
97 |
+
/** @var Events\Select $oSel */
|
98 |
+
$oSel = $oDbH->getQuerySelector();
|
99 |
+
/** @var Events\EntryVO[] $aRecords */
|
100 |
+
$nSum = $oSel->filterByBoundary_Day( $oTime->timestamp )
|
101 |
+
->sumEvent( $sEvent );
|
102 |
+
if ( $nSum > 0 ) {
|
103 |
+
|
104 |
+
/** @var Events\Delete $oDel */
|
105 |
+
$oDel = $oDbH->getQueryDeleter();
|
106 |
+
$oDel->filterByBoundary_Day( $oTime->timestamp )
|
107 |
+
->filterByEvent( $sEvent )
|
108 |
+
->query();
|
109 |
+
|
110 |
+
$oEntry = new Events\EntryVO();
|
111 |
+
$oEntry->event = $sEvent;
|
112 |
+
$oEntry->count = $nSum;
|
113 |
+
$oEntry->created_at = $oTime->timestamp + 1;
|
114 |
+
/** @var Events\Insert $oQI */
|
115 |
+
$oQI = $oDbH->getQueryInserter();
|
116 |
+
$oQI->insert( $oEntry );
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
$nDayCount++;
|
121 |
+
$oTime->subDay();
|
122 |
+
} while ( $nDayCount < 13 );
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Consolidates each event in weekly sums. Doesn't process events from the previous 2 whole weeks.
|
127 |
+
* Processes event for the previous 8 weeks.
|
128 |
+
* @param $sEvent
|
129 |
+
*/
|
130 |
+
protected function consolidateEventIntoWeekly( $sEvent ) {
|
131 |
+
/** @var \ICWP_WPSF_FeatureHandler_Events $oMod */
|
132 |
+
$oMod = $this->getMod();
|
133 |
+
$oDbH = $oMod->getDbHandler_Events();
|
134 |
+
|
135 |
+
$oTime = Services::Request()
|
136 |
+
->carbon()
|
137 |
+
->subWeek( 2 )
|
138 |
+
->startOfWeek();
|
139 |
+
|
140 |
+
$nWeekCount = 0;
|
141 |
+
do {
|
142 |
+
/** @var Events\Select $oSel */
|
143 |
+
$oSel = $oDbH->getQuerySelector();
|
144 |
+
$nRecords = $oSel->filterByBoundary_Week( $oTime->timestamp )
|
145 |
+
->filterByEvent( $sEvent )
|
146 |
+
->count();
|
147 |
+
|
148 |
+
if ( $nRecords > 1 ) {
|
149 |
+
/** @var Events\Select $oSel */
|
150 |
+
$oSel = $oDbH->getQuerySelector();
|
151 |
+
/** @var Events\EntryVO[] $aRecords */
|
152 |
+
$nSum = $oSel->filterByBoundary_Week( $oTime->timestamp )
|
153 |
+
->sumEvent( $sEvent );
|
154 |
+
|
155 |
+
if ( $nSum > 0 ) {
|
156 |
+
/** @var Events\Delete $oDel */
|
157 |
+
$oDel = $oDbH->getQueryDeleter();
|
158 |
+
$oDel->filterByBoundary_Week( $oTime->timestamp )
|
159 |
+
->filterByEvent( $sEvent )
|
160 |
+
->query();
|
161 |
+
|
162 |
+
$oEntry = new Events\EntryVO();
|
163 |
+
$oEntry->event = $sEvent;
|
164 |
+
$oEntry->count = $nSum;
|
165 |
+
$oEntry->created_at = $oTime->timestamp + 1;
|
166 |
+
/** @var Events\Insert $oQI */
|
167 |
+
$oQI = $oDbH->getQueryInserter();
|
168 |
+
$oQI->insert( $oEntry );
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
+
$nWeekCount++;
|
173 |
+
$oTime->subWeek();
|
174 |
+
} while ( $nWeekCount < 8 );
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Consolidates each event in Daily sums. Doesn't process events from the previous 48hrs.
|
179 |
+
* Processes event for the 7 days previous to the last 48 hours.
|
180 |
+
* @param $sEvent
|
181 |
+
*/
|
182 |
+
protected function consolidateEventIntoMonthly( $sEvent ) {
|
183 |
+
/** @var \ICWP_WPSF_FeatureHandler_Events $oMod */
|
184 |
+
$oMod = $this->getMod();
|
185 |
+
$oDbH = $oMod->getDbHandler_Events();
|
186 |
+
|
187 |
+
$oTime = Services::Request()
|
188 |
+
->carbon()
|
189 |
+
->subMonth( 2 )
|
190 |
+
->startOfMonth();
|
191 |
+
|
192 |
+
$nMonthCount = 0;
|
193 |
+
do {
|
194 |
+
/** @var Events\Select $oSel */
|
195 |
+
$oSel = $oDbH->getQuerySelector();
|
196 |
+
$nRecords = $oSel->filterByBoundary_Month( $oTime->timestamp )
|
197 |
+
->filterByEvent( $sEvent )
|
198 |
+
->count();
|
199 |
+
|
200 |
+
if ( $nRecords > 1 ) {
|
201 |
+
/** @var Events\Select $oSel */
|
202 |
+
$oSel = $oDbH->getQuerySelector();
|
203 |
+
/** @var Events\EntryVO[] $aRecords */
|
204 |
+
$nSum = $oSel->filterByBoundary_Month( $oTime->timestamp )
|
205 |
+
->sumEvent( $sEvent );
|
206 |
+
|
207 |
+
if ( $nSum > 0 ) {
|
208 |
+
/** @var Events\Delete $oDel */
|
209 |
+
$oDel = $oDbH->getQueryDeleter();
|
210 |
+
$oDel->filterByBoundary_Month( $oTime->timestamp )
|
211 |
+
->filterByEvent( $sEvent )
|
212 |
+
->query();
|
213 |
+
|
214 |
+
$oEntry = new Events\EntryVO();
|
215 |
+
$oEntry->event = $sEvent;
|
216 |
+
$oEntry->count = $nSum;
|
217 |
+
$oEntry->created_at = $oTime->timestamp + 1;
|
218 |
+
/** @var Events\Insert $oQI */
|
219 |
+
$oQI = $oDbH->getQueryInserter();
|
220 |
+
$oQI->insert( $oEntry );
|
221 |
+
}
|
222 |
+
}
|
223 |
+
|
224 |
+
$nMonthCount++;
|
225 |
+
$oTime->subMonth();
|
226 |
+
} while ( $nMonthCount < 24 );
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* @param $sEvent
|
231 |
+
*/
|
232 |
+
protected function consolidateEventIntoYearly( $sEvent ) {
|
233 |
+
/** @var \ICWP_WPSF_FeatureHandler_Events $oMod */
|
234 |
+
$oMod = $this->getMod();
|
235 |
+
$oDbH = $oMod->getDbHandler_Events();
|
236 |
+
|
237 |
+
$oTime = Services::Request()
|
238 |
+
->carbon()
|
239 |
+
->subYear( 2 )
|
240 |
+
->startOfYear();
|
241 |
+
|
242 |
+
/** @var Events\Select $oSel */
|
243 |
+
$oSel = $oDbH->getQuerySelector();
|
244 |
+
$oOldest = $oSel->getOldestForEvent( $sEvent );
|
245 |
+
|
246 |
+
do {
|
247 |
+
/** @var Events\Select $oSel */
|
248 |
+
$oSel = $oDbH->getQuerySelector();
|
249 |
+
$nRecords = $oSel->filterByBoundary_Year( $oTime->timestamp )
|
250 |
+
->filterByEvent( $sEvent )
|
251 |
+
->count();
|
252 |
+
|
253 |
+
if ( $nRecords > 1 ) {
|
254 |
+
/** @var Events\Select $oSel */
|
255 |
+
$oSel = $oDbH->getQuerySelector();
|
256 |
+
/** @var Events\EntryVO[] $aRecords */
|
257 |
+
$nSum = $oSel->filterByBoundary_Year( $oTime->timestamp )
|
258 |
+
->sumEvent( $sEvent );
|
259 |
+
|
260 |
+
if ( $nSum > 0 ) {
|
261 |
+
/** @var Events\Delete $oDel */
|
262 |
+
$oDel = $oDbH->getQueryDeleter();
|
263 |
+
$oDel->filterByBoundary_Year( $oTime->timestamp )
|
264 |
+
->filterByEvent( $sEvent )
|
265 |
+
->query();
|
266 |
+
|
267 |
+
$oEntry = new Events\EntryVO();
|
268 |
+
$oEntry->event = $sEvent;
|
269 |
+
$oEntry->count = $nSum;
|
270 |
+
$oEntry->created_at = $oTime->timestamp + 1;
|
271 |
+
/** @var Events\Insert $oQI */
|
272 |
+
$oQI = $oDbH->getQueryInserter();
|
273 |
+
$oQI->insert( $oEntry );
|
274 |
+
}
|
275 |
+
}
|
276 |
+
|
277 |
+
$oTime->subYear();
|
278 |
+
} while ( $oTime->timestamp > $oOldest->created_at );
|
279 |
+
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* @return string[]
|
283 |
+
*/
|
284 |
+
protected function getAllEvents() {
|
285 |
+
/** @var \ICWP_WPSF_FeatureHandler_Events $oMod */
|
286 |
+
$oMod = $this->getMod();
|
287 |
+
/** @var Events\Select $oSel */
|
288 |
+
$oSel = $oMod->getDbHandler_Events()->getQuerySelector();
|
289 |
+
return $oSel->getAllEvents();
|
290 |
+
}
|
291 |
+
}
|
src/lib/src/Modules/HackGuard/Options.php
CHANGED
@@ -311,7 +311,7 @@ class Options extends Base\ShieldOptions {
|
|
311 |
public function getWcfFileExclusions() {
|
312 |
$sPattern = null;
|
313 |
|
314 |
-
$aExclusions = $this->
|
315 |
$aExclusions = is_array( $aExclusions ) ? $aExclusions : [];
|
316 |
// Flywheel specific mods
|
317 |
if ( defined( 'FLYWHEEL_PLUGIN_DIR' ) ) {
|
@@ -337,7 +337,7 @@ class Options extends Base\ShieldOptions {
|
|
337 |
*/
|
338 |
public function getWcfMissingExclusions() {
|
339 |
$sPattern = null;
|
340 |
-
$aExclusions = $this->
|
341 |
if ( is_array( $aExclusions ) && !empty( $aExclusions ) ) {
|
342 |
$aQuoted = array_map(
|
343 |
function ( $sExcl ) {
|
311 |
public function getWcfFileExclusions() {
|
312 |
$sPattern = null;
|
313 |
|
314 |
+
$aExclusions = $this->getOptions()->getDef( 'wcf_exclusions' );
|
315 |
$aExclusions = is_array( $aExclusions ) ? $aExclusions : [];
|
316 |
// Flywheel specific mods
|
317 |
if ( defined( 'FLYWHEEL_PLUGIN_DIR' ) ) {
|
337 |
*/
|
338 |
public function getWcfMissingExclusions() {
|
339 |
$sPattern = null;
|
340 |
+
$aExclusions = $this->getOptions()->getDef( 'wcf_exclusions_missing_only' );
|
341 |
if ( is_array( $aExclusions ) && !empty( $aExclusions ) ) {
|
342 |
$aQuoted = array_map(
|
343 |
function ( $sExcl ) {
|
src/lib/src/Modules/HackGuard/Strings.php
CHANGED
@@ -364,7 +364,7 @@ class Strings extends Base\Strings {
|
|
364 |
.'<br />'.__( "Disabling network intelligence turns off 'false positive confidence' levels.", 'wp-simple-firewall' )
|
365 |
.' '.__( 'You will no longer benefit from the intelligence gathered from the entire network.', 'wp-simple-firewall' )
|
366 |
.' '.__( 'All data shared is completely anonymous.', 'wp-simple-firewall' )
|
367 |
-
.' '.' [<a href="https://
|
368 |
.'<br />'.__( 'The more sites that share this information, the stronger and smarter the network becomes.', 'wp-simple-firewall' );
|
369 |
break;
|
370 |
|
364 |
.'<br />'.__( "Disabling network intelligence turns off 'false positive confidence' levels.", 'wp-simple-firewall' )
|
365 |
.' '.__( 'You will no longer benefit from the intelligence gathered from the entire network.', 'wp-simple-firewall' )
|
366 |
.' '.__( 'All data shared is completely anonymous.', 'wp-simple-firewall' )
|
367 |
+
.' '.' [<a href="https://shsec.io/moreinfomalnetwork">'.__( 'More Info', 'wp-simple-firewall' ).'</a>]'
|
368 |
.'<br />'.__( 'The more sites that share this information, the stronger and smarter the network becomes.', 'wp-simple-firewall' );
|
369 |
break;
|
370 |
|
src/lib/src/Modules/IPs/AjaxHandler.php
CHANGED
@@ -53,7 +53,9 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
53 |
$sIp = preg_replace( '#[^/:.a-f\d]#i', '', ( isset( $aFormParams[ 'ip' ] ) ? $aFormParams[ 'ip' ] : '' ) );
|
54 |
$sList = isset( $aFormParams[ 'list' ] ) ? $aFormParams[ 'list' ] : '';
|
55 |
|
56 |
-
$bAcceptableIp = $oIpServ->isValidIp( $sIp )
|
|
|
|
|
57 |
|
58 |
$bIsBlackList = $sList != $oMod::LIST_MANUAL_WHITE;
|
59 |
|
53 |
$sIp = preg_replace( '#[^/:.a-f\d]#i', '', ( isset( $aFormParams[ 'ip' ] ) ? $aFormParams[ 'ip' ] : '' ) );
|
54 |
$sList = isset( $aFormParams[ 'list' ] ) ? $aFormParams[ 'list' ] : '';
|
55 |
|
56 |
+
$bAcceptableIp = $oIpServ->isValidIp( $sIp )
|
57 |
+
|| $oIpServ->isValidIp4Range( $sIp )
|
58 |
+
|| $oIpServ->isValidIp6Range( $sIp );
|
59 |
|
60 |
$bIsBlackList = $sList != $oMod::LIST_MANUAL_WHITE;
|
61 |
|
src/lib/src/Modules/IPs/Components/LookupIpOnList.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Databases\IPs;
|
7 |
+
use FernleafSystems\Wordpress\Services\Services;
|
8 |
+
|
9 |
+
class LookupIpOnList {
|
10 |
+
|
11 |
+
use ModConsumer;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
private $sIp;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
private $sList;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @param bool $bIncludeRanges
|
25 |
+
* @return IPs\EntryVO|null
|
26 |
+
*/
|
27 |
+
public function lookup( $bIncludeRanges = true ) {
|
28 |
+
$oIp = $this->lookupIp();
|
29 |
+
if ( $bIncludeRanges && !$oIp instanceof IPs\EntryVO ) {
|
30 |
+
foreach ( $this->lookupRange() as $oMaybeIp ) {
|
31 |
+
try {
|
32 |
+
if ( Services::IP()->checkIp( $this->getIp(), $oMaybeIp->ip ) ) {
|
33 |
+
$oIp = $oMaybeIp;
|
34 |
+
break;
|
35 |
+
}
|
36 |
+
}
|
37 |
+
catch ( \Exception $oE ) {
|
38 |
+
}
|
39 |
+
}
|
40 |
+
}
|
41 |
+
return $oIp;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @return IPs\EntryVO|null
|
46 |
+
*/
|
47 |
+
public function lookupIp() {
|
48 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
49 |
+
$oMod = $this->getMod();
|
50 |
+
/** @var IPs\Select $oSelect */
|
51 |
+
$oSelect = $oMod->getDbHandler_IPs()->getQuerySelector();
|
52 |
+
|
53 |
+
return $oSelect->filterByIsRange( false )
|
54 |
+
->filterByIp( $this->getIp() )
|
55 |
+
->filterByList( $this->getList() )
|
56 |
+
->first();
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @return IPs\EntryVO[]
|
61 |
+
*/
|
62 |
+
public function lookupRange() {
|
63 |
+
/** @var \ICWP_WPSF_FeatureHandler_Ips $oMod */
|
64 |
+
$oMod = $this->getMod();
|
65 |
+
/** @var IPs\Select $oSelect */
|
66 |
+
$oSelect = $oMod->getDbHandler_IPs()->getQuerySelector();
|
67 |
+
|
68 |
+
$aIps = $oSelect->filterByIsRange( true )
|
69 |
+
->filterByList( $this->getList() )
|
70 |
+
->query();
|
71 |
+
return is_array( $aIps ) ? $aIps : [];
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @return string
|
76 |
+
*/
|
77 |
+
public function getIp() {
|
78 |
+
return $this->sIp;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @return string
|
83 |
+
*/
|
84 |
+
public function getList() {
|
85 |
+
return $this->sList;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @param string $sIp
|
90 |
+
* @return $this
|
91 |
+
*/
|
92 |
+
public function setIp( $sIp ) {
|
93 |
+
$this->sIp = $sIp;
|
94 |
+
return $this;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* @param string $sList
|
99 |
+
* @return $this
|
100 |
+
*/
|
101 |
+
public function setList( $sList ) {
|
102 |
+
$this->sList = $sList;
|
103 |
+
return $this;
|
104 |
+
}
|
105 |
+
}
|
src/lib/src/Modules/IPs/Options.php
CHANGED
@@ -137,7 +137,6 @@ class Options extends Base\ShieldOptions {
|
|
137 |
* @return bool
|
138 |
*/
|
139 |
protected function isSelectOptionEnabled( $sOptionKey ) {
|
140 |
-
|
141 |
-
return ( !$bOptPrem || $this->getCon()->isPremiumActive() ) && !$this->isOpt( $sOptionKey, 'disabled' );
|
142 |
}
|
143 |
}
|
137 |
* @return bool
|
138 |
*/
|
139 |
protected function isSelectOptionEnabled( $sOptionKey ) {
|
140 |
+
return !$this->isOpt( $sOptionKey, 'disabled' );
|
|
|
141 |
}
|
142 |
}
|
src/lib/src/Modules/Plugin/AdminNotices.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
|
|
6 |
use FernleafSystems\Wordpress\Services\Services;
|
7 |
|
8 |
class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
@@ -19,6 +20,10 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
19 |
$this->buildNotice_OverrideForceoff( $oNotice );
|
20 |
break;
|
21 |
|
|
|
|
|
|
|
|
|
22 |
case 'plugin-mailing-list-signup':
|
23 |
$this->buildNotice_PluginMailingListSignup( $oNotice );
|
24 |
break;
|
@@ -99,6 +104,31 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
99 |
];
|
100 |
}
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
/**
|
103 |
* @param Shield\Utilities\AdminNotices\NoticeVO $oNotice
|
104 |
*/
|
@@ -204,7 +234,7 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
204 |
'hrefs' => [
|
205 |
'learn_more' => 'https://translate.fernleafsystems.com',
|
206 |
'link_to_see' => $oMod->getLinkToTrackingDataDump(),
|
207 |
-
'link_to_moreinfo' => 'https://
|
208 |
|
209 |
]
|
210 |
];
|
@@ -240,6 +270,10 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
|
240 |
$bNeeded = $this->getCon()->getIfForceOffActive();
|
241 |
break;
|
242 |
|
|
|
|
|
|
|
|
|
243 |
case 'plugin-update-available':
|
244 |
$bNeeded = !Services::WpPost()->isPage_Updates()
|
245 |
&& Services::WpPlugins()->isUpdateAvailable( !Services::WpPost()->isPage_Updates() );
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
4 |
|
5 |
use FernleafSystems\Wordpress\Plugin\Shield;
|
6 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
|
7 |
use FernleafSystems\Wordpress\Services\Services;
|
8 |
|
9 |
class AdminNotices extends Shield\Modules\Base\AdminNotices {
|
20 |
$this->buildNotice_OverrideForceoff( $oNotice );
|
21 |
break;
|
22 |
|
23 |
+
case 'compat-sgoptimize':
|
24 |
+
$this->buildNotice_CompatSgOptimize( $oNotice );
|
25 |
+
break;
|
26 |
+
|
27 |
case 'plugin-mailing-list-signup':
|
28 |
$this->buildNotice_PluginMailingListSignup( $oNotice );
|
29 |
break;
|
104 |
];
|
105 |
}
|
106 |
|
107 |
+
/**
|
108 |
+
* @param Shield\Utilities\AdminNotices\NoticeVO $oNotice
|
109 |
+
*/
|
110 |
+
private function buildNotice_CompatSgOptimize( $oNotice ) {
|
111 |
+
$sName = $this->getCon()->getHumanName();
|
112 |
+
|
113 |
+
$oNotice->render_data = [
|
114 |
+
'notice_attributes' => [],
|
115 |
+
'strings' => [
|
116 |
+
'title' => sprintf( '%s: %s', __( 'Warning', 'wp-simple-firewall' ),
|
117 |
+
sprintf( __( 'Site Ground Optimizer plugin has a conflict', 'wp-simple-firewall' ), $sName ) ),
|
118 |
+
'message' => sprintf(
|
119 |
+
__( 'The SG Optimizer plugin has 2 settings which are breaking your site and certain %s features.', 'wp-simple-firewall' ),
|
120 |
+
$sName
|
121 |
+
)
|
122 |
+
.' '.sprintf( 'The problematic options are: "Defer Render-blocking JS" and "Remove Query Strings From Static Resources".' ),
|
123 |
+
'learn_more' => sprintf( 'Click here to learn more' ),
|
124 |
+
'sgoptimizer_turnoff' => __( 'Click here to automatically turn off those options.', 'wp-simple-firewall' )
|
125 |
+
],
|
126 |
+
'ajax' => [
|
127 |
+
'sgoptimizer_turnoff' => $this->getMod()->getAjaxActionData( 'sgoptimizer_turnoff', true )
|
128 |
+
]
|
129 |
+
];
|
130 |
+
}
|
131 |
+
|
132 |
/**
|
133 |
* @param Shield\Utilities\AdminNotices\NoticeVO $oNotice
|
134 |
*/
|
234 |
'hrefs' => [
|
235 |
'learn_more' => 'https://translate.fernleafsystems.com',
|
236 |
'link_to_see' => $oMod->getLinkToTrackingDataDump(),
|
237 |
+
'link_to_moreinfo' => 'https://shsec.io/shieldtrackinginfo',
|
238 |
|
239 |
]
|
240 |
];
|
270 |
$bNeeded = $this->getCon()->getIfForceOffActive();
|
271 |
break;
|
272 |
|
273 |
+
case 'compat-sgoptimize':
|
274 |
+
$bNeeded = ( new Plugin\Components\SiteGroundPluginCompatibility() )->testIsIncompatible();
|
275 |
+
break;
|
276 |
+
|
277 |
case 'plugin-update-available':
|
278 |
$bNeeded = !Services::WpPost()->isPage_Updates()
|
279 |
&& Services::WpPlugins()->isUpdateAvailable( !Services::WpPost()->isPage_Updates() );
|
src/lib/src/Modules/Plugin/AjaxHandler.php
CHANGED
@@ -54,6 +54,10 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
54 |
$aResponse = $this->ajaxExec_SendDeactivateSurvey();
|
55 |
break;
|
56 |
|
|
|
|
|
|
|
|
|
57 |
default:
|
58 |
$aResponse = parent::processAjaxAction( $sAction );
|
59 |
}
|
@@ -125,7 +129,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
125 |
$bSuccess = false;
|
126 |
$sMessage = __( 'No items selected.', 'wp-simple-firewall' );
|
127 |
}
|
128 |
-
|
129 |
$sMessage = __( 'Not a supported action.', 'wp-simple-firewall' );
|
130 |
}
|
131 |
else {
|
@@ -253,7 +257,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
253 |
/**
|
254 |
* @return array
|
255 |
*/
|
256 |
-
|
257 |
/** @var \ICWP_WPSF_FeatureHandler_Plugin $oMod */
|
258 |
$oMod = $this->getMod();
|
259 |
$bSuccess = false;
|
@@ -263,7 +267,7 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
263 |
if ( !$oMod->getCanAdminNotes() ) {
|
264 |
$sMessage = __( 'Sorry, Admin Notes is only available for Pro subscriptions.', 'wp-simple-firewall' );
|
265 |
}
|
266 |
-
|
267 |
$sMessage = __( 'Sorry, but it appears your note was empty.', 'wp-simple-firewall' );
|
268 |
}
|
269 |
else {
|
@@ -277,4 +281,17 @@ class AjaxHandler extends Shield\Modules\Base\AjaxHandlerShield {
|
|
277 |
'message' => $sMessage
|
278 |
];
|
279 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
280 |
}
|
54 |
$aResponse = $this->ajaxExec_SendDeactivateSurvey();
|
55 |
break;
|
56 |
|
57 |
+
case 'sgoptimizer_turnoff':
|
58 |
+
$aResponse = $this->ajaxExec_TurnOffSiteGroundOptions();
|
59 |
+
break;
|
60 |
+
|
61 |
default:
|
62 |
$aResponse = parent::processAjaxAction( $sAction );
|
63 |
}
|
129 |
$bSuccess = false;
|
130 |
$sMessage = __( 'No items selected.', 'wp-simple-firewall' );
|
131 |
}
|
132 |
+
elseif ( !in_array( $oReq->post( 'bulk_action' ), [ 'delete' ] ) ) {
|
133 |
$sMessage = __( 'Not a supported action.', 'wp-simple-firewall' );
|
134 |
}
|
135 |
else {
|
257 |
/**
|
258 |
* @return array
|
259 |
*/
|
260 |
+
private function ajaxExec_AdminNotesInsert() {
|
261 |
/** @var \ICWP_WPSF_FeatureHandler_Plugin $oMod */
|
262 |
$oMod = $this->getMod();
|
263 |
$bSuccess = false;
|
267 |
if ( !$oMod->getCanAdminNotes() ) {
|
268 |
$sMessage = __( 'Sorry, Admin Notes is only available for Pro subscriptions.', 'wp-simple-firewall' );
|
269 |
}
|
270 |
+
elseif ( empty( $sNote ) ) {
|
271 |
$sMessage = __( 'Sorry, but it appears your note was empty.', 'wp-simple-firewall' );
|
272 |
}
|
273 |
else {
|
281 |
'message' => $sMessage
|
282 |
];
|
283 |
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* @return array
|
287 |
+
*/
|
288 |
+
private function ajaxExec_TurnOffSiteGroundOptions() {
|
289 |
+
$bSuccess = ( new Shield\Modules\Plugin\Components\SiteGroundPluginCompatibility() )
|
290 |
+
->switchOffOptions();
|
291 |
+
return [
|
292 |
+
'success' => $bSuccess,
|
293 |
+
'message' => $bSuccess ? __( 'Switching-off conflicting options appears to have been successful.', 'wp-simple-firewall' )
|
294 |
+
: __( 'Switching-off conflicting options appears to have failed.', 'wp-simple-firewall' )
|
295 |
+
];
|
296 |
+
}
|
297 |
}
|
src/lib/src/Modules/Plugin/Components/BadgeWidget.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Components;
|
4 |
|
5 |
-
class BadgeWidget extends \
|
6 |
|
7 |
use \FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
|
@@ -29,6 +29,20 @@ class BadgeWidget extends \ICWP_WPSF_WpWidget {
|
|
29 |
add_shortcode( 'SHIELD_BADGE', [ $this, 'renderBadge' ] );
|
30 |
}
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
/**
|
33 |
* @param array $aNewInstance
|
34 |
* @param array $aOldInstance
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Components;
|
4 |
|
5 |
+
class BadgeWidget extends \WP_Widget {
|
6 |
|
7 |
use \FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
|
8 |
|
29 |
add_shortcode( 'SHIELD_BADGE', [ $this, 'renderBadge' ] );
|
30 |
}
|
31 |
|
32 |
+
/**
|
33 |
+
* @param array $aWidgetArguments
|
34 |
+
* @param string $sTitle
|
35 |
+
* @param string $sContent
|
36 |
+
* @return string
|
37 |
+
*/
|
38 |
+
protected function standardRender( $aWidgetArguments, $sTitle = '', $sContent = '' ) {
|
39 |
+
echo $aWidgetArguments[ 'before_widget' ];
|
40 |
+
if ( !empty( $sTitle ) ) {
|
41 |
+
echo $aWidgetArguments[ 'before_title' ].$sTitle.$aWidgetArguments[ 'after_title' ];
|
42 |
+
}
|
43 |
+
return $sContent.$aWidgetArguments[ 'after_widget' ];
|
44 |
+
}
|
45 |
+
|
46 |
/**
|
47 |
* @param array $aNewInstance
|
48 |
* @param array $aOldInstance
|
src/lib/src/Modules/Plugin/Components/PluginBadge.php
CHANGED
@@ -68,7 +68,7 @@ class PluginBadge {
|
|
68 |
'is_floating' => $bFloating
|
69 |
],
|
70 |
'hrefs' => [
|
71 |
-
'badge' => 'https://
|
72 |
'logo' => $oCon->getPluginUrl_Image( 'shield/shield-security-logo-colour-32px.png' ),
|
73 |
],
|
74 |
'strings' => [
|
68 |
'is_floating' => $bFloating
|
69 |
],
|
70 |
'hrefs' => [
|
71 |
+
'badge' => 'https://shsec.io/wpsecurityfirewall',
|
72 |
'logo' => $oCon->getPluginUrl_Image( 'shield/shield-security-logo-colour-32px.png' ),
|
73 |
],
|
74 |
'strings' => [
|
src/lib/src/Modules/Plugin/Components/SiteGroundPluginCompatibility.php
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Components;
|
4 |
+
|
5 |
+
class SiteGroundPluginCompatibility {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @return bool
|
9 |
+
*/
|
10 |
+
public function testIsIncompatible() {
|
11 |
+
$bIncompatExist = false;
|
12 |
+
if ( $this->isSGOptimizerPluginAsExpected() ) {
|
13 |
+
try {
|
14 |
+
foreach ( $this->getIncompatOptions() as $sOption ) {
|
15 |
+
if ( \SiteGround_Optimizer\Options\Options::is_enabled( $sOption ) ) {
|
16 |
+
$bIncompatExist = true;
|
17 |
+
break;
|
18 |
+
}
|
19 |
+
}
|
20 |
+
}
|
21 |
+
catch ( \Exception $oE ) {
|
22 |
+
}
|
23 |
+
}
|
24 |
+
return $bIncompatExist;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @return bool
|
29 |
+
*/
|
30 |
+
public function isSGOptimizerPluginAsExpected() {
|
31 |
+
$bExpected = false;
|
32 |
+
try {
|
33 |
+
$oRefl = new \ReflectionClass( '\SiteGround_Optimizer\Options\Options' );
|
34 |
+
$bExpected = $oRefl->getMethod( 'is_enabled' )->isStatic()
|
35 |
+
&& $oRefl->getMethod( 'disable_option' )->isStatic();
|
36 |
+
}
|
37 |
+
catch ( \Exception $oE ) {
|
38 |
+
}
|
39 |
+
return $bExpected;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return bool
|
44 |
+
*/
|
45 |
+
public function switchOffOptions() {
|
46 |
+
$bSuccess = false;
|
47 |
+
if ( $this->isSGOptimizerPluginAsExpected() ) {
|
48 |
+
try {
|
49 |
+
foreach ( $this->getIncompatOptions() as $sOption ) {
|
50 |
+
\SiteGround_Optimizer\Options\Options::disable_option( $sOption );
|
51 |
+
}
|
52 |
+
$bSuccess = !$this->testIsIncompatible();
|
53 |
+
}
|
54 |
+
catch ( \Exception $oE ) {
|
55 |
+
}
|
56 |
+
}
|
57 |
+
return $bSuccess;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @return string[]
|
62 |
+
*/
|
63 |
+
private function getIncompatOptions() {
|
64 |
+
return [
|
65 |
+
'siteground_optimizer_remove_query_strings',
|
66 |
+
'siteground_optimizer_optimize_javascript_async',
|
67 |
+
];
|
68 |
+
}
|
69 |
+
}
|
src/lib/src/Modules/Plugin/Strings.php
CHANGED
@@ -179,7 +179,7 @@ class Strings extends Base\Strings {
|
|
179 |
$sSummary = __( 'Display Plugin Badge On Your Site', 'wp-simple-firewall' );
|
180 |
$sDescription = __( 'Enabling this option helps support the plugin by spreading the word about it on your website.', 'wp-simple-firewall' )
|
181 |
.' '.__( 'The plugin badge also lets visitors know your are taking your website security seriously.', 'wp-simple-firewall' )
|
182 |
-
.sprintf( '<br /><strong><a href="%s" target="_blank">%s</a></strong>', 'https://
|
183 |
break;
|
184 |
|
185 |
case 'delete_on_deactivate' :
|
179 |
$sSummary = __( 'Display Plugin Badge On Your Site', 'wp-simple-firewall' );
|
180 |
$sDescription = __( 'Enabling this option helps support the plugin by spreading the word about it on your website.', 'wp-simple-firewall' )
|
181 |
.' '.__( 'The plugin badge also lets visitors know your are taking your website security seriously.', 'wp-simple-firewall' )
|
182 |
+
.sprintf( '<br /><strong><a href="%s" target="_blank">%s</a></strong>', 'https://shsec.io/wpsf20', __( 'Read this carefully before enabling this option.', 'wp-simple-firewall' ) );
|
183 |
break;
|
184 |
|
185 |
case 'delete_on_deactivate' :
|
src/lib/src/Modules/PluginControllerConsumer.php
CHANGED
@@ -9,13 +9,19 @@ trait PluginControllerConsumer {
|
|
9 |
/**
|
10 |
* @var Controller
|
11 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
static private $oPluginController;
|
13 |
|
14 |
/**
|
15 |
* @return Controller
|
16 |
*/
|
17 |
public function getCon() {
|
18 |
-
return self::$oPluginController;
|
19 |
}
|
20 |
|
21 |
/**
|
@@ -23,7 +29,7 @@ trait PluginControllerConsumer {
|
|
23 |
* @return $this
|
24 |
*/
|
25 |
public function setCon( $oCon ) {
|
26 |
-
|
27 |
return $this;
|
28 |
}
|
29 |
}
|
9 |
/**
|
10 |
* @var Controller
|
11 |
*/
|
12 |
+
private $oPlugCon;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var Controller
|
16 |
+
* @deprecated 8.4
|
17 |
+
*/
|
18 |
static private $oPluginController;
|
19 |
|
20 |
/**
|
21 |
* @return Controller
|
22 |
*/
|
23 |
public function getCon() {
|
24 |
+
return isset( $this->oPlugCon ) ? $this->oPlugCon : self::$oPluginController;
|
25 |
}
|
26 |
|
27 |
/**
|
29 |
* @return $this
|
30 |
*/
|
31 |
public function setCon( $oCon ) {
|
32 |
+
$this->oPlugCon = $oCon;
|
33 |
return $this;
|
34 |
}
|
35 |
}
|
src/lib/src/Modules/SecurityAdmin/Options.php
CHANGED
@@ -61,7 +61,7 @@ class Options extends Base\ShieldOptions {
|
|
61 |
/**
|
62 |
* @return array
|
63 |
*/
|
64 |
-
|
65 |
$aOptions = $this->getDef( 'options_to_restrict' );
|
66 |
return is_array( $aOptions ) ? $aOptions : [];
|
67 |
}
|
61 |
/**
|
62 |
* @return array
|
63 |
*/
|
64 |
+
private function getRestrictedOptions() {
|
65 |
$aOptions = $this->getDef( 'options_to_restrict' );
|
66 |
return is_array( $aOptions ) ? $aOptions : [];
|
67 |
}
|
src/lib/src/Scans/Mal/FileScanner.php
CHANGED
@@ -75,22 +75,41 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
75 |
else {
|
76 |
$oAction = $this->getScanActionVO();
|
77 |
|
78 |
-
// Remove lines that exceed our false positive confidence
|
79 |
if ( $oAction->confidence_threshold > 0 ) {
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
}
|
85 |
}
|
86 |
}
|
|
|
|
|
|
|
87 |
|
88 |
-
if (
|
89 |
-
$
|
90 |
-
if ( $oAction->confidence_threshold == 0 || $nFalsePositiveConfidence < $oAction->confidence_threshold ) {
|
91 |
-
$oResultItem = $this->getResultItemFromLines( array_keys( $aLines ), $sFullPath, $sSig );
|
92 |
-
$oResultItem->fp_confidence = $nFalsePositiveConfidence;
|
93 |
-
}
|
94 |
}
|
95 |
}
|
96 |
}
|
@@ -123,52 +142,6 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
|
|
123 |
|| $this->isPluginFileValid( $sFullPath ) || $this->isThemeFileValid( $sFullPath );
|
124 |
}
|
125 |
|
126 |
-
/**
|
127 |
-
* @param string $sFullPath
|
128 |
-
* @param string $sLine
|
129 |
-
* @return int
|
130 |
-
*/
|
131 |
-
private function getFalsePositiveConfidenceForLine( $sFullPath, $sLine ) {
|
132 |
-
/** @var ScanActionVO $oScanVO */
|
133 |
-
$oScanVO = $this->getScanActionVO();
|
134 |
-
|
135 |
-
$nConfidence = 0;
|
136 |
-
$sFilePart = basename( $sFullPath );
|
137 |
-
if ( $oScanVO->confidence_threshold > 0 && isset( $oScanVO->fp_signatures[ $sFilePart ] ) ) {
|
138 |
-
$sHashLine = sha1( trim( $sLine ) );
|
139 |
-
if ( isset( $oScanVO->fp_signatures[ $sFilePart ][ $sHashLine ] ) ) {
|
140 |
-
$nConfidence = $oScanVO->fp_signatures[ $sFilePart ][ $sHashLine ];
|
141 |
-
}
|
142 |
-
}
|
143 |
-
return (int)$nConfidence;
|
144 |
-
}
|
145 |
-
|
146 |
-
/**
|
147 |
-
* @param string $sFilePath
|
148 |
-
* @return int
|
149 |
-
*/
|
150 |
-
private function getFalsePositiveConfidenceForFile( $sFilePath ) {
|
151 |
-
/** @var ScanActionVO $oScanVO */
|
152 |
-
$oScanVO = $this->getScanActionVO();
|
153 |
-
|
154 |
-
$nConfidence = 0;
|
155 |
-
$sFilePart = basename( $sFilePath );
|
156 |
-
if ( $oScanVO->confidence_threshold > 0 && isset( $oScanVO->whitelist[ $sFilePart ] ) ) {
|
157 |
-
try {
|
158 |
-
$oHasher = new Utilities\File\Compare\CompareHash();
|
159 |
-
foreach ( $oScanVO->whitelist[ $sFilePart ] as $sWlHash => $nHashConfidence ) {
|
160 |
-
if ( $oHasher->isEqualFileSha1( $sFilePath, $sWlHash ) ) {
|
161 |
-
$nConfidence = $nHashConfidence;
|
162 |
-
break;
|
163 |
-
}
|
164 |
-
}
|
165 |
-
}
|
166 |
-
catch ( \InvalidArgumentException $oE ) {
|
167 |
-
}
|
168 |
-
}
|
169 |
-
return (int)$nConfidence;
|
170 |
-
}
|
171 |
-
|
172 |
/**
|
173 |
* @param string $sFullPath - normalized
|
174 |
* @return bool
|
75 |
else {
|
76 |
$oAction = $this->getScanActionVO();
|
77 |
|
|
|
78 |
if ( $oAction->confidence_threshold > 0 ) {
|
79 |
+
$bReportItem = false;
|
80 |
+
// 1. First check whether the FP of the whole file means we can filter it
|
81 |
+
$nFalsePositiveConfidence = ( new Shield\Scans\Mal\Utilities\FalsePositiveQuery() )
|
82 |
+
->setMod( $this->getMod() )
|
83 |
+
->queryPath( $sFullPath );
|
84 |
+
if ( $nFalsePositiveConfidence < $oAction->confidence_threshold ) {
|
85 |
+
// 2. Check each line and filter out fp confident lines
|
86 |
+
$aLineScores = ( new Shield\Scans\Mal\Utilities\FalsePositiveQuery() )
|
87 |
+
->setMod( $this->getMod() )
|
88 |
+
->queryFileLines( $sFullPath, array_keys( $aLines ) );
|
89 |
+
$aLines = array_filter(
|
90 |
+
$aLineScores,
|
91 |
+
function ( $nScore ) use ( $oAction ) {
|
92 |
+
return $nScore < $oAction->confidence_threshold;
|
93 |
+
}
|
94 |
+
);
|
95 |
+
|
96 |
+
if ( empty( $aLines ) ) {
|
97 |
+
// Now send False Positive report for entire file based on all file lines being FPs.
|
98 |
+
( new Shield\Scans\Mal\Utilities\FalsePositiveReporter() )
|
99 |
+
->setMod( $this->getMod() )
|
100 |
+
->reportPath( $sFullPath, true );
|
101 |
+
}
|
102 |
+
else {
|
103 |
+
$bReportItem = true;
|
104 |
}
|
105 |
}
|
106 |
}
|
107 |
+
else {
|
108 |
+
$bReportItem = true;
|
109 |
+
}
|
110 |
|
111 |
+
if ( $bReportItem ) {
|
112 |
+
$oResultItem = $this->getResultItemFromLines( array_keys( $aLines ), $sFullPath, $sSig );
|
|
|
|
|
|
|
|
|
113 |
}
|
114 |
}
|
115 |
}
|
142 |
|| $this->isPluginFileValid( $sFullPath ) || $this->isThemeFileValid( $sFullPath );
|
143 |
}
|
144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
/**
|
146 |
* @param string $sFullPath - normalized
|
147 |
* @return bool
|
src/lib/src/Scans/Mal/Scan.php
CHANGED
@@ -24,18 +24,6 @@ class Scan extends Shield\Scans\Base\Files\BaseFileMapScan {
|
|
24 |
$oScanVO = $this->getScanActionVO();
|
25 |
|
26 |
$oScanVO->confidence_threshold = $oOpts->getMalConfidenceBoundary();
|
27 |
-
if ( $oOpts->isMalUseNetworkIntelligence() ) {
|
28 |
-
$oScanVO->whitelist = ( new Utilities\Whitelist() )
|
29 |
-
->setMod( $this->getMod() )
|
30 |
-
->retrieve();
|
31 |
-
$oScanVO->fp_signatures = ( new Utilities\Signatures() )
|
32 |
-
->setMod( $this->getMod() )
|
33 |
-
->retrieve();
|
34 |
-
}
|
35 |
-
else {
|
36 |
-
$oScanVO->whitelist = [];
|
37 |
-
$oScanVO->fp_signatures = [];
|
38 |
-
}
|
39 |
|
40 |
$aPatterns = ( new Utilities\Patterns() )
|
41 |
->setMod( $this->getMod() )
|
24 |
$oScanVO = $this->getScanActionVO();
|
25 |
|
26 |
$oScanVO->confidence_threshold = $oOpts->getMalConfidenceBoundary();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
|
28 |
$aPatterns = ( new Utilities\Patterns() )
|
29 |
->setMod( $this->getMod() )
|
src/lib/src/Scans/Mal/ScanActionVO.php
CHANGED
@@ -12,8 +12,6 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\BaseScanActionVO;
|
|
12 |
* @property string[] $paths_whitelisted
|
13 |
* @property string[] $patterns_regex
|
14 |
* @property string[] $patterns_simple
|
15 |
-
* @property string[][] $whitelist
|
16 |
-
* @property int[] $fp_signatures
|
17 |
* @property int $confidence_threshold
|
18 |
*/
|
19 |
class ScanActionVO extends BaseScanActionVO {
|
12 |
* @property string[] $paths_whitelisted
|
13 |
* @property string[] $patterns_regex
|
14 |
* @property string[] $patterns_simple
|
|
|
|
|
15 |
* @property int $confidence_threshold
|
16 |
*/
|
17 |
class ScanActionVO extends BaseScanActionVO {
|
src/lib/src/Scans/Mal/Utilities/FalsePositiveQuery.php
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal\Utilities;
|
4 |
+
|
5 |
+
use FernleafSystems\Wordpress\Plugin\Shield\Modules;
|
6 |
+
use FernleafSystems\Wordpress\Services\Utilities\File\ExtractLinesFromFile;
|
7 |
+
use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Malware;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class FalsePositiveQuery
|
11 |
+
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal\Utilities
|
12 |
+
*/
|
13 |
+
class FalsePositiveQuery {
|
14 |
+
|
15 |
+
use Modules\ModConsumer;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @param string $sFullPath
|
19 |
+
* @param int[] $aLines
|
20 |
+
* @return int[] - key is the file line number, value is the false positive confidence score
|
21 |
+
*/
|
22 |
+
public function queryFileLines( $sFullPath, $aLines ) {
|
23 |
+
$aScores = [];
|
24 |
+
/** @var Modules\HackGuard\Options $oOpts */
|
25 |
+
$oOpts = $this->getOptions();
|
26 |
+
if ( $oOpts->isMalUseNetworkIntelligence() ) {
|
27 |
+
try {
|
28 |
+
$aFile = ( new ExtractLinesFromFile() )->run( $sFullPath, $aLines );
|
29 |
+
foreach ( $aFile as $nLineNum => $sLine ) {
|
30 |
+
$aScores[ $nLineNum ] = $this->queryLine( $sFullPath, $sLine );
|
31 |
+
}
|
32 |
+
}
|
33 |
+
catch ( \Exception $oE ) {
|
34 |
+
}
|
35 |
+
}
|
36 |
+
return $aScores;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @param string $sFullPath
|
41 |
+
* @return int
|
42 |
+
*/
|
43 |
+
public function queryPath( $sFullPath ) {
|
44 |
+
$nFpConfidence = 0;
|
45 |
+
|
46 |
+
/** @var Modules\HackGuard\Options $oOpts */
|
47 |
+
$oOpts = $this->getOptions();
|
48 |
+
if ( $oOpts->isMalUseNetworkIntelligence() ) {
|
49 |
+
|
50 |
+
$aData = ( new Malware\Confidence\Retrieve() )->retrieveForFile( $sFullPath );
|
51 |
+
if ( isset( $aData[ 'score' ] ) ) {
|
52 |
+
$nFpConfidence = (int)$aData[ 'score' ];
|
53 |
+
}
|
54 |
+
}
|
55 |
+
return $nFpConfidence;
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @param string $sFile - path to file containing line
|
60 |
+
* @param string $sLine
|
61 |
+
* @return int
|
62 |
+
*/
|
63 |
+
public function queryLine( $sFile, $sLine ) {
|
64 |
+
$nFpConfidence = 0;
|
65 |
+
|
66 |
+
/** @var Modules\HackGuard\Options $oOpts */
|
67 |
+
$oOpts = $this->getOptions();
|
68 |
+
if ( $oOpts->isMalUseNetworkIntelligence() ) {
|
69 |
+
|
70 |
+
try {
|
71 |
+
$aData = ( new Malware\Confidence\Retrieve() )->retrieveForFileLine( $sFile, $sLine );
|
72 |
+
if ( isset( $aData[ 'score' ] ) ) {
|
73 |
+
$nFpConfidence = (int)$aData[ 'score' ];
|
74 |
+
}
|
75 |
+
}
|
76 |
+
catch ( \Exception $oE ) {
|
77 |
+
}
|
78 |
+
}
|
79 |
+
return $nFpConfidence;
|
80 |
+
}
|
81 |
+
}
|
src/lib/src/Scans/Mal/Utilities/Signatures.php
CHANGED
@@ -9,6 +9,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Malware;
|
|
9 |
/**
|
10 |
* Class Signatures
|
11 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal\Utilities
|
|
|
12 |
*/
|
13 |
class Signatures {
|
14 |
|
9 |
/**
|
10 |
* Class Signatures
|
11 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal\Utilities
|
12 |
+
* @deprecated 8.4
|
13 |
*/
|
14 |
class Signatures {
|
15 |
|
src/lib/src/Scans/Mal/Utilities/Whitelist.php
CHANGED
@@ -9,6 +9,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Malware;
|
|
9 |
/**
|
10 |
* Class Whitelist
|
11 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal\Utilities
|
|
|
12 |
*/
|
13 |
class Whitelist {
|
14 |
|
9 |
/**
|
10 |
* Class Whitelist
|
11 |
* @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal\Utilities
|
12 |
+
* @deprecated 8.4
|
13 |
*/
|
14 |
class Whitelist {
|
15 |
|
src/lib/src/Scans/Ptg/Scan.php
CHANGED
@@ -50,7 +50,6 @@ class Scan extends Shield\Scans\Base\BaseScan {
|
|
50 |
|
51 |
// use live hashes if it's a WP.org plugin/theme
|
52 |
if ( $bUseLiveHashes ) {
|
53 |
-
|
54 |
try {
|
55 |
$oNewRes = ( new WporgAssetScanner() )
|
56 |
->setScanActionVO( $oAction )
|
50 |
|
51 |
// use live hashes if it's a WP.org plugin/theme
|
52 |
if ( $bUseLiveHashes ) {
|
|
|
53 |
try {
|
54 |
$oNewRes = ( new WporgAssetScanner() )
|
55 |
->setScanActionVO( $oAction )
|
src/lib/src/Tables/Build/ScanMal.php
CHANGED
@@ -52,7 +52,7 @@ class ScanMal extends ScanBase {
|
|
52 |
$aStatus[] = sprintf( '%s: %s/100 [%s]',
|
53 |
__( 'False Positive Confidence' ),
|
54 |
sprintf( '<strong>%s</strong>', (int)$oIt->fp_confidence ),
|
55 |
-
sprintf( '<a href="%s" target="_blank">%s↗</a>', 'https://
|
56 |
);
|
57 |
}
|
58 |
|
52 |
$aStatus[] = sprintf( '%s: %s/100 [%s]',
|
53 |
__( 'False Positive Confidence' ),
|
54 |
sprintf( '<strong>%s</strong>', (int)$oIt->fp_confidence ),
|
55 |
+
sprintf( '<a href="%s" target="_blank">%s↗</a>', 'https://shsec.io/isthismalware', __( 'more info', 'wp-simple-firewall' ) )
|
56 |
);
|
57 |
}
|
58 |
|
src/lib/src/Tables/Build/Traffic.php
CHANGED
@@ -132,7 +132,7 @@ class Traffic extends BaseBuild {
|
|
132 |
}
|
133 |
|
134 |
$sIpLink = sprintf( '<a href="%s" target="_blank" title="IP Whois">%s</a>%s',
|
135 |
-
$oIpSrv->
|
136 |
$aEntry[ 'is_you' ] ? ' <span style="font-size: smaller;">('.__( 'You', 'wp-simple-firewall' ).')</span>' : ''
|
137 |
);
|
138 |
|
132 |
}
|
133 |
|
134 |
$sIpLink = sprintf( '<a href="%s" target="_blank" title="IP Whois">%s</a>%s',
|
135 |
+
$oIpSrv->getIpInfo( $sIp ), $sIp,
|
136 |
$aEntry[ 'is_you' ] ? ' <span style="font-size: smaller;">('.__( 'You', 'wp-simple-firewall' ).')</span>' : ''
|
137 |
);
|
138 |
|
src/lib/src/Tables/Render/Base.php
CHANGED
@@ -231,13 +231,14 @@ class Base extends \WP_List_Table {
|
|
231 |
}
|
232 |
|
233 |
/**
|
234 |
-
* TODO Put this into
|
235 |
* @param string $sIp
|
236 |
* @return string
|
237 |
*/
|
238 |
protected function getIpWhoisLookupLink( $sIp ) {
|
|
|
239 |
return sprintf( '<a href="%s" target="_blank" class="ip-whois">%s</a>',
|
240 |
-
|
241 |
$sIp
|
242 |
);
|
243 |
}
|
231 |
}
|
232 |
|
233 |
/**
|
234 |
+
* TODO Put this into Service IPs and grab it from there
|
235 |
* @param string $sIp
|
236 |
* @return string
|
237 |
*/
|
238 |
protected function getIpWhoisLookupLink( $sIp ) {
|
239 |
+
$oIp = Services::IP();
|
240 |
return sprintf( '<a href="%s" target="_blank" class="ip-whois">%s</a>',
|
241 |
+
$oIp->isValidIpRange( $sIp ) ? $oIp->getIpWhoisLookup( $sIp ) : $oIp->getIpInfo( $sIp ),
|
242 |
$sIp
|
243 |
);
|
244 |
}
|
src/lib/src/Utilities/VisitorIpDetection.php
DELETED
@@ -1,187 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace FernleafSystems\Wordpress\Plugin\Shield\Utilities;
|
4 |
-
|
5 |
-
use FernleafSystems\Wordpress\Services\Services;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Class VisitorIpDetection
|
9 |
-
* @package FernleafSystems\Wordpress\Plugin\Shield\Utilities
|
10 |
-
* @deprecated 8.3
|
11 |
-
*/
|
12 |
-
class VisitorIpDetection {
|
13 |
-
|
14 |
-
const DEFAULT_SOURCE = 'REMOTE_ADDR';
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @var string[]
|
18 |
-
*/
|
19 |
-
private $aPotentialHostIps;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* @var string
|
23 |
-
*/
|
24 |
-
private $sLastSuccessfulSource;
|
25 |
-
|
26 |
-
/**
|
27 |
-
* @var string
|
28 |
-
*/
|
29 |
-
private $sPreferredSource;
|
30 |
-
|
31 |
-
/**
|
32 |
-
* @return string
|
33 |
-
*/
|
34 |
-
public function detect() {
|
35 |
-
return $this->runNormalDetection();
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Progressively removes Host IPs from the list so that these don't interfere with detection.
|
40 |
-
* @return string
|
41 |
-
*/
|
42 |
-
public function alternativeDetect() {
|
43 |
-
do {
|
44 |
-
$sIp = $this->runNormalDetection();
|
45 |
-
if ( !empty( $sIp ) ) {
|
46 |
-
break;
|
47 |
-
}
|
48 |
-
|
49 |
-
// Progressively remove a Host IP until there's none left.
|
50 |
-
$aHostIps = $this->getPotentialHostIps();
|
51 |
-
if ( empty( $aHostIps ) ) {
|
52 |
-
break;
|
53 |
-
}
|
54 |
-
array_shift( $aHostIps );
|
55 |
-
$this->setPotentialHostIps( $aHostIps );
|
56 |
-
} while ( empty( $sIp ) );
|
57 |
-
|
58 |
-
return $sIp;
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* @return string
|
63 |
-
*/
|
64 |
-
private function runNormalDetection() {
|
65 |
-
$sSource = '';
|
66 |
-
$aIps = $this->detectAndFilterFromSource( $this->getPreferredSource() );
|
67 |
-
|
68 |
-
if ( empty( $aIps ) ) { // Couldn't detect IP from preferred source.
|
69 |
-
|
70 |
-
foreach ( $this->getIpSourceOptions() as $sMaybeSource ) {
|
71 |
-
$aIps = $this->detectAndFilterFromSource( $sMaybeSource );
|
72 |
-
if ( !empty( $aIps ) ) {
|
73 |
-
$sSource = $sMaybeSource;
|
74 |
-
break;
|
75 |
-
}
|
76 |
-
}
|
77 |
-
}
|
78 |
-
else {
|
79 |
-
$sSource = $this->getPreferredSource();
|
80 |
-
}
|
81 |
-
|
82 |
-
$this->sLastSuccessfulSource = $sSource;
|
83 |
-
return empty( $aIps ) ? '' : array_shift( $aIps );
|
84 |
-
}
|
85 |
-
|
86 |
-
/**
|
87 |
-
* @param string $sSource
|
88 |
-
* @return string[]
|
89 |
-
*/
|
90 |
-
protected function detectAndFilterFromSource( $sSource ) {
|
91 |
-
return $this->filterIpsByViable( $this->getIpsFromSource( $sSource ) );
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* @param string[] $aIps
|
96 |
-
* @return string[]
|
97 |
-
*/
|
98 |
-
protected function filterIpsByViable( $aIps ) {
|
99 |
-
return array_values( array_filter(
|
100 |
-
$aIps,
|
101 |
-
function ( $sIp ) {
|
102 |
-
$oIP = Services::IP();
|
103 |
-
return ( $oIP->isValidIp_PublicRemote( $sIp )
|
104 |
-
&& !$oIP->checkIp( $sIp, $this->getPotentialHostIps() )
|
105 |
-
&& !$oIP->isCloudFlareIp( $sIp )
|
106 |
-
);
|
107 |
-
}
|
108 |
-
) );
|
109 |
-
}
|
110 |
-
|
111 |
-
/**
|
112 |
-
* @param string $sSource
|
113 |
-
* @return string[]
|
114 |
-
*/
|
115 |
-
protected function getIpsFromSource( $sSource ) {
|
116 |
-
$sRawSource = (string)Services::Request()->server( $sSource );
|
117 |
-
return array_filter(
|
118 |
-
empty( $sRawSource ) ? [] : array_map( 'trim', explode( ',', $sRawSource ) ),
|
119 |
-
function ( $sIp ) {
|
120 |
-
$sIp = trim( $sIp, ':' );
|
121 |
-
/** @var string $sIp */
|
122 |
-
$nSemi = strpos( $sIp, ':' );
|
123 |
-
if ( $nSemi !== false ) {
|
124 |
-
$sIp = substr( $sIp, 0, $nSemi );
|
125 |
-
}
|
126 |
-
return filter_var( $sIp, FILTER_VALIDATE_IP ) !== false;
|
127 |
-
}
|
128 |
-
);
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
* @return string[]
|
133 |
-
*/
|
134 |
-
public function getPotentialHostIps() {
|
135 |
-
return is_array( $this->aPotentialHostIps ) ? $this->aPotentialHostIps : [];
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* @return string
|
140 |
-
*/
|
141 |
-
public function getLastSuccessfulSource() {
|
142 |
-
return (string)$this->sLastSuccessfulSource;
|
143 |
-
}
|
144 |
-
|
145 |
-
/**
|
146 |
-
* @return string
|
147 |
-
*/
|
148 |
-
public function getPreferredSource() {
|
149 |
-
return empty( $this->sPreferredSource ) ? self::DEFAULT_SOURCE : $this->sPreferredSource;
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* @param string[] $aPotentialHostIps
|
154 |
-
* @return $this
|
155 |
-
*/
|
156 |
-
public function setPotentialHostIps( $aPotentialHostIps ) {
|
157 |
-
$this->aPotentialHostIps = $aPotentialHostIps;
|
158 |
-
return $this;
|
159 |
-
}
|
160 |
-
|
161 |
-
/**
|
162 |
-
* @param string $sDefaultSource
|
163 |
-
* @return $this
|
164 |
-
*/
|
165 |
-
public function setPreferredSource( $sDefaultSource ) {
|
166 |
-
$this->sPreferredSource = $sDefaultSource;
|
167 |
-
return $this;
|
168 |
-
}
|
169 |
-
|
170 |
-
/**
|
171 |
-
* @return string[]
|
172 |
-
*/
|
173 |
-
private function getIpSourceOptions() {
|
174 |
-
return [
|
175 |
-
'REMOTE_ADDR',
|
176 |
-
'HTTP_CF_CONNECTING_IP',
|
177 |
-
'HTTP_X_FORWARDED_FOR',
|
178 |
-
'HTTP_X_FORWARDED',
|
179 |
-
'HTTP_X_REAL_IP',
|
180 |
-
'HTTP_X_SUCURI_CLIENTIP',
|
181 |
-
'HTTP_INCAP_CLIENT_IP',
|
182 |
-
'HTTP_X_SP_FORWARDED_IP',
|
183 |
-
'HTTP_FORWARDED',
|
184 |
-
'HTTP_CLIENT_IP'
|
185 |
-
];
|
186 |
-
}
|
187 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/lib/vendor/composer/autoload_classmap.php
CHANGED
@@ -25,7 +25,6 @@ return array(
|
|
25 |
'Elliotchance\\Iterator\\PagedIteratorTest' => $vendorDir . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
|
26 |
'FernleafSystems\\Utilities\\Data\\Adapter\\StdClassAdapter' => $vendorDir . '/fernleafsystems/utilities/src/Data/Adapter/StdClassAdapter.php',
|
27 |
'FernleafSystems\\Utilities\\Response' => $vendorDir . '/fernleafsystems/utilities/src/Response.php',
|
28 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\AuditTrail\\Auditor' => $baseDir . '/src/AuditTrail/Auditor.php',
|
29 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => $baseDir . '/src/ChangeTrack/Diff/Base.php',
|
30 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => $baseDir . '/src/ChangeTrack/Diff/DiffComments.php',
|
31 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => $baseDir . '/src/ChangeTrack/Diff/DiffMedia.php',
|
@@ -83,6 +82,7 @@ return array(
|
|
83 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Handler' => $baseDir . '/src/Databases/Comments/Handler.php',
|
84 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Insert' => $baseDir . '/src/Databases/Comments/Insert.php',
|
85 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Select' => $baseDir . '/src/Databases/Comments/Select.php',
|
|
|
86 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\Delete' => $baseDir . '/src/Databases/Events/Delete.php',
|
87 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\EntryVO' => $baseDir . '/src/Databases/Events/EntryVO.php',
|
88 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\Handler' => $baseDir . '/src/Databases/Events/Handler.php',
|
@@ -159,15 +159,20 @@ return array(
|
|
159 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ShieldOptions' => $baseDir . '/src/Modules/Base/ShieldOptions.php',
|
160 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Strings' => $baseDir . '/src/Modules/Base/Strings.php',
|
161 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\AdminNotices' => $baseDir . '/src/Modules/CommentsFilter/AdminNotices.php',
|
|
|
162 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Options' => $baseDir . '/src/Modules/CommentsFilter/Options.php',
|
163 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Bot' => $baseDir . '/src/Modules/CommentsFilter/Scan/Bot.php',
|
164 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Human' => $baseDir . '/src/Modules/CommentsFilter/Scan/Human.php',
|
165 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\IsEmailTrusted' => $baseDir . '/src/Modules/CommentsFilter/Scan/IsEmailTrusted.php',
|
166 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Scanner' => $baseDir . '/src/Modules/CommentsFilter/Scan/Scanner.php',
|
167 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Strings' => $baseDir . '/src/Modules/CommentsFilter/Strings.php',
|
|
|
168 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Email\\Options' => $baseDir . '/src/Modules/Email/Options.php',
|
169 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Email\\Strings' => $baseDir . '/src/Modules/Email/Strings.php',
|
170 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\AjaxHandler' => $baseDir . '/src/Modules/Events/AjaxHandler.php',
|
|
|
|
|
|
|
171 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Options' => $baseDir . '/src/Modules/Events/Options.php',
|
172 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Strings' => $baseDir . '/src/Modules/Events/Strings.php',
|
173 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Options' => $baseDir . '/src/Modules/Firewall/Options.php',
|
@@ -208,6 +213,7 @@ return array(
|
|
208 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackLoginInvalid' => $baseDir . '/src/Modules/IPs/BotTrack/TrackLoginInvalid.php',
|
209 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackUserAgent' => $baseDir . '/src/Modules/IPs/BotTrack/TrackUserAgent.php',
|
210 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackXmlRpc' => $baseDir . '/src/Modules/IPs/BotTrack/TrackXmlRpc.php',
|
|
|
211 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => $baseDir . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
|
212 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Options' => $baseDir . '/src/Modules/IPs/Options.php',
|
213 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Strings' => $baseDir . '/src/Modules/IPs/Strings.php',
|
@@ -231,6 +237,7 @@ return array(
|
|
231 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\AjaxHandler' => $baseDir . '/src/Modules/Plugin/AjaxHandler.php',
|
232 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Components\\BadgeWidget' => $baseDir . '/src/Modules/Plugin/Components/BadgeWidget.php',
|
233 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Components\\PluginBadge' => $baseDir . '/src/Modules/Plugin/Components/PluginBadge.php',
|
|
|
234 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Options' => $baseDir . '/src/Modules/Plugin/Options.php',
|
235 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Strings' => $baseDir . '/src/Modules/Plugin/Strings.php',
|
236 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => $baseDir . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
@@ -291,6 +298,7 @@ return array(
|
|
291 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Scan' => $baseDir . '/src/Scans/Mal/Scan.php',
|
292 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\ScanActionVO' => $baseDir . '/src/Scans/Mal/ScanActionVO.php',
|
293 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\ScanFromFileMap' => $baseDir . '/src/Scans/Mal/ScanFromFileMap.php',
|
|
|
294 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\FalsePositiveReporter' => $baseDir . '/src/Scans/Mal/Utilities/FalsePositiveReporter.php',
|
295 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\Patterns' => $baseDir . '/src/Scans/Mal/Utilities/Patterns.php',
|
296 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\Signatures' => $baseDir . '/src/Scans/Mal/Utilities/Signatures.php',
|
@@ -379,7 +387,6 @@ return array(
|
|
379 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\NoticeVO' => $baseDir . '/src/Utilities/AdminNotices/NoticeVO.php',
|
380 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\TestRequest' => $baseDir . '/src/Utilities/ReCaptcha/TestRequest.php',
|
381 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\WordpressPost' => $baseDir . '/src/Utilities/ReCaptcha/WordpressPost.php',
|
382 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\VisitorIpDetection' => $baseDir . '/src/Utilities/VisitorIpDetection.php',
|
383 |
'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
|
384 |
'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
|
385 |
'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
|
@@ -402,6 +409,7 @@ return array(
|
|
402 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\PluginUpgrader' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/PluginUpgrader.php',
|
403 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\ThemeUpgrader' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/ThemeUpgrader.php',
|
404 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkin' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkin.php',
|
|
|
405 |
'FernleafSystems\\Wordpress\\Services\\Core\\Users' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Users.php',
|
406 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
|
407 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
@@ -502,14 +510,7 @@ return array(
|
|
502 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Versions' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Versions.php',
|
503 |
'Html2Text\\Html2Text' => $vendorDir . '/soundasleep/html2text/src/Html2Text.php',
|
504 |
'Html2Text\\Html2TextException' => $vendorDir . '/soundasleep/html2text/src/Html2TextException.php',
|
505 |
-
'ICWP_Bulk_Plugin_Upgrader_Skin' => $baseDir . '/../common/icwp-wpupgrades.php',
|
506 |
-
'ICWP_Bulk_Theme_Upgrader_Skin' => $baseDir . '/../common/icwp-wpupgrades.php',
|
507 |
-
'ICWP_Plugin_Upgrader' => $baseDir . '/../common/icwp-wpupgrades.php',
|
508 |
-
'ICWP_Theme_Upgrader' => $baseDir . '/../common/icwp-wpupgrades.php',
|
509 |
-
'ICWP_Upgrader_Skin' => $baseDir . '/../common/icwp-wpupgrades.php',
|
510 |
-
'ICWP_WPSF_BaseDbProcessor' => $baseDir . '/../processors/basedb.php',
|
511 |
'ICWP_WPSF_DataProcessor' => $baseDir . '/../common/icwp-data.php',
|
512 |
-
'ICWP_WPSF_Edd' => $baseDir . '/../common/icwp-edd.php',
|
513 |
'ICWP_WPSF_FeatureHandler_AdminAccessRestriction' => $baseDir . '/../features/admin_access_restriction.php',
|
514 |
'ICWP_WPSF_FeatureHandler_AuditTrail' => $baseDir . '/../features/audit_trail.php',
|
515 |
'ICWP_WPSF_FeatureHandler_Autoupdates' => $baseDir . '/../features/autoupdates.php',
|
@@ -532,17 +533,12 @@ return array(
|
|
532 |
'ICWP_WPSF_FeatureHandler_Traffic' => $baseDir . '/../features/traffic.php',
|
533 |
'ICWP_WPSF_FeatureHandler_UserManagement' => $baseDir . '/../features/user_management.php',
|
534 |
'ICWP_WPSF_Foundation' => $baseDir . '/../common/icwp-foundation.php',
|
535 |
-
'ICWP_WPSF_OptionsVO' => $baseDir . '/../common/icwp-optionsvo.php',
|
536 |
-
'ICWP_WPSF_Plugin_Controller' => $baseDir . '/../../icwp-plugin-controller.php',
|
537 |
'ICWP_WPSF_Processor_AdminAccessRestriction' => $baseDir . '/../processors/admin_access_restriction.php',
|
538 |
'ICWP_WPSF_Processor_AdminAccess_Whitelabel' => $baseDir . '/../processors/adminaccess_whitelabel.php',
|
539 |
'ICWP_WPSF_Processor_AuditTrail' => $baseDir . '/../processors/audit_trail.php',
|
540 |
'ICWP_WPSF_Processor_AuditTrail_Auditor' => $baseDir . '/../processors/audit_trail_auditor.php',
|
541 |
'ICWP_WPSF_Processor_AuditTrail_ChangeTracking' => $baseDir . '/../processors/audit_trail_changetracking.php',
|
542 |
'ICWP_WPSF_Processor_Autoupdates' => $baseDir . '/../processors/autoupdates.php',
|
543 |
-
'ICWP_WPSF_Processor_Base' => $baseDir . '/../processors/base.php',
|
544 |
-
'ICWP_WPSF_Processor_BasePlugin' => $baseDir . '/../processors/base_plugin.php',
|
545 |
-
'ICWP_WPSF_Processor_BaseWpsf' => $baseDir . '/../processors/base_wpsf.php',
|
546 |
'ICWP_WPSF_Processor_CommentsFilter' => $baseDir . '/../processors/comments_filter.php',
|
547 |
'ICWP_WPSF_Processor_CommentsFilter_BotSpam' => $baseDir . '/../processors/commentsfilter_botspam.php',
|
548 |
'ICWP_WPSF_Processor_CommentsFilter_GoogleRecaptcha' => $baseDir . '/../processors/commentsfilter_googlerecaptcha.php',
|
@@ -591,26 +587,13 @@ return array(
|
|
591 |
'ICWP_WPSF_Processor_UserManagement_Passwords' => $baseDir . '/../processors/usermanagement_passwords.php',
|
592 |
'ICWP_WPSF_Processor_UserManagement_Sessions' => $baseDir . '/../processors/usermanagement_sessions.php',
|
593 |
'ICWP_WPSF_Processor_UserManagement_Suspend' => $baseDir . '/../processors/usermanagement_suspend.php',
|
594 |
-
'ICWP_WPSF_Query_Statistics_Base' => $baseDir . '/../query/base/statistics_base.php',
|
595 |
-
'ICWP_WPSF_Query_Statistics_Reporting' => $baseDir . '/../query/statistics/reporting.php',
|
596 |
-
'ICWP_WPSF_Render' => $baseDir . '/../common/icwp-render.php',
|
597 |
-
'ICWP_WPSF_Request' => $baseDir . '/../common/icwp-request.php',
|
598 |
'ICWP_WPSF_ServiceProviders' => $baseDir . '/../common/icwp-serviceproviders.php',
|
599 |
'ICWP_WPSF_Wizard_Base' => $baseDir . '/../wizards/base.php',
|
600 |
'ICWP_WPSF_Wizard_BaseWpsf' => $baseDir . '/../wizards/base_wpsf.php',
|
601 |
'ICWP_WPSF_Wizard_LoginProtect' => $baseDir . '/../wizards/login_protect.php',
|
602 |
'ICWP_WPSF_Wizard_Plugin' => $baseDir . '/../wizards/plugin.php',
|
603 |
'ICWP_WPSF_WpAdminNotices' => $baseDir . '/../common/wp-admin-notices.php',
|
604 |
-
'ICWP_WPSF_WpComments' => $baseDir . '/../common/wp-comments.php',
|
605 |
'ICWP_WPSF_WpCron' => $baseDir . '/../common/icwp-wpcron.php',
|
606 |
-
'ICWP_WPSF_WpDb' => $baseDir . '/../common/icwp-wpdb.php',
|
607 |
-
'ICWP_WPSF_WpFilesystem' => $baseDir . '/../common/icwp-wpfilesystem.php',
|
608 |
-
'ICWP_WPSF_WpFunctions' => $baseDir . '/../common/icwp-wpfunctions.php',
|
609 |
-
'ICWP_WPSF_WpFunctions_Plugins' => $baseDir . '/../common/icwp-wpfunctions-plugins.php',
|
610 |
-
'ICWP_WPSF_WpFunctions_Themes' => $baseDir . '/../common/icwp-wpfunctions-themes.php',
|
611 |
-
'ICWP_WPSF_WpIncludes' => $baseDir . '/../common/icwp-wpincludes.php',
|
612 |
-
'ICWP_WPSF_WpUpgrades' => $baseDir . '/../common/icwp-wpupgrades.php',
|
613 |
-
'ICWP_WPSF_WpUsers' => $baseDir . '/../common/wp-users.php',
|
614 |
'ICWP_WPSF_WpWidget' => $baseDir . '/../common/wp-widget.php',
|
615 |
'JsonSerializable' => $vendorDir . '/nesbot/carbon/src/JsonSerializable.php',
|
616 |
'LZCompressor\\LZContext' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php',
|
25 |
'Elliotchance\\Iterator\\PagedIteratorTest' => $vendorDir . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
|
26 |
'FernleafSystems\\Utilities\\Data\\Adapter\\StdClassAdapter' => $vendorDir . '/fernleafsystems/utilities/src/Data/Adapter/StdClassAdapter.php',
|
27 |
'FernleafSystems\\Utilities\\Response' => $vendorDir . '/fernleafsystems/utilities/src/Response.php',
|
|
|
28 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => $baseDir . '/src/ChangeTrack/Diff/Base.php',
|
29 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => $baseDir . '/src/ChangeTrack/Diff/DiffComments.php',
|
30 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => $baseDir . '/src/ChangeTrack/Diff/DiffMedia.php',
|
82 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Handler' => $baseDir . '/src/Databases/Comments/Handler.php',
|
83 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Insert' => $baseDir . '/src/Databases/Comments/Insert.php',
|
84 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Select' => $baseDir . '/src/Databases/Comments/Select.php',
|
85 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\Common' => $baseDir . '/src/Databases/Events/Common.php',
|
86 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\Delete' => $baseDir . '/src/Databases/Events/Delete.php',
|
87 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\EntryVO' => $baseDir . '/src/Databases/Events/EntryVO.php',
|
88 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\Handler' => $baseDir . '/src/Databases/Events/Handler.php',
|
159 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ShieldOptions' => $baseDir . '/src/Modules/Base/ShieldOptions.php',
|
160 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Strings' => $baseDir . '/src/Modules/Base/Strings.php',
|
161 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\AdminNotices' => $baseDir . '/src/Modules/CommentsFilter/AdminNotices.php',
|
162 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\AjaxHandler' => $baseDir . '/src/Modules/CommentsFilter/AjaxHandler.php',
|
163 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Options' => $baseDir . '/src/Modules/CommentsFilter/Options.php',
|
164 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Bot' => $baseDir . '/src/Modules/CommentsFilter/Scan/Bot.php',
|
165 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Human' => $baseDir . '/src/Modules/CommentsFilter/Scan/Human.php',
|
166 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\IsEmailTrusted' => $baseDir . '/src/Modules/CommentsFilter/Scan/IsEmailTrusted.php',
|
167 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Scanner' => $baseDir . '/src/Modules/CommentsFilter/Scan/Scanner.php',
|
168 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Strings' => $baseDir . '/src/Modules/CommentsFilter/Strings.php',
|
169 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Token\\Create' => $baseDir . '/src/Modules/CommentsFilter/Token/Create.php',
|
170 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Email\\Options' => $baseDir . '/src/Modules/Email/Options.php',
|
171 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Email\\Strings' => $baseDir . '/src/Modules/Email/Strings.php',
|
172 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\AjaxHandler' => $baseDir . '/src/Modules/Events/AjaxHandler.php',
|
173 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Charts\\BuildData' => $baseDir . '/src/Modules/Events/Charts/BuildData.php',
|
174 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Charts\\ChartRequestVO' => $baseDir . '/src/Modules/Events/Charts/ChartRequestVO.php',
|
175 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Consolidate\\ConsolidateAllEvents' => $baseDir . '/src/Modules/Events/Consolidate/ConsolidateAllEvents.php',
|
176 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Options' => $baseDir . '/src/Modules/Events/Options.php',
|
177 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Strings' => $baseDir . '/src/Modules/Events/Strings.php',
|
178 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Options' => $baseDir . '/src/Modules/Firewall/Options.php',
|
213 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackLoginInvalid' => $baseDir . '/src/Modules/IPs/BotTrack/TrackLoginInvalid.php',
|
214 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackUserAgent' => $baseDir . '/src/Modules/IPs/BotTrack/TrackUserAgent.php',
|
215 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackXmlRpc' => $baseDir . '/src/Modules/IPs/BotTrack/TrackXmlRpc.php',
|
216 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\LookupIpOnList' => $baseDir . '/src/Modules/IPs/Components/LookupIpOnList.php',
|
217 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => $baseDir . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
|
218 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Options' => $baseDir . '/src/Modules/IPs/Options.php',
|
219 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Strings' => $baseDir . '/src/Modules/IPs/Strings.php',
|
237 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\AjaxHandler' => $baseDir . '/src/Modules/Plugin/AjaxHandler.php',
|
238 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Components\\BadgeWidget' => $baseDir . '/src/Modules/Plugin/Components/BadgeWidget.php',
|
239 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Components\\PluginBadge' => $baseDir . '/src/Modules/Plugin/Components/PluginBadge.php',
|
240 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Components\\SiteGroundPluginCompatibility' => $baseDir . '/src/Modules/Plugin/Components/SiteGroundPluginCompatibility.php',
|
241 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Options' => $baseDir . '/src/Modules/Plugin/Options.php',
|
242 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Strings' => $baseDir . '/src/Modules/Plugin/Strings.php',
|
243 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => $baseDir . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
298 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Scan' => $baseDir . '/src/Scans/Mal/Scan.php',
|
299 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\ScanActionVO' => $baseDir . '/src/Scans/Mal/ScanActionVO.php',
|
300 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\ScanFromFileMap' => $baseDir . '/src/Scans/Mal/ScanFromFileMap.php',
|
301 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\FalsePositiveQuery' => $baseDir . '/src/Scans/Mal/Utilities/FalsePositiveQuery.php',
|
302 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\FalsePositiveReporter' => $baseDir . '/src/Scans/Mal/Utilities/FalsePositiveReporter.php',
|
303 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\Patterns' => $baseDir . '/src/Scans/Mal/Utilities/Patterns.php',
|
304 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\Signatures' => $baseDir . '/src/Scans/Mal/Utilities/Signatures.php',
|
387 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\NoticeVO' => $baseDir . '/src/Utilities/AdminNotices/NoticeVO.php',
|
388 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\TestRequest' => $baseDir . '/src/Utilities/ReCaptcha/TestRequest.php',
|
389 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\WordpressPost' => $baseDir . '/src/Utilities/ReCaptcha/WordpressPost.php',
|
|
|
390 |
'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
|
391 |
'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
|
392 |
'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
|
409 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\PluginUpgrader' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/PluginUpgrader.php',
|
410 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\ThemeUpgrader' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/ThemeUpgrader.php',
|
411 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkin' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkin.php',
|
412 |
+
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkinLegacy' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkinLegacy.php',
|
413 |
'FernleafSystems\\Wordpress\\Services\\Core\\Users' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Users.php',
|
414 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
|
415 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
510 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Versions' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Versions.php',
|
511 |
'Html2Text\\Html2Text' => $vendorDir . '/soundasleep/html2text/src/Html2Text.php',
|
512 |
'Html2Text\\Html2TextException' => $vendorDir . '/soundasleep/html2text/src/Html2TextException.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
513 |
'ICWP_WPSF_DataProcessor' => $baseDir . '/../common/icwp-data.php',
|
|
|
514 |
'ICWP_WPSF_FeatureHandler_AdminAccessRestriction' => $baseDir . '/../features/admin_access_restriction.php',
|
515 |
'ICWP_WPSF_FeatureHandler_AuditTrail' => $baseDir . '/../features/audit_trail.php',
|
516 |
'ICWP_WPSF_FeatureHandler_Autoupdates' => $baseDir . '/../features/autoupdates.php',
|
533 |
'ICWP_WPSF_FeatureHandler_Traffic' => $baseDir . '/../features/traffic.php',
|
534 |
'ICWP_WPSF_FeatureHandler_UserManagement' => $baseDir . '/../features/user_management.php',
|
535 |
'ICWP_WPSF_Foundation' => $baseDir . '/../common/icwp-foundation.php',
|
|
|
|
|
536 |
'ICWP_WPSF_Processor_AdminAccessRestriction' => $baseDir . '/../processors/admin_access_restriction.php',
|
537 |
'ICWP_WPSF_Processor_AdminAccess_Whitelabel' => $baseDir . '/../processors/adminaccess_whitelabel.php',
|
538 |
'ICWP_WPSF_Processor_AuditTrail' => $baseDir . '/../processors/audit_trail.php',
|
539 |
'ICWP_WPSF_Processor_AuditTrail_Auditor' => $baseDir . '/../processors/audit_trail_auditor.php',
|
540 |
'ICWP_WPSF_Processor_AuditTrail_ChangeTracking' => $baseDir . '/../processors/audit_trail_changetracking.php',
|
541 |
'ICWP_WPSF_Processor_Autoupdates' => $baseDir . '/../processors/autoupdates.php',
|
|
|
|
|
|
|
542 |
'ICWP_WPSF_Processor_CommentsFilter' => $baseDir . '/../processors/comments_filter.php',
|
543 |
'ICWP_WPSF_Processor_CommentsFilter_BotSpam' => $baseDir . '/../processors/commentsfilter_botspam.php',
|
544 |
'ICWP_WPSF_Processor_CommentsFilter_GoogleRecaptcha' => $baseDir . '/../processors/commentsfilter_googlerecaptcha.php',
|
587 |
'ICWP_WPSF_Processor_UserManagement_Passwords' => $baseDir . '/../processors/usermanagement_passwords.php',
|
588 |
'ICWP_WPSF_Processor_UserManagement_Sessions' => $baseDir . '/../processors/usermanagement_sessions.php',
|
589 |
'ICWP_WPSF_Processor_UserManagement_Suspend' => $baseDir . '/../processors/usermanagement_suspend.php',
|
|
|
|
|
|
|
|
|
590 |
'ICWP_WPSF_ServiceProviders' => $baseDir . '/../common/icwp-serviceproviders.php',
|
591 |
'ICWP_WPSF_Wizard_Base' => $baseDir . '/../wizards/base.php',
|
592 |
'ICWP_WPSF_Wizard_BaseWpsf' => $baseDir . '/../wizards/base_wpsf.php',
|
593 |
'ICWP_WPSF_Wizard_LoginProtect' => $baseDir . '/../wizards/login_protect.php',
|
594 |
'ICWP_WPSF_Wizard_Plugin' => $baseDir . '/../wizards/plugin.php',
|
595 |
'ICWP_WPSF_WpAdminNotices' => $baseDir . '/../common/wp-admin-notices.php',
|
|
|
596 |
'ICWP_WPSF_WpCron' => $baseDir . '/../common/icwp-wpcron.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
'ICWP_WPSF_WpWidget' => $baseDir . '/../common/wp-widget.php',
|
598 |
'JsonSerializable' => $vendorDir . '/nesbot/carbon/src/JsonSerializable.php',
|
599 |
'LZCompressor\\LZContext' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php',
|
src/lib/vendor/composer/autoload_static.php
CHANGED
@@ -174,7 +174,6 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
174 |
'Elliotchance\\Iterator\\PagedIteratorTest' => __DIR__ . '/..' . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
|
175 |
'FernleafSystems\\Utilities\\Data\\Adapter\\StdClassAdapter' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Data/Adapter/StdClassAdapter.php',
|
176 |
'FernleafSystems\\Utilities\\Response' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Response.php',
|
177 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\AuditTrail\\Auditor' => __DIR__ . '/../..' . '/src/AuditTrail/Auditor.php',
|
178 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/Base.php',
|
179 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffComments.php',
|
180 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffMedia.php',
|
@@ -232,6 +231,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
232 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Handler' => __DIR__ . '/../..' . '/src/Databases/Comments/Handler.php',
|
233 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Insert' => __DIR__ . '/../..' . '/src/Databases/Comments/Insert.php',
|
234 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Select' => __DIR__ . '/../..' . '/src/Databases/Comments/Select.php',
|
|
|
235 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\Delete' => __DIR__ . '/../..' . '/src/Databases/Events/Delete.php',
|
236 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\EntryVO' => __DIR__ . '/../..' . '/src/Databases/Events/EntryVO.php',
|
237 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\Handler' => __DIR__ . '/../..' . '/src/Databases/Events/Handler.php',
|
@@ -308,15 +308,20 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
308 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ShieldOptions' => __DIR__ . '/../..' . '/src/Modules/Base/ShieldOptions.php',
|
309 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Strings' => __DIR__ . '/../..' . '/src/Modules/Base/Strings.php',
|
310 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\AdminNotices' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/AdminNotices.php',
|
|
|
311 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Options' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Options.php',
|
312 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Bot' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Scan/Bot.php',
|
313 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Human' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Scan/Human.php',
|
314 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\IsEmailTrusted' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Scan/IsEmailTrusted.php',
|
315 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Scanner' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Scan/Scanner.php',
|
316 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Strings' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Strings.php',
|
|
|
317 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Email\\Options' => __DIR__ . '/../..' . '/src/Modules/Email/Options.php',
|
318 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Email\\Strings' => __DIR__ . '/../..' . '/src/Modules/Email/Strings.php',
|
319 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/Events/AjaxHandler.php',
|
|
|
|
|
|
|
320 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Options' => __DIR__ . '/../..' . '/src/Modules/Events/Options.php',
|
321 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Strings' => __DIR__ . '/../..' . '/src/Modules/Events/Strings.php',
|
322 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Options' => __DIR__ . '/../..' . '/src/Modules/Firewall/Options.php',
|
@@ -357,6 +362,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
357 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackLoginInvalid' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackLoginInvalid.php',
|
358 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackUserAgent' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackUserAgent.php',
|
359 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackXmlRpc' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackXmlRpc.php',
|
|
|
360 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
|
361 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Options' => __DIR__ . '/../..' . '/src/Modules/IPs/Options.php',
|
362 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Strings' => __DIR__ . '/../..' . '/src/Modules/IPs/Strings.php',
|
@@ -380,6 +386,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
380 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/Plugin/AjaxHandler.php',
|
381 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Components\\BadgeWidget' => __DIR__ . '/../..' . '/src/Modules/Plugin/Components/BadgeWidget.php',
|
382 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Components\\PluginBadge' => __DIR__ . '/../..' . '/src/Modules/Plugin/Components/PluginBadge.php',
|
|
|
383 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Options' => __DIR__ . '/../..' . '/src/Modules/Plugin/Options.php',
|
384 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Strings' => __DIR__ . '/../..' . '/src/Modules/Plugin/Strings.php',
|
385 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
@@ -440,6 +447,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
440 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Scan' => __DIR__ . '/../..' . '/src/Scans/Mal/Scan.php',
|
441 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Mal/ScanActionVO.php',
|
442 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\ScanFromFileMap' => __DIR__ . '/../..' . '/src/Scans/Mal/ScanFromFileMap.php',
|
|
|
443 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\FalsePositiveReporter' => __DIR__ . '/../..' . '/src/Scans/Mal/Utilities/FalsePositiveReporter.php',
|
444 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\Patterns' => __DIR__ . '/../..' . '/src/Scans/Mal/Utilities/Patterns.php',
|
445 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\Signatures' => __DIR__ . '/../..' . '/src/Scans/Mal/Utilities/Signatures.php',
|
@@ -528,7 +536,6 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
528 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\NoticeVO' => __DIR__ . '/../..' . '/src/Utilities/AdminNotices/NoticeVO.php',
|
529 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\TestRequest' => __DIR__ . '/../..' . '/src/Utilities/ReCaptcha/TestRequest.php',
|
530 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\WordpressPost' => __DIR__ . '/../..' . '/src/Utilities/ReCaptcha/WordpressPost.php',
|
531 |
-
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\VisitorIpDetection' => __DIR__ . '/../..' . '/src/Utilities/VisitorIpDetection.php',
|
532 |
'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
|
533 |
'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
|
534 |
'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
|
@@ -551,6 +558,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
551 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\PluginUpgrader' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/PluginUpgrader.php',
|
552 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\ThemeUpgrader' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/ThemeUpgrader.php',
|
553 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkin' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkin.php',
|
|
|
554 |
'FernleafSystems\\Wordpress\\Services\\Core\\Users' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Users.php',
|
555 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
|
556 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
@@ -651,14 +659,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
651 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Versions' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Versions.php',
|
652 |
'Html2Text\\Html2Text' => __DIR__ . '/..' . '/soundasleep/html2text/src/Html2Text.php',
|
653 |
'Html2Text\\Html2TextException' => __DIR__ . '/..' . '/soundasleep/html2text/src/Html2TextException.php',
|
654 |
-
'ICWP_Bulk_Plugin_Upgrader_Skin' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
|
655 |
-
'ICWP_Bulk_Theme_Upgrader_Skin' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
|
656 |
-
'ICWP_Plugin_Upgrader' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
|
657 |
-
'ICWP_Theme_Upgrader' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
|
658 |
-
'ICWP_Upgrader_Skin' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
|
659 |
-
'ICWP_WPSF_BaseDbProcessor' => __DIR__ . '/../..' . '/../processors/basedb.php',
|
660 |
'ICWP_WPSF_DataProcessor' => __DIR__ . '/../..' . '/../common/icwp-data.php',
|
661 |
-
'ICWP_WPSF_Edd' => __DIR__ . '/../..' . '/../common/icwp-edd.php',
|
662 |
'ICWP_WPSF_FeatureHandler_AdminAccessRestriction' => __DIR__ . '/../..' . '/../features/admin_access_restriction.php',
|
663 |
'ICWP_WPSF_FeatureHandler_AuditTrail' => __DIR__ . '/../..' . '/../features/audit_trail.php',
|
664 |
'ICWP_WPSF_FeatureHandler_Autoupdates' => __DIR__ . '/../..' . '/../features/autoupdates.php',
|
@@ -681,17 +682,12 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
681 |
'ICWP_WPSF_FeatureHandler_Traffic' => __DIR__ . '/../..' . '/../features/traffic.php',
|
682 |
'ICWP_WPSF_FeatureHandler_UserManagement' => __DIR__ . '/../..' . '/../features/user_management.php',
|
683 |
'ICWP_WPSF_Foundation' => __DIR__ . '/../..' . '/../common/icwp-foundation.php',
|
684 |
-
'ICWP_WPSF_OptionsVO' => __DIR__ . '/../..' . '/../common/icwp-optionsvo.php',
|
685 |
-
'ICWP_WPSF_Plugin_Controller' => __DIR__ . '/../..' . '/../../icwp-plugin-controller.php',
|
686 |
'ICWP_WPSF_Processor_AdminAccessRestriction' => __DIR__ . '/../..' . '/../processors/admin_access_restriction.php',
|
687 |
'ICWP_WPSF_Processor_AdminAccess_Whitelabel' => __DIR__ . '/../..' . '/../processors/adminaccess_whitelabel.php',
|
688 |
'ICWP_WPSF_Processor_AuditTrail' => __DIR__ . '/../..' . '/../processors/audit_trail.php',
|
689 |
'ICWP_WPSF_Processor_AuditTrail_Auditor' => __DIR__ . '/../..' . '/../processors/audit_trail_auditor.php',
|
690 |
'ICWP_WPSF_Processor_AuditTrail_ChangeTracking' => __DIR__ . '/../..' . '/../processors/audit_trail_changetracking.php',
|
691 |
'ICWP_WPSF_Processor_Autoupdates' => __DIR__ . '/../..' . '/../processors/autoupdates.php',
|
692 |
-
'ICWP_WPSF_Processor_Base' => __DIR__ . '/../..' . '/../processors/base.php',
|
693 |
-
'ICWP_WPSF_Processor_BasePlugin' => __DIR__ . '/../..' . '/../processors/base_plugin.php',
|
694 |
-
'ICWP_WPSF_Processor_BaseWpsf' => __DIR__ . '/../..' . '/../processors/base_wpsf.php',
|
695 |
'ICWP_WPSF_Processor_CommentsFilter' => __DIR__ . '/../..' . '/../processors/comments_filter.php',
|
696 |
'ICWP_WPSF_Processor_CommentsFilter_BotSpam' => __DIR__ . '/../..' . '/../processors/commentsfilter_botspam.php',
|
697 |
'ICWP_WPSF_Processor_CommentsFilter_GoogleRecaptcha' => __DIR__ . '/../..' . '/../processors/commentsfilter_googlerecaptcha.php',
|
@@ -740,26 +736,13 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
|
|
740 |
'ICWP_WPSF_Processor_UserManagement_Passwords' => __DIR__ . '/../..' . '/../processors/usermanagement_passwords.php',
|
741 |
'ICWP_WPSF_Processor_UserManagement_Sessions' => __DIR__ . '/../..' . '/../processors/usermanagement_sessions.php',
|
742 |
'ICWP_WPSF_Processor_UserManagement_Suspend' => __DIR__ . '/../..' . '/../processors/usermanagement_suspend.php',
|
743 |
-
'ICWP_WPSF_Query_Statistics_Base' => __DIR__ . '/../..' . '/../query/base/statistics_base.php',
|
744 |
-
'ICWP_WPSF_Query_Statistics_Reporting' => __DIR__ . '/../..' . '/../query/statistics/reporting.php',
|
745 |
-
'ICWP_WPSF_Render' => __DIR__ . '/../..' . '/../common/icwp-render.php',
|
746 |
-
'ICWP_WPSF_Request' => __DIR__ . '/../..' . '/../common/icwp-request.php',
|
747 |
'ICWP_WPSF_ServiceProviders' => __DIR__ . '/../..' . '/../common/icwp-serviceproviders.php',
|
748 |
'ICWP_WPSF_Wizard_Base' => __DIR__ . '/../..' . '/../wizards/base.php',
|
749 |
'ICWP_WPSF_Wizard_BaseWpsf' => __DIR__ . '/../..' . '/../wizards/base_wpsf.php',
|
750 |
'ICWP_WPSF_Wizard_LoginProtect' => __DIR__ . '/../..' . '/../wizards/login_protect.php',
|
751 |
'ICWP_WPSF_Wizard_Plugin' => __DIR__ . '/../..' . '/../wizards/plugin.php',
|
752 |
'ICWP_WPSF_WpAdminNotices' => __DIR__ . '/../..' . '/../common/wp-admin-notices.php',
|
753 |
-
'ICWP_WPSF_WpComments' => __DIR__ . '/../..' . '/../common/wp-comments.php',
|
754 |
'ICWP_WPSF_WpCron' => __DIR__ . '/../..' . '/../common/icwp-wpcron.php',
|
755 |
-
'ICWP_WPSF_WpDb' => __DIR__ . '/../..' . '/../common/icwp-wpdb.php',
|
756 |
-
'ICWP_WPSF_WpFilesystem' => __DIR__ . '/../..' . '/../common/icwp-wpfilesystem.php',
|
757 |
-
'ICWP_WPSF_WpFunctions' => __DIR__ . '/../..' . '/../common/icwp-wpfunctions.php',
|
758 |
-
'ICWP_WPSF_WpFunctions_Plugins' => __DIR__ . '/../..' . '/../common/icwp-wpfunctions-plugins.php',
|
759 |
-
'ICWP_WPSF_WpFunctions_Themes' => __DIR__ . '/../..' . '/../common/icwp-wpfunctions-themes.php',
|
760 |
-
'ICWP_WPSF_WpIncludes' => __DIR__ . '/../..' . '/../common/icwp-wpincludes.php',
|
761 |
-
'ICWP_WPSF_WpUpgrades' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
|
762 |
-
'ICWP_WPSF_WpUsers' => __DIR__ . '/../..' . '/../common/wp-users.php',
|
763 |
'ICWP_WPSF_WpWidget' => __DIR__ . '/../..' . '/../common/wp-widget.php',
|
764 |
'JsonSerializable' => __DIR__ . '/..' . '/nesbot/carbon/src/JsonSerializable.php',
|
765 |
'LZCompressor\\LZContext' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php',
|
174 |
'Elliotchance\\Iterator\\PagedIteratorTest' => __DIR__ . '/..' . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
|
175 |
'FernleafSystems\\Utilities\\Data\\Adapter\\StdClassAdapter' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Data/Adapter/StdClassAdapter.php',
|
176 |
'FernleafSystems\\Utilities\\Response' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Response.php',
|
|
|
177 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/Base.php',
|
178 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffComments.php',
|
179 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffMedia.php',
|
231 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Handler' => __DIR__ . '/../..' . '/src/Databases/Comments/Handler.php',
|
232 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Insert' => __DIR__ . '/../..' . '/src/Databases/Comments/Insert.php',
|
233 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Comments\\Select' => __DIR__ . '/../..' . '/src/Databases/Comments/Select.php',
|
234 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\Common' => __DIR__ . '/../..' . '/src/Databases/Events/Common.php',
|
235 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\Delete' => __DIR__ . '/../..' . '/src/Databases/Events/Delete.php',
|
236 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\EntryVO' => __DIR__ . '/../..' . '/src/Databases/Events/EntryVO.php',
|
237 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Events\\Handler' => __DIR__ . '/../..' . '/src/Databases/Events/Handler.php',
|
308 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\ShieldOptions' => __DIR__ . '/../..' . '/src/Modules/Base/ShieldOptions.php',
|
309 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Base\\Strings' => __DIR__ . '/../..' . '/src/Modules/Base/Strings.php',
|
310 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\AdminNotices' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/AdminNotices.php',
|
311 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/AjaxHandler.php',
|
312 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Options' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Options.php',
|
313 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Bot' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Scan/Bot.php',
|
314 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Human' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Scan/Human.php',
|
315 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\IsEmailTrusted' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Scan/IsEmailTrusted.php',
|
316 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Scan\\Scanner' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Scan/Scanner.php',
|
317 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Strings' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Strings.php',
|
318 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\CommentsFilter\\Token\\Create' => __DIR__ . '/../..' . '/src/Modules/CommentsFilter/Token/Create.php',
|
319 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Email\\Options' => __DIR__ . '/../..' . '/src/Modules/Email/Options.php',
|
320 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Email\\Strings' => __DIR__ . '/../..' . '/src/Modules/Email/Strings.php',
|
321 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/Events/AjaxHandler.php',
|
322 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Charts\\BuildData' => __DIR__ . '/../..' . '/src/Modules/Events/Charts/BuildData.php',
|
323 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Charts\\ChartRequestVO' => __DIR__ . '/../..' . '/src/Modules/Events/Charts/ChartRequestVO.php',
|
324 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Consolidate\\ConsolidateAllEvents' => __DIR__ . '/../..' . '/src/Modules/Events/Consolidate/ConsolidateAllEvents.php',
|
325 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Options' => __DIR__ . '/../..' . '/src/Modules/Events/Options.php',
|
326 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Events\\Strings' => __DIR__ . '/../..' . '/src/Modules/Events/Strings.php',
|
327 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Firewall\\Options' => __DIR__ . '/../..' . '/src/Modules/Firewall/Options.php',
|
362 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackLoginInvalid' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackLoginInvalid.php',
|
363 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackUserAgent' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackUserAgent.php',
|
364 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackXmlRpc' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackXmlRpc.php',
|
365 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\LookupIpOnList' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/LookupIpOnList.php',
|
366 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Components\\UnblockIpByFlag' => __DIR__ . '/../..' . '/src/Modules/IPs/Components/UnblockIpByFlag.php',
|
367 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Options' => __DIR__ . '/../..' . '/src/Modules/IPs/Options.php',
|
368 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Strings' => __DIR__ . '/../..' . '/src/Modules/IPs/Strings.php',
|
386 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\AjaxHandler' => __DIR__ . '/../..' . '/src/Modules/Plugin/AjaxHandler.php',
|
387 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Components\\BadgeWidget' => __DIR__ . '/../..' . '/src/Modules/Plugin/Components/BadgeWidget.php',
|
388 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Components\\PluginBadge' => __DIR__ . '/../..' . '/src/Modules/Plugin/Components/PluginBadge.php',
|
389 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Components\\SiteGroundPluginCompatibility' => __DIR__ . '/../..' . '/src/Modules/Plugin/Components/SiteGroundPluginCompatibility.php',
|
390 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Options' => __DIR__ . '/../..' . '/src/Modules/Plugin/Options.php',
|
391 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\Plugin\\Strings' => __DIR__ . '/../..' . '/src/Modules/Plugin/Strings.php',
|
392 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\SecurityAdmin\\AdminNotices' => __DIR__ . '/../..' . '/src/Modules/SecurityAdmin/AdminNotices.php',
|
447 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Scan' => __DIR__ . '/../..' . '/src/Scans/Mal/Scan.php',
|
448 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Mal/ScanActionVO.php',
|
449 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\ScanFromFileMap' => __DIR__ . '/../..' . '/src/Scans/Mal/ScanFromFileMap.php',
|
450 |
+
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\FalsePositiveQuery' => __DIR__ . '/../..' . '/src/Scans/Mal/Utilities/FalsePositiveQuery.php',
|
451 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\FalsePositiveReporter' => __DIR__ . '/../..' . '/src/Scans/Mal/Utilities/FalsePositiveReporter.php',
|
452 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\Patterns' => __DIR__ . '/../..' . '/src/Scans/Mal/Utilities/Patterns.php',
|
453 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Mal\\Utilities\\Signatures' => __DIR__ . '/../..' . '/src/Scans/Mal/Utilities/Signatures.php',
|
536 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\AdminNotices\\NoticeVO' => __DIR__ . '/../..' . '/src/Utilities/AdminNotices/NoticeVO.php',
|
537 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\TestRequest' => __DIR__ . '/../..' . '/src/Utilities/ReCaptcha/TestRequest.php',
|
538 |
'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\ReCaptcha\\WordpressPost' => __DIR__ . '/../..' . '/src/Utilities/ReCaptcha/WordpressPost.php',
|
|
|
539 |
'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
|
540 |
'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
|
541 |
'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
|
558 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\PluginUpgrader' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/PluginUpgrader.php',
|
559 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\ThemeUpgrader' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/ThemeUpgrader.php',
|
560 |
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkin' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkin.php',
|
561 |
+
'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkinLegacy' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkinLegacy.php',
|
562 |
'FernleafSystems\\Wordpress\\Services\\Core\\Users' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Users.php',
|
563 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
|
564 |
'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
|
659 |
'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Versions' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Versions.php',
|
660 |
'Html2Text\\Html2Text' => __DIR__ . '/..' . '/soundasleep/html2text/src/Html2Text.php',
|
661 |
'Html2Text\\Html2TextException' => __DIR__ . '/..' . '/soundasleep/html2text/src/Html2TextException.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
662 |
'ICWP_WPSF_DataProcessor' => __DIR__ . '/../..' . '/../common/icwp-data.php',
|
|
|
663 |
'ICWP_WPSF_FeatureHandler_AdminAccessRestriction' => __DIR__ . '/../..' . '/../features/admin_access_restriction.php',
|
664 |
'ICWP_WPSF_FeatureHandler_AuditTrail' => __DIR__ . '/../..' . '/../features/audit_trail.php',
|
665 |
'ICWP_WPSF_FeatureHandler_Autoupdates' => __DIR__ . '/../..' . '/../features/autoupdates.php',
|
682 |
'ICWP_WPSF_FeatureHandler_Traffic' => __DIR__ . '/../..' . '/../features/traffic.php',
|
683 |
'ICWP_WPSF_FeatureHandler_UserManagement' => __DIR__ . '/../..' . '/../features/user_management.php',
|
684 |
'ICWP_WPSF_Foundation' => __DIR__ . '/../..' . '/../common/icwp-foundation.php',
|
|
|
|
|
685 |
'ICWP_WPSF_Processor_AdminAccessRestriction' => __DIR__ . '/../..' . '/../processors/admin_access_restriction.php',
|
686 |
'ICWP_WPSF_Processor_AdminAccess_Whitelabel' => __DIR__ . '/../..' . '/../processors/adminaccess_whitelabel.php',
|
687 |
'ICWP_WPSF_Processor_AuditTrail' => __DIR__ . '/../..' . '/../processors/audit_trail.php',
|
688 |
'ICWP_WPSF_Processor_AuditTrail_Auditor' => __DIR__ . '/../..' . '/../processors/audit_trail_auditor.php',
|
689 |
'ICWP_WPSF_Processor_AuditTrail_ChangeTracking' => __DIR__ . '/../..' . '/../processors/audit_trail_changetracking.php',
|
690 |
'ICWP_WPSF_Processor_Autoupdates' => __DIR__ . '/../..' . '/../processors/autoupdates.php',
|
|
|
|
|
|
|
691 |
'ICWP_WPSF_Processor_CommentsFilter' => __DIR__ . '/../..' . '/../processors/comments_filter.php',
|
692 |
'ICWP_WPSF_Processor_CommentsFilter_BotSpam' => __DIR__ . '/../..' . '/../processors/commentsfilter_botspam.php',
|
693 |
'ICWP_WPSF_Processor_CommentsFilter_GoogleRecaptcha' => __DIR__ . '/../..' . '/../processors/commentsfilter_googlerecaptcha.php',
|
736 |
'ICWP_WPSF_Processor_UserManagement_Passwords' => __DIR__ . '/../..' . '/../processors/usermanagement_passwords.php',
|
737 |
'ICWP_WPSF_Processor_UserManagement_Sessions' => __DIR__ . '/../..' . '/../processors/usermanagement_sessions.php',
|
738 |
'ICWP_WPSF_Processor_UserManagement_Suspend' => __DIR__ . '/../..' . '/../processors/usermanagement_suspend.php',
|
|
|
|
|
|
|
|
|
739 |
'ICWP_WPSF_ServiceProviders' => __DIR__ . '/../..' . '/../common/icwp-serviceproviders.php',
|
740 |
'ICWP_WPSF_Wizard_Base' => __DIR__ . '/../..' . '/../wizards/base.php',
|
741 |
'ICWP_WPSF_Wizard_BaseWpsf' => __DIR__ . '/../..' . '/../wizards/base_wpsf.php',
|
742 |
'ICWP_WPSF_Wizard_LoginProtect' => __DIR__ . '/../..' . '/../wizards/login_protect.php',
|
743 |
'ICWP_WPSF_Wizard_Plugin' => __DIR__ . '/../..' . '/../wizards/plugin.php',
|
744 |
'ICWP_WPSF_WpAdminNotices' => __DIR__ . '/../..' . '/../common/wp-admin-notices.php',
|
|
|
745 |
'ICWP_WPSF_WpCron' => __DIR__ . '/../..' . '/../common/icwp-wpcron.php',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
746 |
'ICWP_WPSF_WpWidget' => __DIR__ . '/../..' . '/../common/wp-widget.php',
|
747 |
'JsonSerializable' => __DIR__ . '/..' . '/nesbot/carbon/src/JsonSerializable.php',
|
748 |
'LZCompressor\\LZContext' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php',
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Plugins.php
CHANGED
@@ -78,46 +78,27 @@ class Plugins {
|
|
78 |
/**
|
79 |
* @param string $sUrlToInstall
|
80 |
* @param bool $bOverwrite
|
81 |
-
* @param bool $bMaintenanceMode
|
82 |
* @return array
|
83 |
*/
|
84 |
-
public function install( $sUrlToInstall, $bOverwrite = true
|
85 |
|
86 |
-
$
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
$oUpgrader->setOverwriteMode( $bOverwrite );
|
95 |
-
if ( $bMaintenanceMode ) {
|
96 |
-
$oUpgrader->maintenance_mode( true );
|
97 |
-
}
|
98 |
-
|
99 |
-
ob_start();
|
100 |
-
$sInstallResult = $oUpgrader->install( $sUrlToInstall );
|
101 |
-
ob_end_clean();
|
102 |
|
103 |
-
|
104 |
-
$oUpgrader->maintenance_mode( false );
|
105 |
-
}
|
106 |
-
|
107 |
-
$aErrors = $oUpgraderSkin->getErrors();
|
108 |
-
if ( isset( $aErrors[ 0 ] ) && is_wp_error( $aErrors[ 0 ] ) ) {
|
109 |
-
/** @var \WP_Error $oErr */
|
110 |
-
$oErr = $aErrors[ 0 ];
|
111 |
-
$aResult[ 'successful' ] = false;
|
112 |
-
$aResult[ 'errors' ] = $oErr->get_error_messages();
|
113 |
-
}
|
114 |
-
else {
|
115 |
-
$aResult[ 'plugin_info' ] = $oUpgrader->plugin_info();
|
116 |
-
}
|
117 |
|
118 |
-
|
119 |
-
|
120 |
-
|
|
|
|
|
|
|
121 |
}
|
122 |
|
123 |
/**
|
@@ -135,7 +116,7 @@ class Plugins {
|
|
135 |
] );
|
136 |
|
137 |
if ( !is_wp_error( $api ) ) {
|
138 |
-
return $this->install( $api->download_link, true
|
139 |
}
|
140 |
return false;
|
141 |
}
|
@@ -185,29 +166,17 @@ class Plugins {
|
|
185 |
*/
|
186 |
public function update( $sFile ) {
|
187 |
|
188 |
-
$
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
$oUpgraderSkin = new Upgrades\BulkPluginUpgraderSkin();
|
194 |
-
ob_start();
|
195 |
-
( new Upgrades\PluginUpgrader( $oUpgraderSkin ) )->bulk_upgrade( [ $sFile ] );
|
196 |
-
if ( ob_get_contents() ) {
|
197 |
-
// for some reason this errors with no buffer present
|
198 |
-
ob_end_clean();
|
199 |
-
}
|
200 |
-
|
201 |
-
$aErrors = $oUpgraderSkin->getErrors();
|
202 |
-
if ( isset( $aErrors[ 0 ] ) && is_wp_error( $aErrors[ 0 ] ) ) {
|
203 |
-
/** @var \WP_Error $oErr */
|
204 |
-
$oErr = $aErrors[ 0 ];
|
205 |
-
$aResult[ 'successful' ] = 0;
|
206 |
-
$aResult[ 'errors' ] = $oErr->get_error_messages();
|
207 |
-
}
|
208 |
-
$aResult[ 'feedback' ] = $oUpgraderSkin->getFeedback();
|
209 |
|
210 |
-
return
|
|
|
|
|
|
|
|
|
211 |
}
|
212 |
|
213 |
/**
|
78 |
/**
|
79 |
* @param string $sUrlToInstall
|
80 |
* @param bool $bOverwrite
|
|
|
81 |
* @return array
|
82 |
*/
|
83 |
+
public function install( $sUrlToInstall, $bOverwrite = true ) {
|
84 |
|
85 |
+
$oSkin = Services::WpGeneral()->getWordpressIsAtLeastVersion( '5.3' ) ?
|
86 |
+
new Upgrades\UpgraderSkin()
|
87 |
+
: new Upgrades\UpgraderSkinLegacy();
|
88 |
+
$oUpgrader = new \Plugin_Upgrader( $oSkin );
|
89 |
+
add_filter( 'upgrader_package_options', function ( $aOptions ) use ( $bOverwrite ) {
|
90 |
+
$aOptions[ 'clear_destination' ] = $bOverwrite;
|
91 |
+
return $aOptions;
|
92 |
+
} );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
|
94 |
+
$mResult = $oUpgrader->install( $sUrlToInstall );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
|
96 |
+
return [
|
97 |
+
'successful' => $mResult === true,
|
98 |
+
'feedback' => $oSkin->getIcwpFeedback(),
|
99 |
+
'plugin_info' => $oUpgrader->plugin_info(),
|
100 |
+
'errors' => is_wp_error( $mResult ) ? $mResult->get_error_messages() : [ 'no errors' ]
|
101 |
+
];
|
102 |
}
|
103 |
|
104 |
/**
|
116 |
] );
|
117 |
|
118 |
if ( !is_wp_error( $api ) ) {
|
119 |
+
return $this->install( $api->download_link, true );
|
120 |
}
|
121 |
return false;
|
122 |
}
|
166 |
*/
|
167 |
public function update( $sFile ) {
|
168 |
|
169 |
+
$oSkin = Services::WpGeneral()->getWordpressIsAtLeastVersion( '5.3' ) ?
|
170 |
+
new Upgrades\UpgraderSkin()
|
171 |
+
: new Upgrades\UpgraderSkinLegacy();
|
172 |
+
$oUpgrader = new \Plugin_Upgrader( $oSkin );
|
173 |
+
$mResult = $oUpgrader->upgrade( $sFile );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
|
175 |
+
return [
|
176 |
+
'successful' => $mResult === true,
|
177 |
+
'feedback' => $oSkin->getIcwpFeedback(),
|
178 |
+
'errors' => is_wp_error( $mResult ) ? $mResult->get_error_messages() : [ 'no errors' ]
|
179 |
+
];
|
180 |
}
|
181 |
|
182 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Themes.php
CHANGED
@@ -65,7 +65,7 @@ class Themes {
|
|
65 |
->setWorkingSlug( $sSlug )
|
66 |
->getInfo();
|
67 |
if ( !empty( $oTheme->download_link ) ) {
|
68 |
-
$bSuccess = $this->install( $oTheme->download_link, true
|
69 |
}
|
70 |
}
|
71 |
catch ( \Exception $oE ) {
|
@@ -76,45 +76,27 @@ class Themes {
|
|
76 |
/**
|
77 |
* @param string $sUrlToInstall
|
78 |
* @param bool $bOverwrite
|
79 |
-
* @param bool $bMaintenanceMode
|
80 |
* @return array
|
81 |
*/
|
82 |
-
public function install( $sUrlToInstall, $bOverwrite = true
|
83 |
-
|
84 |
-
$
|
85 |
-
|
86 |
-
|
87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
];
|
89 |
-
|
90 |
-
$oUpgraderSkin = new Upgrades\UpgraderSkin();
|
91 |
-
$oUpgrader = new Upgrades\ThemeUpgrader( $oUpgraderSkin );
|
92 |
-
$oUpgrader->setOverwriteMode( $bOverwrite );
|
93 |
-
if ( $bMaintenanceMode ) {
|
94 |
-
$oUpgrader->maintenance_mode( true );
|
95 |
-
}
|
96 |
-
|
97 |
-
ob_start();
|
98 |
-
$oUpgrader->install( $sUrlToInstall );
|
99 |
-
ob_end_clean();
|
100 |
-
|
101 |
-
if ( $bMaintenanceMode ) {
|
102 |
-
$oUpgrader->maintenance_mode( false );
|
103 |
-
}
|
104 |
-
|
105 |
-
$aErrors = $oUpgraderSkin->getErrors();
|
106 |
-
if ( isset( $aErrors[ 0 ] ) && is_wp_error( $aErrors[ 0 ] ) ) {
|
107 |
-
/** @var \WP_Error $oErr */
|
108 |
-
$oErr = $aErrors[ 0 ];
|
109 |
-
$aResult[ 'successful' ] = false;
|
110 |
-
$aResult[ 'errors' ] = $oErr->get_error_messages();
|
111 |
-
}
|
112 |
-
else {
|
113 |
-
$aResult[ 'theme_info' ] = $oUpgrader->theme_info();
|
114 |
-
}
|
115 |
-
|
116 |
-
$aResult[ 'feedback' ] = $oUpgraderSkin->getFeedback();
|
117 |
-
return $aResult;
|
118 |
}
|
119 |
|
120 |
/**
|
@@ -159,29 +141,17 @@ class Themes {
|
|
159 |
*/
|
160 |
public function update( $sFile ) {
|
161 |
|
162 |
-
$
|
163 |
-
|
164 |
-
|
165 |
-
|
|
|
166 |
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
// for some reason this errors with no buffer present
|
173 |
-
ob_end_clean();
|
174 |
-
}
|
175 |
-
|
176 |
-
$aErrors = $oUpgraderSkin->getErrors();
|
177 |
-
if ( isset( $aErrors[ 0 ] ) && is_wp_error( $aErrors[ 0 ] ) ) {
|
178 |
-
/** @var \WP_Error $oErr */
|
179 |
-
$oErr = $aErrors[ 0 ];
|
180 |
-
$aResult[ 'successful' ] = 0;
|
181 |
-
$aResult[ 'errors' ] = $oErr->get_error_messages();
|
182 |
-
}
|
183 |
-
$aResult[ 'feedback' ] = $oUpgraderSkin->getFeedback();
|
184 |
-
return $aResult;
|
185 |
}
|
186 |
|
187 |
/**
|
65 |
->setWorkingSlug( $sSlug )
|
66 |
->getInfo();
|
67 |
if ( !empty( $oTheme->download_link ) ) {
|
68 |
+
$bSuccess = $this->install( $oTheme->download_link, true )[ 'successful' ];
|
69 |
}
|
70 |
}
|
71 |
catch ( \Exception $oE ) {
|
76 |
/**
|
77 |
* @param string $sUrlToInstall
|
78 |
* @param bool $bOverwrite
|
|
|
79 |
* @return array
|
80 |
*/
|
81 |
+
public function install( $sUrlToInstall, $bOverwrite = true ) {
|
82 |
+
|
83 |
+
$oSkin = Services::WpGeneral()->getWordpressIsAtLeastVersion( '5.3' ) ?
|
84 |
+
new Upgrades\UpgraderSkin()
|
85 |
+
: new Upgrades\UpgraderSkinLegacy();
|
86 |
+
$oUpgrader = new \Theme_Upgrader( $oSkin );
|
87 |
+
add_filter( 'upgrader_package_options', function ( $aOptions ) use ( $bOverwrite ) {
|
88 |
+
$aOptions[ 'clear_destination' ] = $bOverwrite;
|
89 |
+
return $aOptions;
|
90 |
+
} );
|
91 |
+
|
92 |
+
$mResult = $oUpgrader->install( $sUrlToInstall );
|
93 |
+
|
94 |
+
return [
|
95 |
+
'successful' => $mResult === true,
|
96 |
+
'feedback' => $oSkin->getIcwpFeedback(),
|
97 |
+
'theme_info' => $oUpgrader->theme_info(),
|
98 |
+
'errors' => is_wp_error( $mResult ) ? $mResult->get_error_messages() : [ 'no errors' ]
|
99 |
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
}
|
101 |
|
102 |
/**
|
141 |
*/
|
142 |
public function update( $sFile ) {
|
143 |
|
144 |
+
$oSkin = Services::WpGeneral()->getWordpressIsAtLeastVersion( '5.3' ) ?
|
145 |
+
new Upgrades\UpgraderSkin()
|
146 |
+
: new Upgrades\UpgraderSkinLegacy();
|
147 |
+
$oUpgrader = new \Theme_Upgrader( $oSkin );
|
148 |
+
$mResult = $oUpgrader->upgrade( $sFile );
|
149 |
|
150 |
+
return [
|
151 |
+
'successful' => $mResult === true,
|
152 |
+
'feedback' => $oSkin->getIcwpFeedback(),
|
153 |
+
'errors' => is_wp_error( $mResult ) ? $mResult->get_error_messages() : [ 'no errors' ]
|
154 |
+
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
}
|
156 |
|
157 |
/**
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkin.php
CHANGED
@@ -10,35 +10,29 @@ class UpgraderSkin extends \WP_Upgrader_Skin {
|
|
10 |
/**
|
11 |
* @var array
|
12 |
*/
|
13 |
-
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var array
|
17 |
-
*/
|
18 |
-
public $aFeedback;
|
19 |
|
20 |
public function __construct() {
|
21 |
parent::__construct();
|
22 |
-
$this->done_header = true;
|
|
|
23 |
}
|
24 |
|
25 |
/**
|
26 |
-
* @
|
27 |
*/
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
|
32 |
/**
|
33 |
-
* @return
|
34 |
*/
|
35 |
-
public function
|
36 |
return is_array( $this->aFeedback ) ? $this->aFeedback : [];
|
37 |
}
|
38 |
-
|
39 |
-
function error( $errors ) {
|
40 |
-
}
|
41 |
-
|
42 |
-
function feedback( $string ) {
|
43 |
-
}
|
44 |
}
|
10 |
/**
|
11 |
* @var array
|
12 |
*/
|
13 |
+
private $aFeedback = [];
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
public function __construct() {
|
16 |
parent::__construct();
|
17 |
+
$this->done_header = true; // prevents text output
|
18 |
+
$this->done_footer = true; // prevents text output
|
19 |
}
|
20 |
|
21 |
/**
|
22 |
+
* @inheritDoc
|
23 |
*/
|
24 |
+
function feedback( $string, ...$args ) {
|
25 |
+
// overriding this prevent automatic echo of feedback
|
26 |
+
if ( empty( $this->aFeedback ) ) {
|
27 |
+
$this->aFeedback = [];
|
28 |
+
}
|
29 |
+
$this->aFeedback[] = $string;
|
30 |
}
|
31 |
|
32 |
/**
|
33 |
+
* @return string[]
|
34 |
*/
|
35 |
+
public function getIcwpFeedback() {
|
36 |
return is_array( $this->aFeedback ) ? $this->aFeedback : [];
|
37 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkinLegacy.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace FernleafSystems\Wordpress\Services\Core\Upgrades;
|
4 |
+
|
5 |
+
require_once( ABSPATH.'wp-admin/includes/upgrade.php' );
|
6 |
+
require_once( ABSPATH.'wp-admin/includes/class-wp-upgrader.php' );
|
7 |
+
|
8 |
+
class UpgraderSkinLegacy extends \WP_Upgrader_Skin {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var array
|
12 |
+
*/
|
13 |
+
private $aFeedback = [];
|
14 |
+
|
15 |
+
public function __construct() {
|
16 |
+
parent::__construct();
|
17 |
+
$this->done_header = true; // prevents text output
|
18 |
+
$this->done_footer = true; // prevents text output
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @inheritDoc
|
23 |
+
*/
|
24 |
+
function feedback( $string ) {
|
25 |
+
// overriding this prevent automatic echo of feedback
|
26 |
+
if ( empty( $this->aFeedback ) ) {
|
27 |
+
$this->aFeedback = [];
|
28 |
+
}
|
29 |
+
$this->aFeedback[] = $string;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @return string[]
|
34 |
+
*/
|
35 |
+
public function getIcwpFeedback() {
|
36 |
+
return is_array( $this->aFeedback ) ? $this->aFeedback : [];
|
37 |
+
}
|
38 |
+
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php
CHANGED
@@ -96,6 +96,13 @@ class WpPluginVo {
|
|
96 |
return $mVal;
|
97 |
}
|
98 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
/**
|
100 |
* @return bool
|
101 |
*/
|
96 |
return $mVal;
|
97 |
}
|
98 |
|
99 |
+
/**
|
100 |
+
* @return string
|
101 |
+
*/
|
102 |
+
public function getInstallDir() {
|
103 |
+
return wp_normalize_path( trailingslashit( dirname( path_join( WP_PLUGIN_DIR, $this->file ) ) ) );
|
104 |
+
}
|
105 |
+
|
106 |
/**
|
107 |
* @return bool
|
108 |
*/
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php
CHANGED
@@ -88,6 +88,13 @@ class WpThemeVo {
|
|
88 |
return $mVal;
|
89 |
}
|
90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
/**
|
92 |
* @return bool
|
93 |
*/
|
88 |
return $mVal;
|
89 |
}
|
90 |
|
91 |
+
/**
|
92 |
+
* @return string
|
93 |
+
*/
|
94 |
+
public function getInstallDir() {
|
95 |
+
return wp_normalize_path( trailingslashit( $this->wp_theme->get_stylesheet_directory() ) );
|
96 |
+
}
|
97 |
+
|
98 |
/**
|
99 |
* @return bool
|
100 |
*/
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/DataManipulation.php
CHANGED
@@ -16,6 +16,14 @@ class DataManipulation {
|
|
16 |
return str_replace( [ "\r\n", "\r" ], "\n", file_get_contents( $sFullFilePath ) );
|
17 |
}
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
/**
|
20 |
* @param array $aArrayToConvert
|
21 |
* @return string
|
16 |
return str_replace( [ "\r\n", "\r" ], "\n", file_get_contents( $sFullFilePath ) );
|
17 |
}
|
18 |
|
19 |
+
/**
|
20 |
+
* @param string $sFullFilePath
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
public function convertLineEndingsLinuxToDos( $sFullFilePath ) {
|
24 |
+
return str_replace( "\n", "\r\n", $this->convertLineEndingsDosToLinux( $sFullFilePath ) );
|
25 |
+
}
|
26 |
+
|
27 |
/**
|
28 |
* @param array $aArrayToConvert
|
29 |
* @return string
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/Compare/CompareHash.php
CHANGED
@@ -13,13 +13,17 @@ class CompareHash {
|
|
13 |
* @throws \InvalidArgumentException
|
14 |
*/
|
15 |
public function isEqualFileMd5( $sPath, $sHashToCompare ) {
|
16 |
-
|
17 |
if ( !Services::WpFs()->isFile( $sPath ) ) {
|
18 |
throw new \InvalidArgumentException( 'File does not exist on disk to compare' );
|
19 |
}
|
|
|
|
|
|
|
20 |
|
|
|
21 |
return hash_equals( md5_file( $sPath ), $sHashToCompare )
|
22 |
-
|| hash_equals( md5(
|
|
|
23 |
}
|
24 |
|
25 |
/**
|
@@ -29,13 +33,17 @@ class CompareHash {
|
|
29 |
* @throws \InvalidArgumentException
|
30 |
*/
|
31 |
public function isEqualFileSha1( $sPath, $sHashToCompare ) {
|
32 |
-
|
33 |
if ( !Services::WpFs()->isFile( $sPath ) ) {
|
34 |
throw new \InvalidArgumentException( 'File does not exist on disk to compare' );
|
35 |
}
|
|
|
|
|
|
|
36 |
|
|
|
37 |
return hash_equals( sha1_file( $sPath ), $sHashToCompare )
|
38 |
-
|| hash_equals( sha1(
|
|
|
39 |
}
|
40 |
|
41 |
/**
|
@@ -50,10 +58,16 @@ class CompareHash {
|
|
50 |
throw new \InvalidArgumentException( 'File does not exist on disk to compare' );
|
51 |
}
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
58 |
|
59 |
/**
|
@@ -68,9 +82,15 @@ class CompareHash {
|
|
68 |
throw new \InvalidArgumentException( 'File does not exist on disk to compare' );
|
69 |
}
|
70 |
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
}
|
76 |
}
|
13 |
* @throws \InvalidArgumentException
|
14 |
*/
|
15 |
public function isEqualFileMd5( $sPath, $sHashToCompare ) {
|
|
|
16 |
if ( !Services::WpFs()->isFile( $sPath ) ) {
|
17 |
throw new \InvalidArgumentException( 'File does not exist on disk to compare' );
|
18 |
}
|
19 |
+
if ( !is_string( $sHashToCompare ) ) {
|
20 |
+
throw new \InvalidArgumentException( 'Provided user hash was not a string' );
|
21 |
+
}
|
22 |
|
23 |
+
$oDataManip = Services::DataManipulation();
|
24 |
return hash_equals( md5_file( $sPath ), $sHashToCompare )
|
25 |
+
|| hash_equals( md5( $oDataManip->convertLineEndingsDosToLinux( $sPath ) ), $sHashToCompare )
|
26 |
+
|| hash_equals( md5( $oDataManip->convertLineEndingsLinuxToDos( $sPath ) ), $sHashToCompare );
|
27 |
}
|
28 |
|
29 |
/**
|
33 |
* @throws \InvalidArgumentException
|
34 |
*/
|
35 |
public function isEqualFileSha1( $sPath, $sHashToCompare ) {
|
|
|
36 |
if ( !Services::WpFs()->isFile( $sPath ) ) {
|
37 |
throw new \InvalidArgumentException( 'File does not exist on disk to compare' );
|
38 |
}
|
39 |
+
if ( !is_string( $sHashToCompare ) ) {
|
40 |
+
throw new \InvalidArgumentException( 'Provided user hash was not a string' );
|
41 |
+
}
|
42 |
|
43 |
+
$oDataManip = Services::DataManipulation();
|
44 |
return hash_equals( sha1_file( $sPath ), $sHashToCompare )
|
45 |
+
|| hash_equals( sha1( $oDataManip->convertLineEndingsDosToLinux( $sPath ) ), $sHashToCompare )
|
46 |
+
|| hash_equals( sha1( $oDataManip->convertLineEndingsLinuxToDos( $sPath ) ), $sHashToCompare );
|
47 |
}
|
48 |
|
49 |
/**
|
58 |
throw new \InvalidArgumentException( 'File does not exist on disk to compare' );
|
59 |
}
|
60 |
|
61 |
+
$oDataManip = Services::DataManipulation();
|
62 |
+
return
|
63 |
+
$this->isEqualFileMd5(
|
64 |
+
$sPath1,
|
65 |
+
md5( $oDataManip->convertLineEndingsDosToLinux( $sPath2 ) )
|
66 |
+
)
|
67 |
+
|| $this->isEqualFileMd5(
|
68 |
+
$sPath1,
|
69 |
+
md5( $oDataManip->convertLineEndingsLinuxToDos( $sPath2 ) )
|
70 |
+
);
|
71 |
}
|
72 |
|
73 |
/**
|
82 |
throw new \InvalidArgumentException( 'File does not exist on disk to compare' );
|
83 |
}
|
84 |
|
85 |
+
$oDataManip = Services::DataManipulation();
|
86 |
+
return
|
87 |
+
$this->isEqualFileSha1(
|
88 |
+
$sPath1,
|
89 |
+
sha1( $oDataManip->convertLineEndingsDosToLinux( $sPath2 ) )
|
90 |
+
)
|
91 |
+
|| $this->isEqualFileSha1(
|
92 |
+
$sPath1,
|
93 |
+
sha1( $oDataManip->convertLineEndingsLinuxToDos( $sPath2 ) )
|
94 |
+
);
|
95 |
}
|
96 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/ExtractLinesFromFile.php
CHANGED
@@ -2,8 +2,6 @@
|
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Services\Utilities\File;
|
4 |
|
5 |
-
use FernleafSystems\Wordpress\Services\Services;
|
6 |
-
|
7 |
/**
|
8 |
* Class ExtractLineFromFile
|
9 |
* @package FernleafSystems\Wordpress\Services\Utilities\File
|
@@ -13,7 +11,7 @@ class ExtractLinesFromFile {
|
|
13 |
/**
|
14 |
* @param string $sPath
|
15 |
* @param int[] $aLines
|
16 |
-
* @return string
|
17 |
* @throws \Exception
|
18 |
*/
|
19 |
public function run( $sPath, $aLines ) {
|
2 |
|
3 |
namespace FernleafSystems\Wordpress\Services\Utilities\File;
|
4 |
|
|
|
|
|
5 |
/**
|
6 |
* Class ExtractLineFromFile
|
7 |
* @package FernleafSystems\Wordpress\Services\Utilities\File
|
11 |
/**
|
12 |
* @param string $sPath
|
13 |
* @param int[] $aLines
|
14 |
+
* @return string[]
|
15 |
* @throws \Exception
|
16 |
*/
|
17 |
public function run( $sPath, $aLines ) {
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php
CHANGED
@@ -21,6 +21,16 @@ abstract class ApiBase {
|
|
21 |
*/
|
22 |
private $oReq;
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
/**
|
25 |
* @return string
|
26 |
*/
|
@@ -88,8 +98,23 @@ abstract class ApiBase {
|
|
88 |
* @return string
|
89 |
*/
|
90 |
protected function fireRequest_GET() {
|
|
|
|
|
91 |
$sUrl = add_query_arg( array_map( 'strtolower', $this->getQueryData() ), $this->getApiUrl() );
|
92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
}
|
94 |
|
95 |
/**
|
@@ -104,4 +129,20 @@ abstract class ApiBase {
|
|
104 |
);
|
105 |
return $oHttp->isSuccess() ? $oHttp->lastResponse->body : null;
|
106 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
}
|
21 |
*/
|
22 |
private $oReq;
|
23 |
|
24 |
+
/**
|
25 |
+
* @var bool
|
26 |
+
*/
|
27 |
+
private $bUseQueryCache = false;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @var array
|
31 |
+
*/
|
32 |
+
private static $aQueryCache = [];
|
33 |
+
|
34 |
/**
|
35 |
* @return string
|
36 |
*/
|
98 |
* @return string
|
99 |
*/
|
100 |
protected function fireRequest_GET() {
|
101 |
+
$sResponse = null;
|
102 |
+
|
103 |
$sUrl = add_query_arg( array_map( 'strtolower', $this->getQueryData() ), $this->getApiUrl() );
|
104 |
+
$sSig = md5( $sUrl );
|
105 |
+
|
106 |
+
if ( $this->isUseQueryCache() && isset( self::$aQueryCache[ $sSig ] ) ) {
|
107 |
+
$sResponse = self::$aQueryCache[ $sSig ];
|
108 |
+
}
|
109 |
+
|
110 |
+
if ( is_null( $sResponse ) ) {
|
111 |
+
$sResponse = ( new HttpRequest() )->getContent( $sUrl );
|
112 |
+
if ( $this->isUseQueryCache() ) {
|
113 |
+
self::$aQueryCache[ $sSig ] = $sResponse;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
return $sResponse;
|
118 |
}
|
119 |
|
120 |
/**
|
129 |
);
|
130 |
return $oHttp->isSuccess() ? $oHttp->lastResponse->body : null;
|
131 |
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* @return bool
|
135 |
+
*/
|
136 |
+
public function isUseQueryCache() {
|
137 |
+
return (bool)$this->bUseQueryCache;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @param bool $bUseQueryCache
|
142 |
+
* @return $this
|
143 |
+
*/
|
144 |
+
public function setUseQueryCache( $bUseQueryCache ) {
|
145 |
+
$this->bUseQueryCache = $bUseQueryCache;
|
146 |
+
return $this;
|
147 |
+
}
|
148 |
}
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ClassicPress.php
CHANGED
@@ -18,6 +18,7 @@ class ClassicPress extends Base {
|
|
18 |
* @return string[]|null
|
19 |
*/
|
20 |
public function getHashes( $sVersion, $sHashAlgo = null ) {
|
|
|
21 |
$oReq = $this->getRequestVO();
|
22 |
$oReq->version = $sVersion;
|
23 |
$oReq->hash = $sHashAlgo;
|
18 |
* @return string[]|null
|
19 |
*/
|
20 |
public function getHashes( $sVersion, $sHashAlgo = null ) {
|
21 |
+
/** @var RequestVO $oReq */
|
22 |
$oReq = $this->getRequestVO();
|
23 |
$oReq->version = $sVersion;
|
24 |
$oReq->hash = $sHashAlgo;
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/PluginThemeBase.php
CHANGED
@@ -15,6 +15,7 @@ abstract class PluginThemeBase extends Base {
|
|
15 |
* @return array|null
|
16 |
*/
|
17 |
public function getHashes( $sSlug, $sVersion, $sHashAlgo = null ) {
|
|
|
18 |
$oReq = $this->getRequestVO();
|
19 |
$oReq->version = $sVersion;
|
20 |
$oReq->hash = $sHashAlgo;
|
15 |
* @return array|null
|
16 |
*/
|
17 |
public function getHashes( $sSlug, $sVersion, $sHashAlgo = null ) {
|
18 |
+
/** @var RequestVO $oReq */
|
19 |
$oReq = $this->getRequestVO();
|
20 |
$oReq->version = $sVersion;
|
21 |
$oReq->hash = $sHashAlgo;
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/WordPress.php
CHANGED
@@ -19,6 +19,7 @@ class WordPress extends Base {
|
|
19 |
* @return string[]|null
|
20 |
*/
|
21 |
public function getHashes( $sVersion, $sLocale = null, $sHashAlgo = null ) {
|
|
|
22 |
$oReq = $this->getRequestVO();
|
23 |
$oReq->version = $sVersion;
|
24 |
$oReq->hash = $sHashAlgo;
|
19 |
* @return string[]|null
|
20 |
*/
|
21 |
public function getHashes( $sVersion, $sLocale = null, $sHashAlgo = null ) {
|
22 |
+
/** @var RequestVO $oReq */
|
23 |
$oReq = $this->getRequestVO();
|
24 |
$oReq->version = $sVersion;
|
25 |
$oReq->hash = $sHashAlgo;
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Base.php
CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
|
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
-
const API_ENDPOINT = 'malware/fpconfidence';
|
10 |
|
11 |
/**
|
12 |
* @return RequestVO
|
6 |
|
7 |
abstract class Base extends WpHashes\ApiBase {
|
8 |
|
9 |
+
const API_ENDPOINT = 'malware/fpconfidence/';
|
10 |
|
11 |
/**
|
12 |
* @return RequestVO
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/RequestVO.php
CHANGED
@@ -7,6 +7,7 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations;
|
|
7 |
/**
|
8 |
* Class RequestVO
|
9 |
* @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Malware\Confidence
|
|
|
10 |
* @property string $file
|
11 |
* @property string $hash
|
12 |
* @property string $algo
|
7 |
/**
|
8 |
* Class RequestVO
|
9 |
* @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Malware\Confidence
|
10 |
+
* @property string $type
|
11 |
* @property string $file
|
12 |
* @property string $hash
|
13 |
* @property string $algo
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Retrieve.php
CHANGED
@@ -10,7 +10,23 @@ use FernleafSystems\Wordpress\Services\Services;
|
|
10 |
*/
|
11 |
class Retrieve extends Base {
|
12 |
|
13 |
-
const RESPONSE_DATA_KEY = '
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
/**
|
16 |
* @param string $sFullPath
|
@@ -20,6 +36,7 @@ class Retrieve extends Base {
|
|
20 |
public function retrieveForFile( $sFullPath, $sAlgo = 'sha1' ) {
|
21 |
/** @var RequestVO $oReq */
|
22 |
$oReq = $this->getRequestVO();
|
|
|
23 |
$oReq->file = basename( $sFullPath );
|
24 |
$oReq->hash = hash( $sAlgo, Services::DataManipulation()->convertLineEndingsDosToLinux( $sFullPath ) );
|
25 |
$oReq->algo = $sAlgo;
|
@@ -35,6 +52,7 @@ class Retrieve extends Base {
|
|
35 |
public function retrieveForFileLine( $sFullPath, $sLine, $sAlgo = 'sha1' ) {
|
36 |
/** @var RequestVO $oReq */
|
37 |
$oReq = $this->getRequestVO();
|
|
|
38 |
$oReq->file = basename( $sFullPath );
|
39 |
$oReq->hash = hash( $sAlgo, trim( $sLine ) );
|
40 |
$oReq->algo = $sAlgo;
|
10 |
*/
|
11 |
class Retrieve extends Base {
|
12 |
|
13 |
+
const RESPONSE_DATA_KEY = 'confidence';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @return string
|
17 |
+
*/
|
18 |
+
protected function getApiUrl() {
|
19 |
+
$aData = array_filter( array_merge(
|
20 |
+
[
|
21 |
+
'type' => false,
|
22 |
+
'file' => false,
|
23 |
+
'hash' => false,
|
24 |
+
'algo' => false,
|
25 |
+
],
|
26 |
+
$this->getRequestVO()->getRawDataAsArray()
|
27 |
+
) );
|
28 |
+
return sprintf( '%s%s', parent::getApiUrl(), implode( '/', $aData ) );
|
29 |
+
}
|
30 |
|
31 |
/**
|
32 |
* @param string $sFullPath
|
36 |
public function retrieveForFile( $sFullPath, $sAlgo = 'sha1' ) {
|
37 |
/** @var RequestVO $oReq */
|
38 |
$oReq = $this->getRequestVO();
|
39 |
+
$oReq->type = 'file';
|
40 |
$oReq->file = basename( $sFullPath );
|
41 |
$oReq->hash = hash( $sAlgo, Services::DataManipulation()->convertLineEndingsDosToLinux( $sFullPath ) );
|
42 |
$oReq->algo = $sAlgo;
|
52 |
public function retrieveForFileLine( $sFullPath, $sLine, $sAlgo = 'sha1' ) {
|
53 |
/** @var RequestVO $oReq */
|
54 |
$oReq = $this->getRequestVO();
|
55 |
+
$oReq->type = 'line';
|
56 |
$oReq->file = basename( $sFullPath );
|
57 |
$oReq->hash = hash( $sAlgo, trim( $sLine ) );
|
58 |
$oReq->algo = $sAlgo;
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php
CHANGED
@@ -141,7 +141,15 @@ class IpUtils {
|
|
141 |
}
|
142 |
|
143 |
/**
|
144 |
-
* @param
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
* @return int|string|bool - visitor IP Address as IP2Long
|
146 |
*/
|
147 |
public function getRequestIp( $bAsHuman = true ) {
|
@@ -184,7 +192,7 @@ class IpUtils {
|
|
184 |
/**
|
185 |
* @param string $sIp
|
186 |
* @param bool $flags
|
187 |
-
* @return
|
188 |
*/
|
189 |
public function isValidIp( $sIp, $flags = null ) {
|
190 |
return filter_var( trim( $sIp ), FILTER_VALIDATE_IP, $flags );
|
@@ -192,7 +200,7 @@ class IpUtils {
|
|
192 |
|
193 |
/**
|
194 |
* @param string $sIp
|
195 |
-
* @return
|
196 |
*/
|
197 |
public function isValidIp4Range( $sIp ) {
|
198 |
$bIsRange = false;
|
@@ -205,7 +213,20 @@ class IpUtils {
|
|
205 |
|
206 |
/**
|
207 |
* @param string $sIp
|
208 |
-
* @return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
*/
|
210 |
public function isValidIpOrRange( $sIp ) {
|
211 |
return $this->isValidIp_PublicRemote( $sIp ) || $this->isValidIpRange( $sIp );
|
@@ -214,7 +235,7 @@ class IpUtils {
|
|
214 |
/**
|
215 |
* Assumes a valid IPv4 address is provided as we're only testing for a whether the IP is public or not.
|
216 |
* @param string $sIp
|
217 |
-
* @return
|
218 |
*/
|
219 |
public function isValidIp_PublicRange( $sIp ) {
|
220 |
return $this->isValidIp( $sIp, FILTER_FLAG_NO_PRIV_RANGE );
|
@@ -222,7 +243,7 @@ class IpUtils {
|
|
222 |
|
223 |
/**
|
224 |
* @param string $sIp
|
225 |
-
* @return
|
226 |
*/
|
227 |
public function isValidIp_PublicRemote( $sIp ) {
|
228 |
return $this->isValidIp( $sIp, ( FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) );
|
@@ -230,14 +251,10 @@ class IpUtils {
|
|
230 |
|
231 |
/**
|
232 |
* @param string $sIp
|
233 |
-
* @return
|
234 |
*/
|
235 |
public function isValidIpRange( $sIp ) {
|
236 |
-
|
237 |
-
return false;
|
238 |
-
}
|
239 |
-
$aParts = explode( '/', $sIp );
|
240 |
-
return filter_var( $aParts[ 0 ], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) && ( 0 < $aParts[ 1 ] && $aParts[ 1 ] < 33 );
|
241 |
}
|
242 |
|
243 |
/**
|
141 |
}
|
142 |
|
143 |
/**
|
144 |
+
* @param string $sIp
|
145 |
+
* @return string
|
146 |
+
*/
|
147 |
+
public function getIpInfo( $sIp ) {
|
148 |
+
return sprintf( 'https://redirect.li/map/?ip=%s', $sIp );
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* @param bool $bAsHuman
|
153 |
* @return int|string|bool - visitor IP Address as IP2Long
|
154 |
*/
|
155 |
public function getRequestIp( $bAsHuman = true ) {
|
192 |
/**
|
193 |
* @param string $sIp
|
194 |
* @param bool $flags
|
195 |
+
* @return bool
|
196 |
*/
|
197 |
public function isValidIp( $sIp, $flags = null ) {
|
198 |
return filter_var( trim( $sIp ), FILTER_VALIDATE_IP, $flags );
|
200 |
|
201 |
/**
|
202 |
* @param string $sIp
|
203 |
+
* @return bool
|
204 |
*/
|
205 |
public function isValidIp4Range( $sIp ) {
|
206 |
$bIsRange = false;
|
213 |
|
214 |
/**
|
215 |
* @param string $sIp
|
216 |
+
* @return bool
|
217 |
+
*/
|
218 |
+
public function isValidIp6Range( $sIp ) {
|
219 |
+
$bIsRange = false;
|
220 |
+
if ( strpos( $sIp, '/' ) ) {
|
221 |
+
list( $sIp, $sCIDR ) = explode( '/', $sIp );
|
222 |
+
$bIsRange = $this->isValidIp( $sIp ) && ( (int)$sCIDR >= 0 && (int)$sCIDR <= 128 );
|
223 |
+
}
|
224 |
+
return $bIsRange;
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* @param string $sIp
|
229 |
+
* @return bool
|
230 |
*/
|
231 |
public function isValidIpOrRange( $sIp ) {
|
232 |
return $this->isValidIp_PublicRemote( $sIp ) || $this->isValidIpRange( $sIp );
|
235 |
/**
|
236 |
* Assumes a valid IPv4 address is provided as we're only testing for a whether the IP is public or not.
|
237 |
* @param string $sIp
|
238 |
+
* @return bool
|
239 |
*/
|
240 |
public function isValidIp_PublicRange( $sIp ) {
|
241 |
return $this->isValidIp( $sIp, FILTER_FLAG_NO_PRIV_RANGE );
|
243 |
|
244 |
/**
|
245 |
* @param string $sIp
|
246 |
+
* @return bool
|
247 |
*/
|
248 |
public function isValidIp_PublicRemote( $sIp ) {
|
249 |
return $this->isValidIp( $sIp, ( FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) );
|
251 |
|
252 |
/**
|
253 |
* @param string $sIp
|
254 |
+
* @return bool
|
255 |
*/
|
256 |
public function isValidIpRange( $sIp ) {
|
257 |
+
return $this->isValidIp4Range( $sIp ) || $this->isValidIp6Range( $sIp );
|
|
|
|
|
|
|
|
|
258 |
}
|
259 |
|
260 |
/**
|
src/lib/vendor/symfony/polyfill-mbstring/Mbstring.php
CHANGED
@@ -512,7 +512,9 @@ final class Mbstring
|
|
512 |
$offset = 0;
|
513 |
} elseif ($offset = (int) $offset) {
|
514 |
if ($offset < 0) {
|
515 |
-
|
|
|
|
|
516 |
$offset = 0;
|
517 |
} else {
|
518 |
$haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
|
@@ -532,7 +534,7 @@ final class Mbstring
|
|
532 |
return null;
|
533 |
}
|
534 |
|
535 |
-
if ($split_length
|
536 |
trigger_error('The length of each segment must be greater than zero', E_USER_WARNING);
|
537 |
|
538 |
return false;
|
@@ -542,6 +544,10 @@ final class Mbstring
|
|
542 |
$encoding = mb_internal_encoding();
|
543 |
}
|
544 |
|
|
|
|
|
|
|
|
|
545 |
$result = array();
|
546 |
$length = mb_strlen($string, $encoding);
|
547 |
|
@@ -815,11 +821,16 @@ final class Mbstring
|
|
815 |
return self::$internalEncoding;
|
816 |
}
|
817 |
|
|
|
|
|
|
|
|
|
818 |
$encoding = strtoupper($encoding);
|
819 |
|
820 |
if ('8BIT' === $encoding || 'BINARY' === $encoding) {
|
821 |
return 'CP850';
|
822 |
}
|
|
|
823 |
if ('UTF8' === $encoding) {
|
824 |
return 'UTF-8';
|
825 |
}
|
512 |
$offset = 0;
|
513 |
} elseif ($offset = (int) $offset) {
|
514 |
if ($offset < 0) {
|
515 |
+
if (0 > $offset += self::mb_strlen($needle)) {
|
516 |
+
$haystack = self::mb_substr($haystack, 0, $offset, $encoding);
|
517 |
+
}
|
518 |
$offset = 0;
|
519 |
} else {
|
520 |
$haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
|
534 |
return null;
|
535 |
}
|
536 |
|
537 |
+
if (1 > $split_length = (int) $split_length) {
|
538 |
trigger_error('The length of each segment must be greater than zero', E_USER_WARNING);
|
539 |
|
540 |
return false;
|
544 |
$encoding = mb_internal_encoding();
|
545 |
}
|
546 |
|
547 |
+
if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
|
548 |
+
return preg_split("/(.{{$split_length}})/u", $string, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
549 |
+
}
|
550 |
+
|
551 |
$result = array();
|
552 |
$length = mb_strlen($string, $encoding);
|
553 |
|
821 |
return self::$internalEncoding;
|
822 |
}
|
823 |
|
824 |
+
if ('UTF-8' === $encoding) {
|
825 |
+
return 'UTF-8';
|
826 |
+
}
|
827 |
+
|
828 |
$encoding = strtoupper($encoding);
|
829 |
|
830 |
if ('8BIT' === $encoding || 'BINARY' === $encoding) {
|
831 |
return 'CP850';
|
832 |
}
|
833 |
+
|
834 |
if ('UTF8' === $encoding) {
|
835 |
return 'UTF-8';
|
836 |
}
|
src/processors/adminaccess_whitelabel.php
CHANGED
@@ -57,7 +57,7 @@ class ICWP_WPSF_Processor_AdminAccess_Whitelabel extends Modules\BaseShield\Shie
|
|
57 |
|
58 |
public function hideFromPluginEditor() {
|
59 |
$oCon = $this->getCon();
|
60 |
-
$sJs =
|
61 |
echo sprintf( '<script type="text/javascript">%s</script>', sprintf( $sJs, $oCon->getPluginBaseFile() ) );
|
62 |
}
|
63 |
|
57 |
|
58 |
public function hideFromPluginEditor() {
|
59 |
$oCon = $this->getCon();
|
60 |
+
$sJs = Services::Data()->readFileContentsUsingInclude( $oCon->getPath_AssetJs( 'whitelabel.js' ) );
|
61 |
echo sprintf( '<script type="text/javascript">%s</script>', sprintf( $sJs, $oCon->getPluginBaseFile() ) );
|
62 |
}
|
63 |
|
src/processors/audit_trail.php
CHANGED
@@ -12,7 +12,7 @@ class ICWP_WPSF_Processor_AuditTrail extends Modules\BaseShield\ShieldProcessor
|
|
12 |
if ( $oOpts->isEnabledAuditing() ) {
|
13 |
$this->getSubProAuditor()->execute();
|
14 |
}
|
15 |
-
if ( $oOpts->isEnabledChangeTracking() ) {
|
16 |
$this->getSubProChangeTracking()->execute();
|
17 |
}
|
18 |
}
|
12 |
if ( $oOpts->isEnabledAuditing() ) {
|
13 |
$this->getSubProAuditor()->execute();
|
14 |
}
|
15 |
+
if ( false && $oOpts->isEnabledChangeTracking() ) {
|
16 |
$this->getSubProChangeTracking()->execute();
|
17 |
}
|
18 |
}
|
src/processors/autoupdates.php
CHANGED
@@ -34,8 +34,8 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
34 |
* filter. What this filter decides will ultimately determine the fate of any core upgrade.
|
35 |
*/
|
36 |
public function run() {
|
37 |
-
/** @var
|
38 |
-
$
|
39 |
|
40 |
$nFilterPriority = $this->getHookPriority();
|
41 |
add_filter( 'allow_minor_auto_core_updates', [ $this, 'autoupdate_core_minor' ], $nFilterPriority );
|
@@ -46,11 +46,11 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
46 |
add_filter( 'auto_update_theme', [ $this, 'autoupdate_themes' ], $nFilterPriority, 2 );
|
47 |
add_filter( 'auto_update_core', [ $this, 'autoupdate_core' ], $nFilterPriority, 2 );
|
48 |
|
49 |
-
if ( $
|
50 |
add_filter( 'automatic_updates_is_vcs_checkout', '__return_false', $nFilterPriority );
|
51 |
}
|
52 |
|
53 |
-
if ( !$
|
54 |
//more parameter options here for later
|
55 |
add_filter( 'auto_core_update_send_email', [ $this, 'autoupdate_send_email' ], $nFilterPriority, 1 );
|
56 |
add_filter( 'auto_core_update_email', [ $this, 'autoupdate_email_override' ], $nFilterPriority, 1 );
|
@@ -59,12 +59,12 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
59 |
add_action( 'set_site_transient_update_plugins', [ $this, 'trackUpdateTimesPlugins' ] );
|
60 |
add_action( 'set_site_transient_update_themes', [ $this, 'trackUpdateTimesThemes' ] );
|
61 |
|
62 |
-
if ( $
|
63 |
$this->trackAssetsVersions();
|
64 |
add_action( 'automatic_updates_complete', [ $this, 'sendNotificationEmail' ] );
|
65 |
}
|
66 |
|
67 |
-
if ( $
|
68 |
// Adds automatic update indicator column to all plugins in plugin listing.
|
69 |
add_filter( 'manage_plugins_columns', [ $this, 'fAddPluginsListAutoUpdateColumn' ] );
|
70 |
}
|
@@ -72,9 +72,9 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
72 |
}
|
73 |
|
74 |
public function onWpLoaded() {
|
75 |
-
/** @var
|
76 |
-
$
|
77 |
-
if ( $
|
78 |
$this->disableAllAutoUpdates();
|
79 |
}
|
80 |
else {
|
@@ -126,10 +126,10 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
126 |
public function trackUpdateTimesCore( $oUpdates ) {
|
127 |
|
128 |
if ( !empty( $oUpdates ) && isset( $oUpdates->updates ) && is_array( $oUpdates->updates ) ) {
|
129 |
-
/** @var
|
130 |
-
$
|
131 |
|
132 |
-
$aTk = $
|
133 |
$aItemTk = isset( $aTk[ 'core' ][ 'wp' ] ) ? $aTk[ 'core' ][ 'wp' ] : [];
|
134 |
foreach ( $oUpdates->updates as $oUpdate ) {
|
135 |
if ( 'autoupdate' == $oUpdate->response ) {
|
@@ -140,7 +140,7 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
140 |
}
|
141 |
}
|
142 |
$aTk[ 'core' ][ 'wp' ] = array_slice( $aItemTk, -5 );
|
143 |
-
$
|
144 |
}
|
145 |
}
|
146 |
|
@@ -163,12 +163,12 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
163 |
* @param string $sContext - plugins/themes
|
164 |
*/
|
165 |
protected function trackUpdateTimeCommon( $oUpdates, $sContext ) {
|
|
|
|
|
166 |
|
167 |
if ( !empty( $oUpdates ) && isset( $oUpdates->response ) && is_array( $oUpdates->response ) ) {
|
168 |
-
/** @var ICWP_WPSF_FeatureHandler_Autoupdates $oFO */
|
169 |
-
$oFO = $this->getMod();
|
170 |
|
171 |
-
$aTk = $
|
172 |
foreach ( $oUpdates->response as $sSlug => $oUpdate ) {
|
173 |
$aItemTk = isset( $aTk[ $sContext ][ $sSlug ] ) ? $aTk[ $sContext ][ $sSlug ] : [];
|
174 |
if ( is_array( $oUpdate ) ) {
|
@@ -183,7 +183,7 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
183 |
$aTk[ $sContext ][ $sSlug ] = array_slice( $aItemTk, -3 );
|
184 |
}
|
185 |
}
|
186 |
-
$
|
187 |
}
|
188 |
}
|
189 |
|
@@ -203,14 +203,14 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
203 |
* @return boolean
|
204 |
*/
|
205 |
public function autoupdate_core_major( $bUpdate ) {
|
206 |
-
/** @var
|
207 |
-
$
|
208 |
|
209 |
-
if ( $
|
210 |
$bUpdate = false;
|
211 |
}
|
212 |
-
else if ( !$
|
213 |
-
$bUpdate = $
|
214 |
}
|
215 |
|
216 |
return $bUpdate;
|
@@ -223,14 +223,14 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
223 |
* @return boolean
|
224 |
*/
|
225 |
public function autoupdate_core_minor( $bUpdate ) {
|
226 |
-
/** @var
|
227 |
-
$
|
228 |
|
229 |
-
if ( $
|
230 |
$bUpdate = false;
|
231 |
}
|
232 |
-
else if ( !$
|
233 |
-
$bUpdate = $
|
234 |
}
|
235 |
return $bUpdate;
|
236 |
}
|
@@ -242,7 +242,7 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
242 |
* @return boolean
|
243 |
*/
|
244 |
public function autoupdate_translations( $bUpdate ) {
|
245 |
-
return $this->
|
246 |
}
|
247 |
|
248 |
/**
|
@@ -251,10 +251,10 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
251 |
* @return bool
|
252 |
*/
|
253 |
public function autoupdate_core( $bDoAutoUpdate, $oCoreUpdate ) {
|
254 |
-
/** @var
|
255 |
-
$
|
256 |
|
257 |
-
if ( $
|
258 |
$bDoAutoUpdate = false;
|
259 |
}
|
260 |
else if ( $this->isDelayed( $oCoreUpdate, 'core' ) ) {
|
@@ -270,10 +270,10 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
270 |
* @return boolean
|
271 |
*/
|
272 |
public function autoupdate_plugins( $bDoAutoUpdate, $mItem ) {
|
273 |
-
/** @var
|
274 |
-
$
|
275 |
|
276 |
-
if ( $
|
277 |
$bDoAutoUpdate = false;
|
278 |
}
|
279 |
else {
|
@@ -284,14 +284,14 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
284 |
}
|
285 |
|
286 |
// first, is global auto updates for plugins set
|
287 |
-
if ( $
|
288 |
$bDoAutoUpdate = true;
|
289 |
}
|
290 |
-
else if ( $
|
291 |
$bDoAutoUpdate = true;
|
292 |
}
|
293 |
else if ( $sFile === $this->getCon()->getPluginBaseFile() ) {
|
294 |
-
$sAuto = $
|
295 |
if ( $sAuto === 'immediate' ) {
|
296 |
$bDoAutoUpdate = true;
|
297 |
}
|
@@ -310,10 +310,10 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
310 |
* @return boolean
|
311 |
*/
|
312 |
public function autoupdate_themes( $bDoAutoUpdate, $mItem ) {
|
313 |
-
/** @var
|
314 |
-
$
|
315 |
|
316 |
-
if ( $
|
317 |
$bDoAutoUpdate = false;
|
318 |
}
|
319 |
else {
|
@@ -341,15 +341,17 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
341 |
* @param string $sContext
|
342 |
* @return bool
|
343 |
*/
|
344 |
-
|
|
|
|
|
345 |
|
346 |
$bDelayed = false;
|
347 |
|
348 |
/** @var \ICWP_WPSF_FeatureHandler_Autoupdates $oFO */
|
349 |
$oFO = $this->getMod();
|
350 |
-
if ( $
|
351 |
|
352 |
-
$aTk = $
|
353 |
|
354 |
$sVersion = '';
|
355 |
if ( $sContext == 'core' ) {
|
@@ -369,7 +371,7 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
369 |
}
|
370 |
|
371 |
if ( !empty( $sVersion ) && isset( $aItemTk[ $sVersion ] ) ) {
|
372 |
-
$bDelayed = ( Services::Request()->ts() - $aItemTk[ $sVersion ] < $
|
373 |
}
|
374 |
}
|
375 |
|
@@ -382,9 +384,9 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
382 |
* @return boolean
|
383 |
*/
|
384 |
public function autoupdate_send_email( $bSendEmail ) {
|
385 |
-
/** @var
|
386 |
-
$
|
387 |
-
return $
|
388 |
}
|
389 |
|
390 |
/**
|
@@ -444,11 +446,12 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
444 |
if ( $sColumnName != 'icwp_autoupdate' ) {
|
445 |
return;
|
446 |
}
|
447 |
-
/** @var
|
448 |
-
$
|
|
|
449 |
$bUpdate = Services::WpPlugins()->isPluginAutomaticallyUpdated( $sPluginBaseFileName );
|
450 |
-
// $bUpdate = in_array( $sPluginBaseFileName, $
|
451 |
-
$bDisabled = $bUpdate && !in_array( $sPluginBaseFileName, $
|
452 |
echo $this->getPluginAutoupdateIconHtml( $sPluginBaseFileName, $bUpdate, $bDisabled );
|
453 |
}
|
454 |
|
@@ -595,6 +598,6 @@ class ICWP_WPSF_Processor_Autoupdates extends Modules\BaseShield\ShieldProcessor
|
|
595 |
* @return int
|
596 |
*/
|
597 |
protected function getHookPriority() {
|
598 |
-
return $this->
|
599 |
}
|
600 |
}
|
34 |
* filter. What this filter decides will ultimately determine the fate of any core upgrade.
|
35 |
*/
|
36 |
public function run() {
|
37 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
38 |
+
$oOpts = $this->getOptions();
|
39 |
|
40 |
$nFilterPriority = $this->getHookPriority();
|
41 |
add_filter( 'allow_minor_auto_core_updates', [ $this, 'autoupdate_core_minor' ], $nFilterPriority );
|
46 |
add_filter( 'auto_update_theme', [ $this, 'autoupdate_themes' ], $nFilterPriority, 2 );
|
47 |
add_filter( 'auto_update_core', [ $this, 'autoupdate_core' ], $nFilterPriority, 2 );
|
48 |
|
49 |
+
if ( $oOpts->isOpt( 'enable_autoupdate_ignore_vcs', 'Y' ) ) {
|
50 |
add_filter( 'automatic_updates_is_vcs_checkout', '__return_false', $nFilterPriority );
|
51 |
}
|
52 |
|
53 |
+
if ( !$oOpts->isDisableAllAutoUpdates() ) {
|
54 |
//more parameter options here for later
|
55 |
add_filter( 'auto_core_update_send_email', [ $this, 'autoupdate_send_email' ], $nFilterPriority, 1 );
|
56 |
add_filter( 'auto_core_update_email', [ $this, 'autoupdate_email_override' ], $nFilterPriority, 1 );
|
59 |
add_action( 'set_site_transient_update_plugins', [ $this, 'trackUpdateTimesPlugins' ] );
|
60 |
add_action( 'set_site_transient_update_themes', [ $this, 'trackUpdateTimesThemes' ] );
|
61 |
|
62 |
+
if ( $oOpts->isSendAutoupdatesNotificationEmail() ) {
|
63 |
$this->trackAssetsVersions();
|
64 |
add_action( 'automatic_updates_complete', [ $this, 'sendNotificationEmail' ] );
|
65 |
}
|
66 |
|
67 |
+
if ( $oOpts->isAutoupdateIndividualPlugins() ) {
|
68 |
// Adds automatic update indicator column to all plugins in plugin listing.
|
69 |
add_filter( 'manage_plugins_columns', [ $this, 'fAddPluginsListAutoUpdateColumn' ] );
|
70 |
}
|
72 |
}
|
73 |
|
74 |
public function onWpLoaded() {
|
75 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
76 |
+
$oOpts = $this->getOptions();
|
77 |
+
if ( $oOpts->isDisableAllAutoUpdates() ) {
|
78 |
$this->disableAllAutoUpdates();
|
79 |
}
|
80 |
else {
|
126 |
public function trackUpdateTimesCore( $oUpdates ) {
|
127 |
|
128 |
if ( !empty( $oUpdates ) && isset( $oUpdates->updates ) && is_array( $oUpdates->updates ) ) {
|
129 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
130 |
+
$oOpts = $this->getOptions();
|
131 |
|
132 |
+
$aTk = $oOpts->getDelayTracking();
|
133 |
$aItemTk = isset( $aTk[ 'core' ][ 'wp' ] ) ? $aTk[ 'core' ][ 'wp' ] : [];
|
134 |
foreach ( $oUpdates->updates as $oUpdate ) {
|
135 |
if ( 'autoupdate' == $oUpdate->response ) {
|
140 |
}
|
141 |
}
|
142 |
$aTk[ 'core' ][ 'wp' ] = array_slice( $aItemTk, -5 );
|
143 |
+
$oOpts->setDelayTracking( $aTk );
|
144 |
}
|
145 |
}
|
146 |
|
163 |
* @param string $sContext - plugins/themes
|
164 |
*/
|
165 |
protected function trackUpdateTimeCommon( $oUpdates, $sContext ) {
|
166 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
167 |
+
$oOpts = $this->getOptions();
|
168 |
|
169 |
if ( !empty( $oUpdates ) && isset( $oUpdates->response ) && is_array( $oUpdates->response ) ) {
|
|
|
|
|
170 |
|
171 |
+
$aTk = $oOpts->getDelayTracking();
|
172 |
foreach ( $oUpdates->response as $sSlug => $oUpdate ) {
|
173 |
$aItemTk = isset( $aTk[ $sContext ][ $sSlug ] ) ? $aTk[ $sContext ][ $sSlug ] : [];
|
174 |
if ( is_array( $oUpdate ) ) {
|
183 |
$aTk[ $sContext ][ $sSlug ] = array_slice( $aItemTk, -3 );
|
184 |
}
|
185 |
}
|
186 |
+
$oOpts->setDelayTracking( $aTk );
|
187 |
}
|
188 |
}
|
189 |
|
203 |
* @return boolean
|
204 |
*/
|
205 |
public function autoupdate_core_major( $bUpdate ) {
|
206 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
207 |
+
$oOpts = $this->getOptions();
|
208 |
|
209 |
+
if ( $oOpts->isDisableAllAutoUpdates() ) {
|
210 |
$bUpdate = false;
|
211 |
}
|
212 |
+
else if ( !$oOpts->isDelayUpdates() ) { // the delay is handles elsewhere
|
213 |
+
$bUpdate = $oOpts->isAutoUpdateCoreMajor();
|
214 |
}
|
215 |
|
216 |
return $bUpdate;
|
223 |
* @return boolean
|
224 |
*/
|
225 |
public function autoupdate_core_minor( $bUpdate ) {
|
226 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
227 |
+
$oOpts = $this->getOptions();
|
228 |
|
229 |
+
if ( $oOpts->isDisableAllAutoUpdates() ) {
|
230 |
$bUpdate = false;
|
231 |
}
|
232 |
+
else if ( !$oOpts->isDelayUpdates() ) {//TODO delay
|
233 |
+
$bUpdate = $oOpts->isAutoUpdateCoreMinor();
|
234 |
}
|
235 |
return $bUpdate;
|
236 |
}
|
242 |
* @return boolean
|
243 |
*/
|
244 |
public function autoupdate_translations( $bUpdate ) {
|
245 |
+
return $this->getOptions()->isOpt( 'enable_autoupdate_translations', 'Y' );
|
246 |
}
|
247 |
|
248 |
/**
|
251 |
* @return bool
|
252 |
*/
|
253 |
public function autoupdate_core( $bDoAutoUpdate, $oCoreUpdate ) {
|
254 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
255 |
+
$oOpts = $this->getOptions();
|
256 |
|
257 |
+
if ( $oOpts->isDisableAllAutoUpdates() ) {
|
258 |
$bDoAutoUpdate = false;
|
259 |
}
|
260 |
else if ( $this->isDelayed( $oCoreUpdate, 'core' ) ) {
|
270 |
* @return boolean
|
271 |
*/
|
272 |
public function autoupdate_plugins( $bDoAutoUpdate, $mItem ) {
|
273 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
274 |
+
$oOpts = $this->getOptions();
|
275 |
|
276 |
+
if ( $oOpts->isDisableAllAutoUpdates() ) {
|
277 |
$bDoAutoUpdate = false;
|
278 |
}
|
279 |
else {
|
284 |
}
|
285 |
|
286 |
// first, is global auto updates for plugins set
|
287 |
+
if ( $oOpts->isAutoupdateAllPlugins() ) {
|
288 |
$bDoAutoUpdate = true;
|
289 |
}
|
290 |
+
else if ( $oOpts->isPluginSetToAutoupdate( $sFile ) ) {
|
291 |
$bDoAutoUpdate = true;
|
292 |
}
|
293 |
else if ( $sFile === $this->getCon()->getPluginBaseFile() ) {
|
294 |
+
$sAuto = $oOpts->getSelfAutoUpdateOpt();
|
295 |
if ( $sAuto === 'immediate' ) {
|
296 |
$bDoAutoUpdate = true;
|
297 |
}
|
310 |
* @return boolean
|
311 |
*/
|
312 |
public function autoupdate_themes( $bDoAutoUpdate, $mItem ) {
|
313 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
314 |
+
$oOpts = $this->getOptions();
|
315 |
|
316 |
+
if ( $oOpts->isDisableAllAutoUpdates() ) {
|
317 |
$bDoAutoUpdate = false;
|
318 |
}
|
319 |
else {
|
341 |
* @param string $sContext
|
342 |
* @return bool
|
343 |
*/
|
344 |
+
private function isDelayed( $sSlug, $sContext = 'plugins' ) {
|
345 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
346 |
+
$oOpts = $this->getOptions();
|
347 |
|
348 |
$bDelayed = false;
|
349 |
|
350 |
/** @var \ICWP_WPSF_FeatureHandler_Autoupdates $oFO */
|
351 |
$oFO = $this->getMod();
|
352 |
+
if ( $oOpts->isDelayUpdates() ) {
|
353 |
|
354 |
+
$aTk = $oOpts->getDelayTracking();
|
355 |
|
356 |
$sVersion = '';
|
357 |
if ( $sContext == 'core' ) {
|
371 |
}
|
372 |
|
373 |
if ( !empty( $sVersion ) && isset( $aItemTk[ $sVersion ] ) ) {
|
374 |
+
$bDelayed = ( Services::Request()->ts() - $aItemTk[ $sVersion ] < $oOpts->getDelayUpdatesPeriod() );
|
375 |
}
|
376 |
}
|
377 |
|
384 |
* @return boolean
|
385 |
*/
|
386 |
public function autoupdate_send_email( $bSendEmail ) {
|
387 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
388 |
+
$oOpts = $this->getOptions();
|
389 |
+
return $oOpts->isSendAutoupdatesNotificationEmail();
|
390 |
}
|
391 |
|
392 |
/**
|
446 |
if ( $sColumnName != 'icwp_autoupdate' ) {
|
447 |
return;
|
448 |
}
|
449 |
+
/** @var Modules\Autoupdates\Options $oOpts */
|
450 |
+
$oOpts = $this->getOptions();
|
451 |
+
|
452 |
$bUpdate = Services::WpPlugins()->isPluginAutomaticallyUpdated( $sPluginBaseFileName );
|
453 |
+
// $bUpdate = in_array( $sPluginBaseFileName, $oOpts->getAutoupdatePlugins() );
|
454 |
+
$bDisabled = $bUpdate && !in_array( $sPluginBaseFileName, $oOpts->getAutoupdatePlugins() );
|
455 |
echo $this->getPluginAutoupdateIconHtml( $sPluginBaseFileName, $bUpdate, $bDisabled );
|
456 |
}
|
457 |
|
598 |
* @return int
|
599 |
*/
|
600 |
protected function getHookPriority() {
|
601 |
+
return $this->getOptions()->getDef( 'action_hook_priority' );
|
602 |
}
|
603 |
}
|
src/processors/base.php
DELETED
@@ -1,265 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
-
use FernleafSystems\Wordpress\Services\Services;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Class ICWP_WPSF_Processor_Base
|
8 |
-
* @deprecated 8.1
|
9 |
-
*/
|
10 |
-
abstract class ICWP_WPSF_Processor_Base extends Shield\Deprecated\Foundation {
|
11 |
-
|
12 |
-
use Shield\Modules\ModConsumer;
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @var int
|
16 |
-
*/
|
17 |
-
static protected $nPromoNoticesCount = 0;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* @var ICWP_WPSF_Processor_Base[]
|
21 |
-
*/
|
22 |
-
protected $aSubPros;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @var bool
|
26 |
-
*/
|
27 |
-
private $bLoginCaptured;
|
28 |
-
|
29 |
-
/**
|
30 |
-
* @param \ICWP_WPSF_FeatureHandler_Base $oModCon
|
31 |
-
*/
|
32 |
-
public function __construct( $oModCon ) {
|
33 |
-
$this->setMod( $oModCon );
|
34 |
-
|
35 |
-
add_action( 'init', [ $this, 'onWpInit' ], 9 );
|
36 |
-
add_action( 'wp_loaded', [ $this, 'onWpLoaded' ] );
|
37 |
-
{ // Capture Logins
|
38 |
-
add_action( 'wp_login', [ $this, 'onWpLogin' ], 10, 2 );
|
39 |
-
if ( !Services::WpUsers()->isProfilePage() ) { // This can be fired during profile update.
|
40 |
-
add_action( 'set_logged_in_cookie', [ $this, 'onWpSetLoggedInCookie' ], 5, 4 );
|
41 |
-
}
|
42 |
-
}
|
43 |
-
add_action( $oModCon->prefix( 'plugin_shutdown' ), [ $this, 'onModuleShutdown' ] );
|
44 |
-
add_action( $oModCon->prefix( 'daily_cron' ), [ $this, 'runDailyCron' ] );
|
45 |
-
add_action( $oModCon->prefix( 'hourly_cron' ), [ $this, 'runHourlyCron' ] );
|
46 |
-
add_action( $oModCon->prefix( 'deactivate_plugin' ), [ $this, 'deactivatePlugin' ] );
|
47 |
-
|
48 |
-
/**
|
49 |
-
* 2019-04-19:
|
50 |
-
* wp_service_worker: added to prevent infinite page reloads triggered by an error with the PWA plugin.
|
51 |
-
* It seems that using wp_localize_script() on a request with wp_service_worker=1 causes the worker
|
52 |
-
* reload the page. Why exactly this happens hasn't been investigated, so we just skip any FRONTend
|
53 |
-
* enqueues that might call wp_localize_script() for these requests.
|
54 |
-
*/
|
55 |
-
if ( Services::Request()->query( 'wp_service_worker', 0 ) != 1 ) {
|
56 |
-
add_action( 'wp_enqueue_scripts', [ $this, 'onWpEnqueueJs' ] );
|
57 |
-
}
|
58 |
-
|
59 |
-
$this->init();
|
60 |
-
}
|
61 |
-
|
62 |
-
public function onWpInit() {
|
63 |
-
}
|
64 |
-
|
65 |
-
public function onWpLoaded() {
|
66 |
-
}
|
67 |
-
|
68 |
-
public function onWpEnqueueJs() {
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* @param string $sUsername
|
73 |
-
* @param WP_User $oUser
|
74 |
-
*/
|
75 |
-
public function onWpLogin( $sUsername, $oUser ) {
|
76 |
-
/*
|
77 |
-
if ( !$oUser instanceof WP_User ) {
|
78 |
-
$oUser = $this->loadWpUsers()->getUserByUsername( $sUsername );
|
79 |
-
}
|
80 |
-
*/
|
81 |
-
}
|
82 |
-
|
83 |
-
/**
|
84 |
-
* @param string $sCookie
|
85 |
-
* @param int $nExpire
|
86 |
-
* @param int $nExpiration
|
87 |
-
* @param int $nUserId
|
88 |
-
*/
|
89 |
-
public function onWpSetLoggedInCookie( $sCookie, $nExpire, $nExpiration, $nUserId ) {
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* @return bool
|
94 |
-
*/
|
95 |
-
protected function isLoginCaptured() {
|
96 |
-
return (bool)$this->bLoginCaptured;
|
97 |
-
}
|
98 |
-
|
99 |
-
public function runDailyCron() {
|
100 |
-
}
|
101 |
-
|
102 |
-
public function runHourlyCron() {
|
103 |
-
}
|
104 |
-
|
105 |
-
/**
|
106 |
-
* @return $this
|
107 |
-
*/
|
108 |
-
protected function setLoginCaptured() {
|
109 |
-
$this->bLoginCaptured = true;
|
110 |
-
return $this;
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* @return int
|
115 |
-
*/
|
116 |
-
protected function getPromoNoticesCount() {
|
117 |
-
return self::$nPromoNoticesCount;
|
118 |
-
}
|
119 |
-
|
120 |
-
/**
|
121 |
-
* @return $this
|
122 |
-
*/
|
123 |
-
protected function incrementPromoNoticesCount() {
|
124 |
-
self::$nPromoNoticesCount++;
|
125 |
-
return $this;
|
126 |
-
}
|
127 |
-
|
128 |
-
public function onModuleShutdown() {
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
*/
|
133 |
-
public function init() {
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* @return bool
|
138 |
-
*/
|
139 |
-
public function isReadyToRun() {
|
140 |
-
return true;
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* Override to set what this processor does when it's "run"
|
145 |
-
*/
|
146 |
-
public function run() {
|
147 |
-
}
|
148 |
-
|
149 |
-
/**
|
150 |
-
* @param array $aNoticeData
|
151 |
-
* @throws \Exception
|
152 |
-
*/
|
153 |
-
protected function insertAdminNotice( $aNoticeData ) {
|
154 |
-
$aAttrs = $aNoticeData[ 'notice_attributes' ];
|
155 |
-
$bIsPromo = isset( $aAttrs[ 'type' ] ) && $aAttrs[ 'type' ] == 'promo';
|
156 |
-
if ( $bIsPromo && $this->getPromoNoticesCount() > 0 ) {
|
157 |
-
return;
|
158 |
-
}
|
159 |
-
|
160 |
-
$bCantDismiss = isset( $aNoticeData[ 'notice_attributes' ][ 'can_dismiss' ] )
|
161 |
-
&& !$aNoticeData[ 'notice_attributes' ][ 'can_dismiss' ];
|
162 |
-
|
163 |
-
$oNotices = $this->loadWpNotices();
|
164 |
-
if ( $bCantDismiss || !$oNotices->isDismissed( $aAttrs[ 'id' ] ) ) {
|
165 |
-
|
166 |
-
$sRenderedNotice = $this->getMod()->renderAdminNotice( $aNoticeData );
|
167 |
-
if ( !empty( $sRenderedNotice ) ) {
|
168 |
-
$oNotices->addAdminNotice(
|
169 |
-
$sRenderedNotice,
|
170 |
-
$aNoticeData[ 'notice_attributes' ][ 'notice_id' ]
|
171 |
-
);
|
172 |
-
if ( $bIsPromo ) {
|
173 |
-
$this->incrementPromoNoticesCount();
|
174 |
-
}
|
175 |
-
}
|
176 |
-
}
|
177 |
-
}
|
178 |
-
|
179 |
-
/**
|
180 |
-
* @param $sOptionKey
|
181 |
-
* @param mixed $mDefault
|
182 |
-
* @return mixed
|
183 |
-
*/
|
184 |
-
public function getOption( $sOptionKey, $mDefault = false ) {
|
185 |
-
return $this->getMod()->getOpt( $sOptionKey, $mDefault );
|
186 |
-
}
|
187 |
-
|
188 |
-
/**
|
189 |
-
* We don't handle locale derivatives (yet)
|
190 |
-
* @return string
|
191 |
-
*/
|
192 |
-
protected function getGoogleRecaptchaLocale() {
|
193 |
-
return Services::WpGeneral()->getLocale( '-' );
|
194 |
-
}
|
195 |
-
|
196 |
-
/**
|
197 |
-
* @return ICWP_WPSF_Processor_Email
|
198 |
-
*/
|
199 |
-
public function getEmailProcessor() {
|
200 |
-
return $this->getMod()->getEmailProcessor();
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* @param string $sKey
|
205 |
-
* @return ICWP_WPSF_Processor_Base|mixed|null
|
206 |
-
*/
|
207 |
-
protected function getSubPro( $sKey ) {
|
208 |
-
$aProcessors = $this->getSubProcessors();
|
209 |
-
if ( !isset( $aProcessors[ $sKey ] ) ) {
|
210 |
-
$aMap = $this->getSubProMap();
|
211 |
-
if ( !isset( $aMap[ $sKey ] ) ) {
|
212 |
-
error_log( 'Sub processor key not set: '.$sKey );
|
213 |
-
}
|
214 |
-
$aProcessors[ $sKey ] = new $aMap[ $sKey ]( $this->getMod() );
|
215 |
-
}
|
216 |
-
return $aProcessors[ $sKey ];
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* @return array
|
221 |
-
*/
|
222 |
-
protected function getSubProMap() {
|
223 |
-
return [];
|
224 |
-
}
|
225 |
-
|
226 |
-
/**
|
227 |
-
*/
|
228 |
-
public function deactivatePlugin() {
|
229 |
-
}
|
230 |
-
|
231 |
-
/**
|
232 |
-
* @return ICWP_WPSF_Processor_Base[]
|
233 |
-
*/
|
234 |
-
protected function getSubProcessors() {
|
235 |
-
if ( !isset( $this->aSubPros ) ) {
|
236 |
-
$this->aSubPros = [];
|
237 |
-
}
|
238 |
-
return $this->aSubPros;
|
239 |
-
}
|
240 |
-
|
241 |
-
/**
|
242 |
-
* @deprecated 8.1
|
243 |
-
*/
|
244 |
-
public function autoAddToAdminNotices() {
|
245 |
-
}
|
246 |
-
|
247 |
-
/**
|
248 |
-
* @return string
|
249 |
-
* @deprecated 8.1
|
250 |
-
*/
|
251 |
-
protected function ip() {
|
252 |
-
return Services::IP()->getRequestIp();
|
253 |
-
}
|
254 |
-
|
255 |
-
/**
|
256 |
-
* Will prefix and return any string with the unique plugin prefix.
|
257 |
-
* @param string $sSuffix
|
258 |
-
* @param string $sGlue
|
259 |
-
* @return string
|
260 |
-
* @deprecated 8.1
|
261 |
-
*/
|
262 |
-
protected function prefix( $sSuffix = '', $sGlue = '-' ) {
|
263 |
-
return $this->getCon()->prefix( $sSuffix, $sGlue );
|
264 |
-
}
|
265 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/processors/base_plugin.php
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Services\Services;
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Class ICWP_WPSF_Processor_BasePlugin
|
7 |
-
* @deprecated 8.1
|
8 |
-
*/
|
9 |
-
class ICWP_WPSF_Processor_BasePlugin extends ICWP_WPSF_Processor_BaseWpsf {
|
10 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/processors/base_wpsf.php
DELETED
@@ -1,198 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
-
use FernleafSystems\Wordpress\Services\Services;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Class ICWP_WPSF_Processor_BaseWpsf
|
8 |
-
* @deprecated 8.1
|
9 |
-
*/
|
10 |
-
abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
|
11 |
-
|
12 |
-
const RECAPTCHA_JS_HANDLE = 'icwp-google-recaptcha';
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @var array
|
16 |
-
*/
|
17 |
-
private $aStatistics;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* @var bool
|
21 |
-
*/
|
22 |
-
private static $bRecaptchaEnqueue = false;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @var bool
|
26 |
-
*/
|
27 |
-
private $bLogRequest;
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Resets the object values to be re-used anew
|
31 |
-
*/
|
32 |
-
public function init() {
|
33 |
-
parent::init();
|
34 |
-
$oFO = $this->getMod();
|
35 |
-
add_filter( $oFO->prefix( 'collect_tracking_data' ), [ $this, 'tracking_DataCollect' ] );
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* @return int
|
40 |
-
*/
|
41 |
-
protected function getInstallationDays() {
|
42 |
-
$nTimeInstalled = $this->getCon()
|
43 |
-
->getModule_Plugin()
|
44 |
-
->getInstallDate();
|
45 |
-
if ( empty( $nTimeInstalled ) ) {
|
46 |
-
return 0;
|
47 |
-
}
|
48 |
-
return (int)round( ( Services::Request()->ts() - $nTimeInstalled )/DAY_IN_SECONDS );
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* @param WP_User $oUser
|
53 |
-
* @return bool
|
54 |
-
*/
|
55 |
-
protected function isUserSubjectToLoginIntent( $oUser = null ) {
|
56 |
-
$bIsSubject = false;
|
57 |
-
|
58 |
-
if ( !$oUser instanceof WP_User ) {
|
59 |
-
$oUser = Services::WpUsers()->getCurrentWpUser();
|
60 |
-
}
|
61 |
-
if ( $oUser instanceof WP_User ) {
|
62 |
-
$bIsSubject = apply_filters( $this->getCon()->prefix( 'user_subject_to_login_intent' ), false, $oUser );
|
63 |
-
}
|
64 |
-
|
65 |
-
return $bIsSubject;
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* @return bool
|
70 |
-
*/
|
71 |
-
protected function getRecaptchaTheme() {
|
72 |
-
/** @var \ICWP_WPSF_FeatureHandler_BaseWpsf $oFO */
|
73 |
-
$oFO = $this->getMod();
|
74 |
-
return $this->isRecaptchaInvisible() ? 'light' : $oFO->getGoogleRecaptchaStyle();
|
75 |
-
}
|
76 |
-
|
77 |
-
/**
|
78 |
-
* @return bool
|
79 |
-
*/
|
80 |
-
protected function getIfLogRequest() {
|
81 |
-
return isset( $this->bLogRequest ) ? (bool)$this->bLogRequest : !Services::WpGeneral()->isCron();
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* @param bool $bLog
|
86 |
-
* @return $this
|
87 |
-
*/
|
88 |
-
protected function setIfLogRequest( $bLog ) {
|
89 |
-
$this->bLogRequest = $bLog;
|
90 |
-
return $this;
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* @return bool
|
95 |
-
*/
|
96 |
-
protected function isRecaptchaInvisible() {
|
97 |
-
/** @var \ICWP_WPSF_FeatureHandler_BaseWpsf $oFO */
|
98 |
-
$oFO = $this->getMod();
|
99 |
-
return ( $oFO->getGoogleRecaptchaStyle() == 'invisible' );
|
100 |
-
}
|
101 |
-
|
102 |
-
public function registerGoogleRecaptchaJs() {
|
103 |
-
$sJsUri = add_query_arg(
|
104 |
-
[
|
105 |
-
'hl' => $this->getGoogleRecaptchaLocale(),
|
106 |
-
'onload' => 'onLoadIcwpRecaptchaCallback',
|
107 |
-
'render' => 'explicit',
|
108 |
-
],
|
109 |
-
'https://www.google.com/recaptcha/api.js'
|
110 |
-
);
|
111 |
-
wp_register_script( self::RECAPTCHA_JS_HANDLE, $sJsUri, [], false, true );
|
112 |
-
wp_enqueue_script( self::RECAPTCHA_JS_HANDLE );
|
113 |
-
|
114 |
-
// This also gives us the chance to remove recaptcha before it's printed, if it isn't needed
|
115 |
-
add_action( 'wp_footer', [ $this, 'maybeDequeueRecaptcha' ], -100 );
|
116 |
-
add_action( 'login_footer', [ $this, 'maybeDequeueRecaptcha' ], -100 );
|
117 |
-
|
118 |
-
Services::Includes()
|
119 |
-
->addIncludeAttribute( self::RECAPTCHA_JS_HANDLE, 'async', 'async' )
|
120 |
-
->addIncludeAttribute( self::RECAPTCHA_JS_HANDLE, 'defer', 'defer' );
|
121 |
-
/**
|
122 |
-
* Change to recaptcha implementation now means
|
123 |
-
* 1 - the form will not submit unless the recaptcha has been executed (either invisible or manual)
|
124 |
-
*/
|
125 |
-
}
|
126 |
-
|
127 |
-
/**
|
128 |
-
* @return array
|
129 |
-
*/
|
130 |
-
public function stats_Get() {
|
131 |
-
if ( !isset( $this->aStatistics ) || !is_array( $this->aStatistics ) ) {
|
132 |
-
$this->aStatistics = [];
|
133 |
-
}
|
134 |
-
return $this->aStatistics;
|
135 |
-
}
|
136 |
-
|
137 |
-
/**
|
138 |
-
* Filter used to collect plugin data for tracking. Fired from the plugin processor only if the option is enabled
|
139 |
-
* - it is not enabled by default.
|
140 |
-
* Note that in this case we "mask" options that have been identified as "sensitive" - i.e. could contain
|
141 |
-
* identifiable data.
|
142 |
-
*
|
143 |
-
* @param $aData
|
144 |
-
* @return array
|
145 |
-
*/
|
146 |
-
public function tracking_DataCollect( $aData ) {
|
147 |
-
if ( !is_array( $aData ) ) {
|
148 |
-
$aData = [];
|
149 |
-
}
|
150 |
-
$oFO = $this->getMod();
|
151 |
-
$aData[ $oFO->getSlug() ] = [ 'options' => $oFO->collectOptionsForTracking() ];
|
152 |
-
return $aData;
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* If recaptcha is required, it prints the necessary snippet and does not remove the enqueue
|
157 |
-
*
|
158 |
-
* @throws \Exception
|
159 |
-
*/
|
160 |
-
public function maybeDequeueRecaptcha() {
|
161 |
-
|
162 |
-
if ( $this->isRecaptchaEnqueue() ) {
|
163 |
-
/** @var ICWP_WPSF_FeatureHandler_BaseWpsf $oFO */
|
164 |
-
$oFO = $this->getMod();
|
165 |
-
echo $oFO->renderTemplate(
|
166 |
-
'snippets/google_recaptcha_js',
|
167 |
-
[
|
168 |
-
'sitekey' => $oFO->getGoogleRecaptchaSiteKey(),
|
169 |
-
'size' => $this->isRecaptchaInvisible() ? 'invisible' : '',
|
170 |
-
'theme' => $this->getRecaptchaTheme(),
|
171 |
-
'invis' => $this->isRecaptchaInvisible(),
|
172 |
-
]
|
173 |
-
|
174 |
-
);
|
175 |
-
}
|
176 |
-
else {
|
177 |
-
wp_dequeue_script( self::RECAPTCHA_JS_HANDLE );
|
178 |
-
}
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* @return bool
|
183 |
-
*/
|
184 |
-
public function isRecaptchaEnqueue() {
|
185 |
-
return self::$bRecaptchaEnqueue;
|
186 |
-
}
|
187 |
-
|
188 |
-
/**
|
189 |
-
* Note we don't provide a 'false' option here as if it's set to be needed somewhere,
|
190 |
-
* it shouldn't be unset anywhere else.
|
191 |
-
*
|
192 |
-
* @return $this
|
193 |
-
*/
|
194 |
-
public function setRecaptchaToEnqueue() {
|
195 |
-
self::$bRecaptchaEnqueue = true;
|
196 |
-
return $this;
|
197 |
-
}
|
198 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/processors/basedb.php
DELETED
@@ -1,103 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use FernleafSystems\Wordpress\Plugin\Shield;
|
4 |
-
use FernleafSystems\Wordpress\Services\Services;
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Class ICWP_WPSF_BaseDbProcessor
|
8 |
-
* @deprecated 8.1
|
9 |
-
*/
|
10 |
-
class ICWP_WPSF_BaseDbProcessor extends ICWP_WPSF_Processor_BaseWpsf {
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var \FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\Handler
|
14 |
-
*/
|
15 |
-
protected $oDbh;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var integer
|
19 |
-
*/
|
20 |
-
protected $nAutoExpirePeriod = null;
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @return bool
|
24 |
-
*/
|
25 |
-
public function isReadyToRun() {
|
26 |
-
try {
|
27 |
-
return ( parent::isReadyToRun() && $this->getDbHandler()->isReady() );
|
28 |
-
}
|
29 |
-
catch ( \Exception $oE ) {
|
30 |
-
return false;
|
31 |
-
}
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @return Shield\Databases\Base\Handler
|
36 |
-
*/
|
37 |
-
public function getDbHandler() {
|
38 |
-
if ( !isset( $this->oDbh ) ) {
|
39 |
-
$this->oDbh = $this->getMod()->getDbHandler();
|
40 |
-
}
|
41 |
-
return $this->oDbh;
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* @return string
|
46 |
-
*/
|
47 |
-
protected function getCreateTableSql() {
|
48 |
-
}
|
49 |
-
|
50 |
-
/**
|
51 |
-
* @return array
|
52 |
-
*/
|
53 |
-
protected function getTableColumnsByDefinition() {
|
54 |
-
}
|
55 |
-
|
56 |
-
public function runDailyCron() {
|
57 |
-
try {
|
58 |
-
if ( $this->getDbHandler()->isReady() ) {
|
59 |
-
$this->cleanupDatabase();
|
60 |
-
}
|
61 |
-
}
|
62 |
-
catch ( \Exception $oE ) {
|
63 |
-
}
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* @return bool|int
|
68 |
-
*/
|
69 |
-
public function cleanupDatabase() {
|
70 |
-
$nAutoExpirePeriod = $this->getAutoExpirePeriod();
|
71 |
-
if ( is_null( $nAutoExpirePeriod ) || !$this->getDbHandler()->isTable() ) {
|
72 |
-
return false;
|
73 |
-
}
|
74 |
-
$nTimeStamp = Services::Request()->ts() - $nAutoExpirePeriod;
|
75 |
-
return $this->getDbHandler()->deleteRowsOlderThan( $nTimeStamp );
|
76 |
-
}
|
77 |
-
|
78 |
-
/**
|
79 |
-
* 1 in 20 page loads will clean the databases. This ensures that even if the crons don't run
|
80 |
-
* correctly, we'll keep it trim.
|
81 |
-
*/
|
82 |
-
public function onModuleShutdown() {
|
83 |
-
parent::onModuleShutdown();
|
84 |
-
if ( rand( 1, 20 ) === 2 ) {
|
85 |
-
$this->cleanupDatabase();
|
86 |
-
}
|
87 |
-
}
|
88 |
-
|
89 |
-
/**
|
90 |
-
* @return int
|
91 |
-
*/
|
92 |
-
protected function getAutoExpirePeriod() {
|
93 |
-
return null;
|
94 |
-
}
|
95 |
-
|
96 |
-
/**
|
97 |
-
* @param string $sTableName
|
98 |
-
* @throws \Exception
|
99 |
-
* @deprecated 8.1
|
100 |
-
*/
|
101 |
-
protected function initializeTable( $sTableName ) {
|
102 |
-
}
|
103 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/processors/comments_filter.php
CHANGED
@@ -63,7 +63,7 @@ class ICWP_WPSF_Processor_CommentsFilter extends Modules\BaseShield\ShieldProces
|
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
-
* @return ICWP_WPSF_Processor_CommentsFilter_BotSpam
|
67 |
*/
|
68 |
private function getSubProGasp() {
|
69 |
return $this->getSubPro( 'bot' );
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
+
* @return \ICWP_WPSF_Processor_CommentsFilter_BotSpam
|
67 |
*/
|
68 |
private function getSubProGasp() {
|
69 |
return $this->getSubPro( 'bot' );
|
src/processors/commentsfilter_botspam.php
CHANGED
@@ -11,66 +11,87 @@ class ICWP_WPSF_Processor_CommentsFilter_BotSpam extends Modules\BaseShield\Shie
|
|
11 |
*/
|
12 |
private $sFormId;
|
13 |
|
14 |
-
public function run() {
|
15 |
-
add_action( 'comment_form', [ $this, 'printGaspFormItems' ], 1 );
|
16 |
-
}
|
17 |
-
|
18 |
-
public function printGaspFormItems() {
|
19 |
-
echo $this->getGaspCommentsHtml();
|
20 |
-
}
|
21 |
-
|
22 |
/**
|
23 |
-
* @
|
24 |
*/
|
25 |
-
private
|
26 |
-
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $oMod */
|
27 |
-
$oMod = $this->getMod();
|
28 |
|
29 |
-
|
30 |
-
$
|
31 |
-
|
32 |
-
|
33 |
-
'token' => $this->tokenCreateStore(),
|
34 |
-
'alert' => $oMod->getTextOpt( 'custom_message_alert' ),
|
35 |
-
'comment_reload' => $oMod->getTextOpt( 'custom_message_comment_reload' ),
|
36 |
-
'cooldown' => $oMod->getTokenCooldown(),
|
37 |
-
'expire' => $oMod->getTokenExpireInterval(),
|
38 |
-
'comment_wait' => $sCommentWait,
|
39 |
-
'js_comment_wait' => str_replace( '%s', '"+nRemaining+"', $sCommentWait ),
|
40 |
-
'confirm' => $oMod->getTextOpt( 'custom_message_checkbox' ),
|
41 |
-
];
|
42 |
|
43 |
-
|
|
|
44 |
}
|
45 |
|
46 |
-
|
47 |
-
* @return string
|
48 |
-
*/
|
49 |
-
private function tokenCreateStore() {
|
50 |
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $oMod */
|
51 |
$oMod = $this->getMod();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
$nTs = Services::Request()->ts();
|
54 |
-
$
|
55 |
-
$
|
|
|
56 |
|
57 |
-
|
58 |
-
$
|
59 |
-
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
);
|
62 |
-
|
63 |
-
return $sToken;
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
-
*
|
68 |
-
* @param string $nPostId
|
69 |
-
* @return string
|
70 |
*/
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
|
76 |
/**
|
@@ -86,4 +107,20 @@ class ICWP_WPSF_Processor_CommentsFilter_BotSpam extends Modules\BaseShield\Shie
|
|
86 |
}
|
87 |
return $this->sFormId;
|
88 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
}
|
11 |
*/
|
12 |
private $sFormId;
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
/**
|
15 |
+
* @var bool
|
16 |
*/
|
17 |
+
private $bFormItemPrinted = false;
|
|
|
|
|
18 |
|
19 |
+
public function run() {
|
20 |
+
add_action( 'wp', [ $this, 'onWp' ] );
|
21 |
+
add_action( 'wp_footer', [ $this, 'maybeDequeueScript' ] );
|
22 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
+
public function onWp() {
|
25 |
+
add_action( 'comment_form', [ $this, 'printGaspFormItems' ], 1 );
|
26 |
}
|
27 |
|
28 |
+
public function onWpEnqueueJs() {
|
|
|
|
|
|
|
29 |
/** @var \ICWP_WPSF_FeatureHandler_CommentsFilter $oMod */
|
30 |
$oMod = $this->getMod();
|
31 |
+
$oConn = $this->getCon();
|
32 |
+
|
33 |
+
$sAsset = 'shield-comments';
|
34 |
+
$sUnique = $oMod->prefix( 'shield-comments' );
|
35 |
+
wp_register_script(
|
36 |
+
$sUnique,
|
37 |
+
$oConn->getPluginUrl_Js( $sAsset ),
|
38 |
+
[ 'jquery' ],
|
39 |
+
$oConn->getVersion(),
|
40 |
+
true
|
41 |
+
);
|
42 |
+
wp_enqueue_script( $sUnique );
|
43 |
|
44 |
$nTs = Services::Request()->ts();
|
45 |
+
$aNonce = $oMod->getAjaxActionData( 'comment_token'.Services::IP()->getRequestIp() );
|
46 |
+
$aNonce[ 'ts' ] = $nTs;
|
47 |
+
$aNonce[ 'post_id' ] = Services::WpPost()->getCurrentPostId();
|
48 |
|
49 |
+
wp_localize_script(
|
50 |
+
$sUnique,
|
51 |
+
'shield_comments',
|
52 |
+
[
|
53 |
+
'ajax' => [
|
54 |
+
'comment_token' => $aNonce,
|
55 |
+
],
|
56 |
+
'vars' => [
|
57 |
+
'cbname' => 'cb_nombre'.rand(),
|
58 |
+
'botts' => $nTs,
|
59 |
+
'token' => 'not created',
|
60 |
+
'uniq' => $this->getUniqueFormId(),
|
61 |
+
'cooldown' => $oMod->getTokenCooldown(),
|
62 |
+
'expires' => $oMod->getTokenExpireInterval(),
|
63 |
+
],
|
64 |
+
'strings' => [
|
65 |
+
'label' => $oMod->getTextOpt( 'custom_message_checkbox' ),
|
66 |
+
'alert' => $oMod->getTextOpt( 'custom_message_alert' ),
|
67 |
+
'comment_reload' => $oMod->getTextOpt( 'custom_message_comment_reload' ),
|
68 |
+
'js_comment_wait' => $oMod->getTextOpt( 'custom_message_comment_wait' ),
|
69 |
+
],
|
70 |
+
'flags' => [
|
71 |
+
'gasp' => true,
|
72 |
+
'recap' => $oMod->isGoogleRecaptchaEnabled(),
|
73 |
+
]
|
74 |
+
]
|
75 |
);
|
|
|
|
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
+
* If the comment form component hasn't been printed, there's no comment form to protect.
|
|
|
|
|
80 |
*/
|
81 |
+
public function maybeDequeueScript() {
|
82 |
+
if ( empty( $this->bFormItemPrinted ) ) {
|
83 |
+
wp_dequeue_script( $this->getCon()->prefix( 'shield-comments' ) );
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
public function printGaspFormItems() {
|
88 |
+
$this->bFormItemPrinted = true;
|
89 |
+
echo $this->getMod()
|
90 |
+
->renderTemplate(
|
91 |
+
'snippets/comment_form_botbox.twig',
|
92 |
+
[ 'uniq' => $this->getUniqueFormId() ],
|
93 |
+
true
|
94 |
+
);
|
95 |
}
|
96 |
|
97 |
/**
|
107 |
}
|
108 |
return $this->sFormId;
|
109 |
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* @return string
|
113 |
+
* @deprecated 8.4
|
114 |
+
*/
|
115 |
+
private function getGaspCommentsHtml() {
|
116 |
+
return '';
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* @return string
|
121 |
+
* @deprecated 8.4
|
122 |
+
*/
|
123 |
+
public function tokenCreateStore() {
|
124 |
+
return '';
|
125 |
+
}
|
126 |
}
|
src/processors/events.php
CHANGED
@@ -110,4 +110,10 @@ class ICWP_WPSF_Processor_Events extends Shield\Modules\BaseShield\ShieldProcess
|
|
110 |
$oMod->getDbHandler_Events()
|
111 |
->commitEvents( $oMod->getRegisteredEvents( true ) );
|
112 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
}
|
110 |
$oMod->getDbHandler_Events()
|
111 |
->commitEvents( $oMod->getRegisteredEvents( true ) );
|
112 |
}
|
113 |
+
|
114 |
+
public function runDailyCron() {
|
115 |
+
( new Shield\Modules\Events\Consolidate\ConsolidateAllEvents() )
|
116 |
+
->setMod( $this->getMod() )
|
117 |
+
->run();
|
118 |
+
}
|
119 |
}
|
src/processors/firewall.php
CHANGED
@@ -228,7 +228,7 @@ class ICWP_WPSF_Processor_Firewall extends Modules\BaseShield\ShieldProcessor {
|
|
228 |
*/
|
229 |
protected function getFirewallPatterns( $sKey = null ) {
|
230 |
if ( !isset( $this->aPatterns ) ) {
|
231 |
-
$this->aPatterns = $this->
|
232 |
}
|
233 |
if ( !empty( $sKey ) ) {
|
234 |
return isset( $this->aPatterns[ $sKey ] ) ? $this->aPatterns[ $sKey ] : null;
|
228 |
*/
|
229 |
protected function getFirewallPatterns( $sKey = null ) {
|
230 |
if ( !isset( $this->aPatterns ) ) {
|
231 |
+
$this->aPatterns = $this->getOptions()->getDef( 'firewall_patterns' );
|
232 |
}
|
233 |
if ( !empty( $sKey ) ) {
|
234 |
return isset( $this->aPatterns[ $sKey ] ) ? $this->aPatterns[ $sKey ] : null;
|
src/processors/hackprotect_scan_base.php
CHANGED
@@ -408,11 +408,4 @@ abstract class ICWP_WPSF_Processor_ScanBase extends Shield\Modules\BaseShield\Sh
|
|
408 |
$this->oScanner = $oScanner;
|
409 |
return $this;
|
410 |
}
|
411 |
-
|
412 |
-
/**
|
413 |
-
* @param Shield\Scans\Base\BaseScanActionVO $oAction
|
414 |
-
* @deprecated 8.1
|
415 |
-
*/
|
416 |
-
public function postScanActionProcess( $oAction ) {
|
417 |
-
}
|
418 |
}
|
408 |
$this->oScanner = $oScanner;
|
409 |
return $this;
|
410 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
411 |
}
|
src/processors/hackprotect_scan_mal.php
CHANGED
@@ -162,7 +162,7 @@ class ICWP_WPSF_Processor_HackProtect_Mal extends ICWP_WPSF_Processor_ScanBase {
|
|
162 |
else {
|
163 |
$aContent[] = __( 'You should review these files and replace them with official versions if required.', 'wp-simple-firewall' );
|
164 |
$aContent[] = __( 'Alternatively you can have the plugin attempt to repair/replace these files automatically.', 'wp-simple-firewall' )
|
165 |
-
.' [<a href="https://
|
166 |
}
|
167 |
}
|
168 |
|
@@ -172,7 +172,7 @@ class ICWP_WPSF_Processor_HackProtect_Mal extends ICWP_WPSF_Processor_ScanBase {
|
|
172 |
|
173 |
if ( !$this->getCon()->isRelabelled() ) {
|
174 |
$aContent[] = '';
|
175 |
-
$aContent[] = '[ <a href="https://
|
176 |
}
|
177 |
|
178 |
return $aContent;
|
162 |
else {
|
163 |
$aContent[] = __( 'You should review these files and replace them with official versions if required.', 'wp-simple-firewall' );
|
164 |
$aContent[] = __( 'Alternatively you can have the plugin attempt to repair/replace these files automatically.', 'wp-simple-firewall' )
|
165 |
+
.' [<a href="https://shsec.io/g2">'.__( 'More Info', 'wp-simple-firewall' ).'</a>]';
|
166 |
}
|
167 |
}
|
168 |
|
172 |
|
173 |
if ( !$this->getCon()->isRelabelled() ) {
|
174 |
$aContent[] = '';
|
175 |
+
$aContent[] = '[ <a href="https://shsec.io/moreinfochecksum">'.__( 'More Info On This Scanner', 'wp-simple-firewall' ).'</a> ]';
|
176 |
}
|
177 |
|
178 |
return $aContent;
|
src/processors/hackprotect_scan_ufc.php
CHANGED
@@ -133,7 +133,7 @@ class ICWP_WPSF_Processor_HackProtect_Ufc extends ICWP_WPSF_Processor_ScanBase {
|
|
133 |
$aContent[] = '';
|
134 |
|
135 |
if ( !$oCon->isRelabelled() ) {
|
136 |
-
$aContent[] = sprintf( '[ <a href="https://
|
137 |
}
|
138 |
|
139 |
return $aContent;
|
133 |
$aContent[] = '';
|
134 |
|
135 |
if ( !$oCon->isRelabelled() ) {
|
136 |
+
$aContent[] = sprintf( '[ <a href="https://shsec.io/moreinfoufc">%s</a> ]', __( 'More Info On This Scanner', 'wp-simple-firewall' ) );
|
137 |
}
|
138 |
|
139 |
return $aContent;
|
src/processors/hackprotect_scan_wcf.php
CHANGED
@@ -109,7 +109,7 @@ class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
|
|
109 |
else {
|
110 |
$aContent[] = __( 'You should review these files and replace them with official versions if required.', 'wp-simple-firewall' );
|
111 |
$aContent[] = __( 'Alternatively you can have the plugin attempt to repair/replace these files automatically.', 'wp-simple-firewall' )
|
112 |
-
.' [<a href="https://
|
113 |
}
|
114 |
}
|
115 |
|
@@ -119,7 +119,7 @@ class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
|
|
119 |
|
120 |
if ( !$this->getCon()->isRelabelled() ) {
|
121 |
$aContent[] = '';
|
122 |
-
$aContent[] = '[ <a href="https://
|
123 |
}
|
124 |
|
125 |
return $aContent;
|
109 |
else {
|
110 |
$aContent[] = __( 'You should review these files and replace them with official versions if required.', 'wp-simple-firewall' );
|
111 |
$aContent[] = __( 'Alternatively you can have the plugin attempt to repair/replace these files automatically.', 'wp-simple-firewall' )
|
112 |
+
.' [<a href="https://shsec.io/moreinfochecksum">'.__( 'More Info', 'wp-simple-firewall' ).'</a>]';
|
113 |
}
|
114 |
}
|
115 |
|
119 |
|
120 |
if ( !$this->getCon()->isRelabelled() ) {
|
121 |
$aContent[] = '';
|
122 |
+
$aContent[] = '[ <a href="https://shsec.io/moreinfochecksum">'.__( 'More Info On This Scanner', 'wp-simple-firewall' ).'</a> ]';
|
123 |
}
|
124 |
|
125 |
return $aContent;
|
src/processors/hackprotect_scanner.php
CHANGED
@@ -215,11 +215,4 @@ class ICWP_WPSF_Processor_HackProtect_Scanner extends ShieldProcessor {
|
|
215 |
protected function getCronName() {
|
216 |
return $this->getCon()->prefix( $this->getOptions()->getDef( 'cron_all_scans' ) );
|
217 |
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* @param string $sScanSlug
|
221 |
-
* @deprecated 8.1
|
222 |
-
*/
|
223 |
-
public function launchScan( $sScanSlug ) {
|
224 |
-
}
|
225 |
}
|
215 |
protected function getCronName() {
|
216 |
return $this->getCon()->prefix( $this->getOptions()->getDef( 'cron_all_scans' ) );
|
217 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
}
|
src/processors/ips.php
CHANGED
@@ -391,9 +391,15 @@ class ICWP_WPSF_Processor_Ips extends ShieldProcessor {
|
|
391 |
/**
|
392 |
* @param string $sIp
|
393 |
* @return bool
|
|
|
394 |
*/
|
395 |
public function isIpOnWhiteList( $sIp ) {
|
396 |
-
|
|
|
|
|
|
|
|
|
|
|
397 |
}
|
398 |
|
399 |
/**
|
@@ -411,6 +417,7 @@ class ICWP_WPSF_Processor_Ips extends ShieldProcessor {
|
|
411 |
* @param string $sIp
|
412 |
* @param string $sList
|
413 |
* @return bool
|
|
|
414 |
*/
|
415 |
private function isIpOnList( $sIp, $sList ) {
|
416 |
$bOnList = false;
|
391 |
/**
|
392 |
* @param string $sIp
|
393 |
* @return bool
|
394 |
+
* @deprecated 8.4
|
395 |
*/
|
396 |
public function isIpOnWhiteList( $sIp ) {
|
397 |
+
$oIp = ( new IPs\Components\LookupIpOnList() )
|
398 |
+
->setMod( $this->getMod() )
|
399 |
+
->setIp( $sIp )
|
400 |
+
->setList( ICWP_WPSF_FeatureHandler_Ips::LIST_MANUAL_WHITE )
|
401 |
+
->lookup();
|
402 |
+
return $oIp instanceof Databases\IPs\EntryVO;
|
403 |
}
|
404 |
|
405 |
/**
|
417 |
* @param string $sIp
|
418 |
* @param string $sList
|
419 |
* @return bool
|
420 |
+
* @deprecated 8.4
|
421 |
*/
|
422 |
private function isIpOnList( $sIp, $sList ) {
|
423 |
$bOnList = false;
|
src/processors/lockdown.php
CHANGED
@@ -92,7 +92,7 @@ class ICWP_WPSF_Processor_Lockdown extends Modules\BaseShield\ShieldProcessor {
|
|
92 |
Services::WpGeneral()->wpDie( sprintf(
|
93 |
__( 'The "author" query parameter has been blocked by %s to protect against user login name fishing.', 'wp-simple-firewall' )
|
94 |
.sprintf( '<br /><a href="%s" target="_blank">%s</a>',
|
95 |
-
'https://
|
96 |
__( 'Learn More.', 'wp-simple-firewall' )
|
97 |
),
|
98 |
$this->getCon()->getHumanName()
|
92 |
Services::WpGeneral()->wpDie( sprintf(
|
93 |
__( 'The "author" query parameter has been blocked by %s to protect against user login name fishing.', 'wp-simple-firewall' )
|
94 |
.sprintf( '<br /><a href="%s" target="_blank">%s</a>',
|
95 |
+
'https://shsec.io/7l',
|
96 |
__( 'Learn More.', 'wp-simple-firewall' )
|
97 |
),
|
98 |
$this->getCon()->getHumanName()
|
src/processors/loginprotect_intentprovider_email.php
CHANGED
@@ -72,7 +72,7 @@ class ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth extends ICWP_WPSF_Processor
|
|
72 |
'value' => $this->fetchCodeFromRequest(),
|
73 |
'placeholder' => __( 'This code was just sent to your registered Email address.', 'wp-simple-firewall' ),
|
74 |
'text' => __( 'Email OTP', 'wp-simple-firewall' ),
|
75 |
-
'help_link' => 'https://
|
76 |
];
|
77 |
}
|
78 |
return $aFields;
|
@@ -150,7 +150,7 @@ class ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth extends ICWP_WPSF_Processor
|
|
150 |
];
|
151 |
|
152 |
if ( !$this->getCon()->isRelabelled() ) {
|
153 |
-
$aMessage[] = sprintf( '- <a href="%s" target="_blank">%s</a>', 'https://
|
154 |
$aContent[] = '';
|
155 |
}
|
156 |
|
72 |
'value' => $this->fetchCodeFromRequest(),
|
73 |
'placeholder' => __( 'This code was just sent to your registered Email address.', 'wp-simple-firewall' ),
|
74 |
'text' => __( 'Email OTP', 'wp-simple-firewall' ),
|
75 |
+
'help_link' => 'https://shsec.io/3t'
|
76 |
];
|
77 |
}
|
78 |
return $aFields;
|
150 |
];
|
151 |
|
152 |
if ( !$this->getCon()->isRelabelled() ) {
|
153 |
+
$aMessage[] = sprintf( '- <a href="%s" target="_blank">%s</a>', 'https://shsec.io/96', __( 'Why no login link?', 'wp-simple-firewall' ) );
|
154 |
$aContent[] = '';
|
155 |
}
|
156 |
|
src/processors/loginprotect_intentprovider_ga.php
CHANGED
@@ -208,7 +208,7 @@ class ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator extends ICWP_WPSF_Pro
|
|
208 |
'value' => '',
|
209 |
'placeholder' => __( 'Please use your Google Authenticator App to retrieve your code.', 'wp-simple-firewall' ),
|
210 |
'text' => __( 'Google Authenticator Code', 'wp-simple-firewall' ),
|
211 |
-
'help_link' => 'https://
|
212 |
'extras' => [
|
213 |
'onkeyup' => "this.value=this.value.replace(/[^\d]/g,'')"
|
214 |
]
|
208 |
'value' => '',
|
209 |
'placeholder' => __( 'Please use your Google Authenticator App to retrieve your code.', 'wp-simple-firewall' ),
|
210 |
'text' => __( 'Google Authenticator Code', 'wp-simple-firewall' ),
|
211 |
+
'help_link' => 'https://shsec.io/wpsf42',
|
212 |
'extras' => [
|
213 |
'onkeyup' => "this.value=this.value.replace(/[^\d]/g,'')"
|
214 |
]
|
src/processors/loginprotect_intentprovider_yubikey.php
CHANGED
@@ -252,7 +252,7 @@ class ICWP_WPSF_Processor_LoginProtect_Yubikey extends ICWP_WPSF_Processor_Login
|
|
252 |
'placeholder' => __( 'Use your Yubikey to generate a new code.', 'wp-simple-firewall' ),
|
253 |
'value' => '',
|
254 |
'text' => __( 'Yubikey OTP', 'wp-simple-firewall' ),
|
255 |
-
'help_link' => 'https://
|
256 |
];
|
257 |
}
|
258 |
return $aFields;
|
252 |
'placeholder' => __( 'Use your Yubikey to generate a new code.', 'wp-simple-firewall' ),
|
253 |
'value' => '',
|
254 |
'text' => __( 'Yubikey OTP', 'wp-simple-firewall' ),
|
255 |
+
'help_link' => 'https://shsec.io/4i'
|
256 |
];
|
257 |
}
|
258 |
return $aFields;
|
src/processors/loginprotect_wplogin.php
CHANGED
@@ -42,6 +42,8 @@ class ICWP_WPSF_Processor_LoginProtect_WpLogin extends Modules\BaseShield\Shield
|
|
42 |
* @return bool - true if conflict exists
|
43 |
*/
|
44 |
protected function checkForPluginConflict() {
|
|
|
|
|
45 |
|
46 |
$sMessage = '';
|
47 |
$bConflicted = false;
|
@@ -75,7 +77,7 @@ class ICWP_WPSF_Processor_LoginProtect_WpLogin extends Modules\BaseShield\Shield
|
|
75 |
__( 'Warning', 'wp-simple-firewall' ),
|
76 |
$sMessage
|
77 |
);
|
78 |
-
$
|
79 |
}
|
80 |
|
81 |
return $bConflicted;
|
@@ -84,7 +86,9 @@ class ICWP_WPSF_Processor_LoginProtect_WpLogin extends Modules\BaseShield\Shield
|
|
84 |
/**
|
85 |
* @return bool
|
86 |
*/
|
87 |
-
|
|
|
|
|
88 |
$sPath = Services::Request()->getPath();
|
89 |
if ( empty( $sPath ) ) {
|
90 |
|
@@ -93,7 +97,7 @@ class ICWP_WPSF_Processor_LoginProtect_WpLogin extends Modules\BaseShield\Shield
|
|
93 |
__( 'Warning', 'wp-simple-firewall' ),
|
94 |
__( 'Your login URL is unchanged because your current hosting/PHP configuration cannot parse the necessary information.', 'wp-simple-firewall' )
|
95 |
);
|
96 |
-
$
|
97 |
return true;
|
98 |
}
|
99 |
return false;
|
42 |
* @return bool - true if conflict exists
|
43 |
*/
|
44 |
protected function checkForPluginConflict() {
|
45 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
46 |
+
$oMod = $this->getMod();
|
47 |
|
48 |
$sMessage = '';
|
49 |
$bConflicted = false;
|
77 |
__( 'Warning', 'wp-simple-firewall' ),
|
78 |
$sMessage
|
79 |
);
|
80 |
+
$oMod->setFlashAdminNotice( $sNoticeMessage, true );
|
81 |
}
|
82 |
|
83 |
return $bConflicted;
|
86 |
/**
|
87 |
* @return bool
|
88 |
*/
|
89 |
+
private function checkForUnsupportedConfiguration() {
|
90 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oMod */
|
91 |
+
$oMod = $this->getMod();
|
92 |
$sPath = Services::Request()->getPath();
|
93 |
if ( empty( $sPath ) ) {
|
94 |
|
97 |
__( 'Warning', 'wp-simple-firewall' ),
|
98 |
__( 'Your login URL is unchanged because your current hosting/PHP configuration cannot parse the necessary information.', 'wp-simple-firewall' )
|
99 |
);
|
100 |
+
$oMod->setFlashAdminNotice( $sNoticeMessage, true );
|
101 |
return true;
|
102 |
}
|
103 |
return false;
|
src/processors/plugin_tracking.php
CHANGED
@@ -75,9 +75,9 @@ class ICWP_WPSF_Processor_Plugin_Tracking extends Shield\Modules\BaseShield\Shie
|
|
75 |
* Cron callback
|
76 |
*/
|
77 |
public function runDailyCron() {
|
78 |
-
/** @var ICWP_WPSF_FeatureHandler_Plugin $
|
79 |
-
$
|
80 |
-
if ( $
|
81 |
$this->sendTrackingData();
|
82 |
}
|
83 |
}
|
75 |
* Cron callback
|
76 |
*/
|
77 |
public function runDailyCron() {
|
78 |
+
/** @var \ICWP_WPSF_FeatureHandler_Plugin $oMod */
|
79 |
+
$oMod = $this->getMod();
|
80 |
+
if ( $oMod->isTrackingEnabled() ) {
|
81 |
$this->sendTrackingData();
|
82 |
}
|
83 |
}
|
src/processors/sessions.php
CHANGED
@@ -202,21 +202,4 @@ class ICWP_WPSF_Processor_Sessions extends Modules\BaseShield\ShieldProcessor {
|
|
202 |
$oSel = $oMod->getDbHandler_Sessions()->getQuerySelector();
|
203 |
return $oSel->retrieveUserSession( $sSessionId, $sUsername );
|
204 |
}
|
205 |
-
|
206 |
-
/**
|
207 |
-
* @return $this
|
208 |
-
* @deprecated 8.3.0
|
209 |
-
*/
|
210 |
-
private function clearCurrentSession() {
|
211 |
-
$this->oCurrent = null;
|
212 |
-
return $this;
|
213 |
-
}
|
214 |
-
|
215 |
-
/**
|
216 |
-
* @return string
|
217 |
-
* @deprecated 8.3.0
|
218 |
-
*/
|
219 |
-
private function getSessionId() {
|
220 |
-
return $this->getCon()->getSessionId();
|
221 |
-
}
|
222 |
}
|
202 |
$oSel = $oMod->getDbHandler_Sessions()->getQuerySelector();
|
203 |
return $oSel->retrieveUserSession( $sSessionId, $sUsername );
|
204 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
}
|
src/processors/traffic_logger.php
CHANGED
@@ -45,15 +45,15 @@ class ICWP_WPSF_Processor_TrafficLogger extends ShieldProcessor {
|
|
45 |
* @return bool
|
46 |
*/
|
47 |
protected function isCustomExcluded() {
|
48 |
-
/** @var ICWP_WPSF_FeatureHandler_Traffic $
|
49 |
-
$
|
50 |
$oReq = Services::Request();
|
51 |
|
52 |
$sAgent = $oReq->getUserAgent();
|
53 |
$sPath = $oReq->getPath().( empty( $_GET ) ? '' : '?'.http_build_query( $_GET ) );
|
54 |
|
55 |
$bExcluded = false;
|
56 |
-
foreach ( $
|
57 |
if ( stripos( $sAgent, $sExcl ) !== false || stripos( $sPath, $sExcl ) !== false ) {
|
58 |
$bExcluded = true;
|
59 |
}
|
45 |
* @return bool
|
46 |
*/
|
47 |
protected function isCustomExcluded() {
|
48 |
+
/** @var \ICWP_WPSF_FeatureHandler_Traffic $oMod */
|
49 |
+
$oMod = $this->getMod();
|
50 |
$oReq = Services::Request();
|
51 |
|
52 |
$sAgent = $oReq->getUserAgent();
|
53 |
$sPath = $oReq->getPath().( empty( $_GET ) ? '' : '?'.http_build_query( $_GET ) );
|
54 |
|
55 |
$bExcluded = false;
|
56 |
+
foreach ( $oMod->getCustomExclusions() as $sExcl ) {
|
57 |
if ( stripos( $sAgent, $sExcl ) !== false || stripos( $sPath, $sExcl ) !== false ) {
|
58 |
$bExcluded = true;
|
59 |
}
|
src/processors/usermanagement_passwords.php
CHANGED
@@ -14,7 +14,6 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends Modules\BaseShield\Sh
|
|
14 |
add_filter( 'registration_errors', [ $this, 'checkPassword' ], 100, 3 );
|
15 |
add_action( 'user_profile_update_errors', [ $this, 'checkPassword' ], 100, 3 );
|
16 |
add_action( 'validate_password_reset', [ $this, 'checkPassword' ], 100, 3 );
|
17 |
-
add_filter( 'login_message', [ $this, 'addPasswordResetMessage' ] );
|
18 |
}
|
19 |
|
20 |
/**
|
@@ -41,7 +40,7 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends Modules\BaseShield\Sh
|
|
41 |
private function captureLogin( $oUser ) {
|
42 |
$sPassword = $this->getLoginPassword();
|
43 |
|
44 |
-
if (
|
45 |
&& $oUser instanceof WP_User && !empty( $sPassword ) ) {
|
46 |
$this->setLoginCaptured();
|
47 |
try {
|
@@ -63,18 +62,6 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends Modules\BaseShield\Sh
|
|
63 |
}
|
64 |
}
|
65 |
|
66 |
-
/**
|
67 |
-
* @param string $sMessage
|
68 |
-
* @return string
|
69 |
-
*/
|
70 |
-
public function addPasswordResetMessage( $sMessage = '' ) {
|
71 |
-
$sFlushed = $this->loadWpNotices()
|
72 |
-
->flushFlash()
|
73 |
-
->getFlashText();
|
74 |
-
// we overwrite rather than augment the message
|
75 |
-
return empty( $sFlushed ) ? $sMessage : sprintf( '<p class="message">%s</p>', $sFlushed );
|
76 |
-
}
|
77 |
-
|
78 |
/**
|
79 |
* @param WP_User $oUser
|
80 |
*/
|
@@ -87,15 +74,15 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends Modules\BaseShield\Sh
|
|
87 |
}
|
88 |
|
89 |
private function processExpiredPassword() {
|
90 |
-
/** @var \ICWP_WPSF_FeatureHandler_UserManagement $
|
91 |
-
$
|
92 |
-
if ( $
|
93 |
$nPassStartedAt = (int)$this->getCon()->getCurrentUserMeta()->pass_started_at;
|
94 |
if ( $nPassStartedAt > 0 ) {
|
95 |
-
if ( Services::Request()->ts() - $nPassStartedAt > $
|
96 |
$this->getCon()->fireEvent( 'pass_expired' );
|
97 |
$this->redirectToResetPassword(
|
98 |
-
sprintf( __( 'Your password has expired (after %s days).', 'wp-simple-firewall' ), $
|
99 |
);
|
100 |
}
|
101 |
}
|
@@ -103,7 +90,7 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends Modules\BaseShield\Sh
|
|
103 |
}
|
104 |
|
105 |
private function processFailedCheckPassword() {
|
106 |
-
/** @var ICWP_WPSF_FeatureHandler_UserManagement $oFO */
|
107 |
$oFO = $this->getMod();
|
108 |
$oMeta = $this->getCon()->getCurrentUserMeta();
|
109 |
|
@@ -186,12 +173,12 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends Modules\BaseShield\Sh
|
|
186 |
* @throws \Exception
|
187 |
*/
|
188 |
protected function applyPasswordChecks( $sPassword ) {
|
189 |
-
/** @var ICWP_WPSF_FeatureHandler_UserManagement $
|
190 |
-
$
|
191 |
|
192 |
$this->testPasswordMeetsMinimumLength( $sPassword );
|
193 |
$this->testPasswordMeetsMinimumStrength( $sPassword );
|
194 |
-
if ( $
|
195 |
$this->sendRequestToPwnedRange( $sPassword );
|
196 |
}
|
197 |
}
|
@@ -258,12 +245,12 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends Modules\BaseShield\Sh
|
|
258 |
* @param string $sPass
|
259 |
* @return bool
|
260 |
* @throws \Exception
|
261 |
-
* @deprecated 8.
|
262 |
*/
|
263 |
protected function sendRequestToPwned( $sPass ) {
|
264 |
$oHttpReq = Services::HttpRequest();
|
265 |
$bSuccess = $oHttpReq->get(
|
266 |
-
sprintf( '%s/%s', $this->
|
267 |
[
|
268 |
'headers' => [ 'user-agent' => sprintf( '%s WP Plugin-v%s', 'Shield', $this->getCon()->getVersion() ) ]
|
269 |
]
|
@@ -321,7 +308,7 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends Modules\BaseShield\Sh
|
|
321 |
$sSubHash = substr( $sPassHash, 0, 5 );
|
322 |
|
323 |
$bSuccess = $oHttpReq->get(
|
324 |
-
sprintf( '%s/%s', $this->
|
325 |
[
|
326 |
'headers' => [ 'user-agent' => sprintf( '%s WP Plugin-v%s', 'Shield', $this->getCon()->getVersion() ) ]
|
327 |
]
|
@@ -383,7 +370,7 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends Modules\BaseShield\Sh
|
|
383 |
|
384 |
// Edd: edd_user_pass; Woo: password;
|
385 |
foreach ( [ 'pwd', 'pass1' ] as $sKey ) {
|
386 |
-
$sP =
|
387 |
if ( !empty( $sP ) ) {
|
388 |
$sPass = $sP;
|
389 |
break;
|
14 |
add_filter( 'registration_errors', [ $this, 'checkPassword' ], 100, 3 );
|
15 |
add_action( 'user_profile_update_errors', [ $this, 'checkPassword' ], 100, 3 );
|
16 |
add_action( 'validate_password_reset', [ $this, 'checkPassword' ], 100, 3 );
|
|
|
17 |
}
|
18 |
|
19 |
/**
|
40 |
private function captureLogin( $oUser ) {
|
41 |
$sPassword = $this->getLoginPassword();
|
42 |
|
43 |
+
if ( Services::Request()->isPost() && !$this->isLoginCaptured()
|
44 |
&& $oUser instanceof WP_User && !empty( $sPassword ) ) {
|
45 |
$this->setLoginCaptured();
|
46 |
try {
|
62 |
}
|
63 |
}
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
/**
|
66 |
* @param WP_User $oUser
|
67 |
*/
|
74 |
}
|
75 |
|
76 |
private function processExpiredPassword() {
|
77 |
+
/** @var \ICWP_WPSF_FeatureHandler_UserManagement $oMod */
|
78 |
+
$oMod = $this->getMod();
|
79 |
+
if ( $oMod->isPassExpirationEnabled() ) {
|
80 |
$nPassStartedAt = (int)$this->getCon()->getCurrentUserMeta()->pass_started_at;
|
81 |
if ( $nPassStartedAt > 0 ) {
|
82 |
+
if ( Services::Request()->ts() - $nPassStartedAt > $oMod->getPassExpireTimeout() ) {
|
83 |
$this->getCon()->fireEvent( 'pass_expired' );
|
84 |
$this->redirectToResetPassword(
|
85 |
+
sprintf( __( 'Your password has expired (after %s days).', 'wp-simple-firewall' ), $oMod->getPassExpireDays() )
|
86 |
);
|
87 |
}
|
88 |
}
|
90 |
}
|
91 |
|
92 |
private function processFailedCheckPassword() {
|
93 |
+
/** @var \ICWP_WPSF_FeatureHandler_UserManagement $oFO */
|
94 |
$oFO = $this->getMod();
|
95 |
$oMeta = $this->getCon()->getCurrentUserMeta();
|
96 |
|
173 |
* @throws \Exception
|
174 |
*/
|
175 |
protected function applyPasswordChecks( $sPassword ) {
|
176 |
+
/** @var \ICWP_WPSF_FeatureHandler_UserManagement $oMod */
|
177 |
+
$oMod = $this->getMod();
|
178 |
|
179 |
$this->testPasswordMeetsMinimumLength( $sPassword );
|
180 |
$this->testPasswordMeetsMinimumStrength( $sPassword );
|
181 |
+
if ( $oMod->isPassPreventPwned() ) {
|
182 |
$this->sendRequestToPwnedRange( $sPassword );
|
183 |
}
|
184 |
}
|
245 |
* @param string $sPass
|
246 |
* @return bool
|
247 |
* @throws \Exception
|
248 |
+
* @deprecated 8.4
|
249 |
*/
|
250 |
protected function sendRequestToPwned( $sPass ) {
|
251 |
$oHttpReq = Services::HttpRequest();
|
252 |
$bSuccess = $oHttpReq->get(
|
253 |
+
sprintf( '%s/%s', $this->getOptions()->getDef( 'pwned_api_url_password_single' ), hash( 'sha1', $sPass ) ),
|
254 |
[
|
255 |
'headers' => [ 'user-agent' => sprintf( '%s WP Plugin-v%s', 'Shield', $this->getCon()->getVersion() ) ]
|
256 |
]
|
308 |
$sSubHash = substr( $sPassHash, 0, 5 );
|
309 |
|
310 |
$bSuccess = $oHttpReq->get(
|
311 |
+
sprintf( '%s/%s', $this->getOptions()->getDef( 'pwned_api_url_password_range' ), $sSubHash ),
|
312 |
[
|
313 |
'headers' => [ 'user-agent' => sprintf( '%s WP Plugin-v%s', 'Shield', $this->getCon()->getVersion() ) ]
|
314 |
]
|
370 |
|
371 |
// Edd: edd_user_pass; Woo: password;
|
372 |
foreach ( [ 'pwd', 'pass1' ] as $sKey ) {
|
373 |
+
$sP = Services::Request()->post( $sKey );
|
374 |
if ( !empty( $sP ) ) {
|
375 |
$sPass = $sP;
|
376 |
break;
|
src/query/base/statistics_base.php
DELETED
@@ -1,252 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
require_once( dirname( dirname( __DIR__ ) ).'/lib/vendor/autoload.php' );
|
4 |
-
|
5 |
-
class ICWP_WPSF_Query_Statistics_Base extends ICWP_WPSF_Query_Base {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @var ICWP_WPSF_FeatureHandler_Statistics
|
9 |
-
*/
|
10 |
-
protected $oFO;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var int
|
14 |
-
*/
|
15 |
-
protected $nDateFrom;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var int
|
19 |
-
*/
|
20 |
-
protected $nDateTo;
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @var int
|
24 |
-
*/
|
25 |
-
protected $nQueryLimit;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @var array
|
29 |
-
*/
|
30 |
-
protected $aStatKeys;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @var bool
|
34 |
-
*/
|
35 |
-
protected $bSelectDeleted;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* @return StatisticsReportingVO[]
|
39 |
-
*/
|
40 |
-
protected function runQuery() {
|
41 |
-
|
42 |
-
$sQuery = $this->buildQuery();
|
43 |
-
$mResult = $this->loadDbProcessor()->selectCustom( $sQuery, OBJECT );
|
44 |
-
|
45 |
-
// TODO: NOT PHP 5.2!
|
46 |
-
if ( is_array( $mResult ) ) {
|
47 |
-
include_once( __DIR__.'/StatisticsReportingVO.php' );
|
48 |
-
$mResult = array_map(
|
49 |
-
function ( $oData ) {
|
50 |
-
return new StatisticsReportingVO( $oData );
|
51 |
-
},
|
52 |
-
$mResult
|
53 |
-
);
|
54 |
-
}
|
55 |
-
else {
|
56 |
-
$mResult = array();
|
57 |
-
}
|
58 |
-
return $mResult;
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* @param bool $bIsCount
|
63 |
-
* @return string
|
64 |
-
*/
|
65 |
-
protected function buildQuery( $bIsCount = false ) {
|
66 |
-
$sQuery = "
|
67 |
-
SELECT %s
|
68 |
-
FROM `%s`
|
69 |
-
WHERE
|
70 |
-
`created_at` > %s AND `created_at` < %s
|
71 |
-
AND `deleted_at` %s 0
|
72 |
-
%s
|
73 |
-
%s
|
74 |
-
";
|
75 |
-
|
76 |
-
$sStatPart = $this->buildStatKeyQuery();
|
77 |
-
return sprintf( $sQuery,
|
78 |
-
$bIsCount ? 'COUNT(*) AS total' : '*',
|
79 |
-
$this->getMod()->getFullEventsTableName(),
|
80 |
-
$this->getDateFrom(),
|
81 |
-
$this->getDateTo(),
|
82 |
-
$this->isSelectDeleted() ? '>' : '=',
|
83 |
-
empty( $sStatPart ) ? $sStatPart : 'AND '.$sStatPart,
|
84 |
-
$this->getQueryLimit()
|
85 |
-
);
|
86 |
-
}
|
87 |
-
|
88 |
-
protected function deleteAllFromTo() {
|
89 |
-
$this->loadDbProcessor()->doSql( $this->buildDeleteQuery() );
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* @return string
|
94 |
-
*/
|
95 |
-
protected function buildDeleteQuery() {
|
96 |
-
$sQuery = "
|
97 |
-
DELETE FROM `%s`
|
98 |
-
WHERE
|
99 |
-
`created_at` > %s AND `created_at` < %s
|
100 |
-
%s
|
101 |
-
";
|
102 |
-
|
103 |
-
$sStatPart = $this->buildStatKeyQuery();
|
104 |
-
return sprintf( $sQuery,
|
105 |
-
$this->getMod()->getFullEventsTableName(),
|
106 |
-
$this->getDateFrom(),
|
107 |
-
$this->getDateTo(),
|
108 |
-
empty( $sStatPart ) ? $sStatPart : 'AND '.$sStatPart
|
109 |
-
);
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* @return string
|
114 |
-
*/
|
115 |
-
protected function buildStatKeyQuery() {
|
116 |
-
|
117 |
-
$sQuery = '';
|
118 |
-
if ( $this->hasStatKeys() ) {
|
119 |
-
$aKeys = $this->getStatKeys();
|
120 |
-
if ( count( $aKeys ) == 1 ) {
|
121 |
-
$sQuery = sprintf( '`stat_key` = "%s"', $aKeys[ 0 ] );
|
122 |
-
}
|
123 |
-
else {
|
124 |
-
$sQuery = sprintf( '`stat_key` IN ("%s")', implode( '","', $aKeys ) );
|
125 |
-
}
|
126 |
-
}
|
127 |
-
|
128 |
-
return $sQuery;
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
* @return int
|
133 |
-
*/
|
134 |
-
public function getDateFrom() {
|
135 |
-
return isset( $this->nDateFrom ) ? (int)$this->nDateFrom : 0;
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* @return int
|
140 |
-
*/
|
141 |
-
public function getDateTo() {
|
142 |
-
return isset( $this->nDateTo ) ? (int)$this->nDateTo : $this->loadRequest()->ts();
|
143 |
-
}
|
144 |
-
|
145 |
-
/**
|
146 |
-
* @return int
|
147 |
-
*/
|
148 |
-
public function getQueryLimit() {
|
149 |
-
return isset( $this->nQueryLimit ) ? 'LIMIT '.$this->nQueryLimit : '';
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* @return array
|
154 |
-
*/
|
155 |
-
public function getStatKeys() {
|
156 |
-
if ( !isset( $this->aStatKeys ) ) {
|
157 |
-
$this->aStatKeys = array();
|
158 |
-
}
|
159 |
-
return $this->aStatKeys;
|
160 |
-
}
|
161 |
-
|
162 |
-
/**
|
163 |
-
* @return bool
|
164 |
-
*/
|
165 |
-
public function hasStatKeys() {
|
166 |
-
return ( count( $this->getStatKeys() ) > 0 );
|
167 |
-
}
|
168 |
-
|
169 |
-
/**
|
170 |
-
* @return bool
|
171 |
-
*/
|
172 |
-
public function isSelectDeleted() {
|
173 |
-
return isset( $this->bSelectDeleted ) ? (bool)$this->bSelectDeleted : false;
|
174 |
-
}
|
175 |
-
|
176 |
-
/**
|
177 |
-
* @param int $nDateFrom
|
178 |
-
* @return $this
|
179 |
-
*/
|
180 |
-
public function setDateFrom( $nDateFrom ) {
|
181 |
-
$this->nDateFrom = $nDateFrom;
|
182 |
-
return $this;
|
183 |
-
}
|
184 |
-
|
185 |
-
/**
|
186 |
-
* @param int $nDateTo
|
187 |
-
* @return $this
|
188 |
-
*/
|
189 |
-
public function setDateTo( $nDateTo ) {
|
190 |
-
$this->nDateTo = $nDateTo;
|
191 |
-
return $this;
|
192 |
-
}
|
193 |
-
|
194 |
-
/**
|
195 |
-
* @param int $nLimit
|
196 |
-
* @return $this
|
197 |
-
*/
|
198 |
-
public function setQueryLimit( $nLimit ) {
|
199 |
-
$this->nQueryLimit = $nLimit;
|
200 |
-
return $this;
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* @param string $sStatKey
|
205 |
-
* @return $this
|
206 |
-
*/
|
207 |
-
public function addStatKey( $sStatKey ) {
|
208 |
-
$aKeys = $this->getStatKeys();
|
209 |
-
$sStatKey = esc_sql( trim( $sStatKey ) );
|
210 |
-
if ( !in_array( $sStatKey, $aKeys ) ) {
|
211 |
-
$aKeys[] = $sStatKey;
|
212 |
-
}
|
213 |
-
return $this->setStatKeys( $aKeys );
|
214 |
-
}
|
215 |
-
|
216 |
-
/**
|
217 |
-
* @param bool $bSelectDeleted
|
218 |
-
* @return $this
|
219 |
-
*/
|
220 |
-
public function setSelectDeleted( $bSelectDeleted ) {
|
221 |
-
$this->bSelectDeleted = $bSelectDeleted;
|
222 |
-
return $this;
|
223 |
-
}
|
224 |
-
|
225 |
-
/**
|
226 |
-
* @param array $aKeys
|
227 |
-
* @return $this
|
228 |
-
*/
|
229 |
-
public function setStatKeys( $aKeys ) {
|
230 |
-
if ( !is_array( $aKeys ) ) {
|
231 |
-
$aKeys = array();
|
232 |
-
}
|
233 |
-
$this->aStatKeys = $aKeys;
|
234 |
-
return $this;
|
235 |
-
}
|
236 |
-
|
237 |
-
/**
|
238 |
-
* @return ICWP_WPSF_FeatureHandler_Statistics
|
239 |
-
*/
|
240 |
-
protected function getMod() {
|
241 |
-
return $this->oFO;
|
242 |
-
}
|
243 |
-
|
244 |
-
/**
|
245 |
-
* @param ICWP_WPSF_FeatureHandler_Statistics $oFeature
|
246 |
-
* @return $this
|
247 |
-
*/
|
248 |
-
public function setFeature( $oFeature ) {
|
249 |
-
$this->oFO = $oFeature;
|
250 |
-
return $this;
|
251 |
-
}
|
252 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/query/statistics/reporting.php
DELETED
@@ -1,11 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class ICWP_WPSF_Query_Statistics_Reporting extends ICWP_WPSF_Query_Statistics_Base {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @return int
|
7 |
-
*/
|
8 |
-
public function countQuery() {
|
9 |
-
return $this->loadDbProcessor()->doSql( $this->buildQuery() );
|
10 |
-
}
|
11 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/wizards/base.php
CHANGED
@@ -274,7 +274,7 @@ abstract class ICWP_WPSF_Wizard_Base extends \FernleafSystems\Wordpress\Plugin\S
|
|
274 |
],
|
275 |
'hrefs' => [
|
276 |
'dashboard' => $oFO->getUrl_AdminPage(),
|
277 |
-
'goprofooter' => 'https://
|
278 |
],
|
279 |
'ajax' => [
|
280 |
'content' => $oFO->getAjaxActionData( 'wiz_process_step' ),
|
@@ -342,7 +342,7 @@ abstract class ICWP_WPSF_Wizard_Base extends \FernleafSystems\Wordpress\Plugin\S
|
|
342 |
],
|
343 |
'hrefs' => [
|
344 |
'dashboard' => $oFO->getUrl_AdminPage(),
|
345 |
-
'goprofooter' => 'https://
|
346 |
],
|
347 |
'ajax' => [
|
348 |
'content' => $oFO->getAjaxActionData( 'wiz_process_step' ),
|
@@ -439,7 +439,7 @@ abstract class ICWP_WPSF_Wizard_Base extends \FernleafSystems\Wordpress\Plugin\S
|
|
439 |
],
|
440 |
'hrefs' => [
|
441 |
'dashboard' => $oMod->getUrl_AdminPage(),
|
442 |
-
'gopro' => 'https://
|
443 |
],
|
444 |
'imgs' => [],
|
445 |
'data' => [
|
274 |
],
|
275 |
'hrefs' => [
|
276 |
'dashboard' => $oFO->getUrl_AdminPage(),
|
277 |
+
'goprofooter' => 'https://shsec.io/goprofooter',
|
278 |
],
|
279 |
'ajax' => [
|
280 |
'content' => $oFO->getAjaxActionData( 'wiz_process_step' ),
|
342 |
],
|
343 |
'hrefs' => [
|
344 |
'dashboard' => $oFO->getUrl_AdminPage(),
|
345 |
+
'goprofooter' => 'https://shsec.io/goprofooter',
|
346 |
],
|
347 |
'ajax' => [
|
348 |
'content' => $oFO->getAjaxActionData( 'wiz_process_step' ),
|
439 |
],
|
440 |
'hrefs' => [
|
441 |
'dashboard' => $oMod->getUrl_AdminPage(),
|
442 |
+
'gopro' => 'https://shsec.io/ap',
|
443 |
],
|
444 |
'imgs' => [],
|
445 |
'data' => [
|
src/wizards/base_wpsf.php
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
3 |
/**
|
4 |
* Class ICWP_WPSF_Wizard_BaseWpsf
|
5 |
*/
|
@@ -36,7 +38,7 @@ abstract class ICWP_WPSF_Wizard_BaseWpsf extends ICWP_WPSF_Wizard_Base {
|
|
36 |
|
37 |
switch ( $sStep ) {
|
38 |
case 'security_admin_verify':
|
39 |
-
$aAdditional = array( 'current_index' =>
|
40 |
break;
|
41 |
default:
|
42 |
$aAdditional = parent::getRenderData_SlideExtra( $sStep );
|
@@ -91,7 +93,7 @@ abstract class ICWP_WPSF_Wizard_BaseWpsf extends ICWP_WPSF_Wizard_Base {
|
|
91 |
* @return \FernleafSystems\Utilities\Response
|
92 |
*/
|
93 |
private function wizardSecurityAdminVerify() {
|
94 |
-
$sKey =
|
95 |
|
96 |
$oResponse = new \FernleafSystems\Utilities\Response();
|
97 |
|
1 |
<?php
|
2 |
|
3 |
+
use FernleafSystems\Wordpress\Services\Services;
|
4 |
+
|
5 |
/**
|
6 |
* Class ICWP_WPSF_Wizard_BaseWpsf
|
7 |
*/
|
38 |
|
39 |
switch ( $sStep ) {
|
40 |
case 'security_admin_verify':
|
41 |
+
$aAdditional = array( 'current_index' => Services::Request()->post( 'current_index' ) );
|
42 |
break;
|
43 |
default:
|
44 |
$aAdditional = parent::getRenderData_SlideExtra( $sStep );
|
93 |
* @return \FernleafSystems\Utilities\Response
|
94 |
*/
|
95 |
private function wizardSecurityAdminVerify() {
|
96 |
+
$sKey = Services::Request()->post( 'AccessKey' );
|
97 |
|
98 |
$oResponse = new \FernleafSystems\Utilities\Response();
|
99 |
|
src/wizards/login_protect.php
CHANGED
@@ -150,10 +150,10 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
150 |
* @return \FernleafSystems\Utilities\Response
|
151 |
*/
|
152 |
private function processMultiSelect() {
|
153 |
-
/** @var ICWP_WPSF_FeatureHandler_LoginProtect $oFO */
|
154 |
$oFO = $this->getMod();
|
155 |
|
156 |
-
$bEnabledMulti =
|
157 |
$oFO->setIsChainedAuth( $bEnabledMulti );
|
158 |
$sMessage = sprintf( __( 'Multi-Factor Authentication was %s for the site.', 'wp-simple-firewall' ),
|
159 |
$bEnabledMulti ? __( 'enabled', 'wp-simple-firewall' ) : __( 'disabled', 'wp-simple-firewall' )
|
150 |
* @return \FernleafSystems\Utilities\Response
|
151 |
*/
|
152 |
private function processMultiSelect() {
|
153 |
+
/** @var \ICWP_WPSF_FeatureHandler_LoginProtect $oFO */
|
154 |
$oFO = $this->getMod();
|
155 |
|
156 |
+
$bEnabledMulti = Services::Request()->post( 'multiselect' ) === 'Y';
|
157 |
$oFO->setIsChainedAuth( $bEnabledMulti );
|
158 |
$sMessage = sprintf( __( 'Multi-Factor Authentication was %s for the site.', 'wp-simple-firewall' ),
|
159 |
$bEnabledMulti ? __( 'enabled', 'wp-simple-firewall' ) : __( 'disabled', 'wp-simple-firewall' )
|
src/wizards/plugin.php
CHANGED
@@ -194,7 +194,7 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
194 |
case 'ip_detect':
|
195 |
$aAdditional = [
|
196 |
'hrefs' => [
|
197 |
-
'visitor_ip' => 'https://
|
198 |
]
|
199 |
];
|
200 |
break;
|
@@ -203,7 +203,7 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
203 |
case 'import':
|
204 |
$aAdditional = [
|
205 |
'hrefs' => [
|
206 |
-
'blog_importexport' => 'https://
|
207 |
],
|
208 |
'imgs' => [
|
209 |
'shieldnetworkmini' => $oConn->getPluginUrl_Image( 'shield/shieldnetworkmini.png' ),
|
@@ -219,7 +219,7 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
219 |
'user_email' => $oUser->user_email
|
220 |
],
|
221 |
'hrefs' => [
|
222 |
-
'privacy_policy' => $this->
|
223 |
],
|
224 |
];
|
225 |
break;
|
@@ -272,7 +272,7 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
|
|
272 |
case 'import':
|
273 |
$aAdditional = [
|
274 |
'hrefs' => [
|
275 |
-
'blog_importexport' => 'https://
|
276 |
],
|
277 |
'imgs' => [
|
278 |
'shieldnetworkmini' => $oConn->getPluginUrl_Image( 'shield/shieldnetworkmini.png' ),
|
194 |
case 'ip_detect':
|
195 |
$aAdditional = [
|
196 |
'hrefs' => [
|
197 |
+
'visitor_ip' => 'https://shsec.io/visitorip',
|
198 |
]
|
199 |
];
|
200 |
break;
|
203 |
case 'import':
|
204 |
$aAdditional = [
|
205 |
'hrefs' => [
|
206 |
+
'blog_importexport' => 'https://shsec.io/av'
|
207 |
],
|
208 |
'imgs' => [
|
209 |
'shieldnetworkmini' => $oConn->getPluginUrl_Image( 'shield/shieldnetworkmini.png' ),
|
219 |
'user_email' => $oUser->user_email
|
220 |
],
|
221 |
'hrefs' => [
|
222 |
+
'privacy_policy' => $this->getOptions()->getDef( 'href_privacy_policy' )
|
223 |
],
|
224 |
];
|
225 |
break;
|
272 |
case 'import':
|
273 |
$aAdditional = [
|
274 |
'hrefs' => [
|
275 |
+
'blog_importexport' => 'https://shsec.io/av'
|
276 |
],
|
277 |
'imgs' => [
|
278 |
'shieldnetworkmini' => $oConn->getPluginUrl_Image( 'shield/shieldnetworkmini.png' ),
|
templates/php/snippets/module-help-admin_access_restriction.php
CHANGED
@@ -32,11 +32,11 @@
|
|
32 |
do the 1st option - which is the recommended.
|
33 |
</p>
|
34 |
<ol>
|
35 |
-
<li>Follow the guide <a href="https://
|
36 |
turned off the Shield plugin you can go in and set the access key to whatever you like,
|
37 |
and then remove the 'forceoff' file.
|
38 |
</li>
|
39 |
-
<li>Follow the guide <a href="https://
|
40 |
your plugin to default settings.
|
41 |
</li>
|
42 |
</ol>
|
32 |
do the 1st option - which is the recommended.
|
33 |
</p>
|
34 |
<ol>
|
35 |
+
<li>Follow the guide <a href="https://shsec.io/am" target="_blank">set out here</a>. Once you've
|
36 |
turned off the Shield plugin you can go in and set the access key to whatever you like,
|
37 |
and then remove the 'forceoff' file.
|
38 |
</li>
|
39 |
+
<li>Follow the guide <a href="https://shsec.io/al" target="_blank">set out here</a> to reset
|
40 |
your plugin to default settings.
|
41 |
</li>
|
42 |
</ol>
|
templates/php/snippets/module-help-firewall.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<h5>What is the Firewall?</h5>
|
2 |
<p>This is a big topic and is best covered in-detail in our helpdesk section.</p>
|
3 |
-
<p><a href="https://
|
4 |
https://icontrolwp.freshdesk.com/support/solutions/folders/3000000263</a> .
|
5 |
</p>
|
1 |
<h5>What is the Firewall?</h5>
|
2 |
<p>This is a big topic and is best covered in-detail in our helpdesk section.</p>
|
3 |
+
<p><a href="https://shsec.io/ak" target="_blank">
|
4 |
https://icontrolwp.freshdesk.com/support/solutions/folders/3000000263</a> .
|
5 |
</p>
|
templates/php/snippets/module-help-headers.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
<h5>What are HTTP Headers?</h5>
|
2 |
<p>This can be a complex topic, but it's worth taking some time to read about it.</p>
|
3 |
-
<p>We've provided some further <a href="https://
|
4 |
on the topic to help you get your... "head" around it. ;)</p>
|
1 |
<h5>What are HTTP Headers?</h5>
|
2 |
<p>This can be a complex topic, but it's worth taking some time to read about it.</p>
|
3 |
+
<p>We've provided some further <a href="https://shsec.io/aj" target="_blank">in-depth articles</a>
|
4 |
on the topic to help you get your... "head" around it. ;)</p>
|
templates/php/snippets/module-help-login_protect.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
<dt>What is multi-factor authentication (MFA)?</dt>
|
7 |
<dd>
|
8 |
<p>See the link below for a complete explanation of MFA.</p>
|
9 |
-
<p><a href="https://
|
10 |
https://www.icontrolwp.com/blog/security-multi-two-factor-authentication-wordpress/</a> .
|
11 |
</p>
|
12 |
<p>Please read this. It really helps.</p>
|
6 |
<dt>What is multi-factor authentication (MFA)?</dt>
|
7 |
<dd>
|
8 |
<p>See the link below for a complete explanation of MFA.</p>
|
9 |
+
<p><a href="https://shsec.io/ai" target="_blank">
|
10 |
https://www.icontrolwp.com/blog/security-multi-two-factor-authentication-wordpress/</a> .
|
11 |
</p>
|
12 |
<p>Please read this. It really helps.</p>
|
templates/php/snippets/module-help-plugin.php
CHANGED
@@ -16,7 +16,7 @@
|
|
16 |
public IP address.
|
17 |
</p>
|
18 |
<p>Don't know your IP address? Go here:
|
19 |
-
(<a href="https://
|
20 |
</p>
|
21 |
<p>With this result, you should be able to select the correct item from the list. The higher up the
|
22 |
list the better, with <code>REMOTE_ADDR</code> being the #1 preferred, if possible.</p>
|
16 |
public IP address.
|
17 |
</p>
|
18 |
<p>Don't know your IP address? Go here:
|
19 |
+
(<a href="https://shsec.io/an" target="_blank">We've done it for you</a> ;)
|
20 |
</p>
|
21 |
<p>With this result, you should be able to select the correct item from the list. The higher up the
|
22 |
list the better, with <code>REMOTE_ADDR</code> being the #1 preferred, if possible.</p>
|
templates/php/snippets/pro.php
DELETED
@@ -1,310 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/** @var string[] $strings */
|
3 |
-
/** @var string[] $inputs */
|
4 |
-
/** @var string[] $flags */
|
5 |
-
/** @var string[] $vars */
|
6 |
-
/** @var string[] $aLicenseAjax */
|
7 |
-
/** @var array $aLicKeyInput */
|
8 |
-
$aLicKeyInput = $inputs[ 'license_key' ];
|
9 |
-
?>
|
10 |
-
<style>
|
11 |
-
#accordionTop .accordion-toggle h3 {
|
12 |
-
color: #333333;
|
13 |
-
}
|
14 |
-
#accordionTop .accordion-toggle {
|
15 |
-
background-color: rgba(255, 255, 255, 0.6);
|
16 |
-
}
|
17 |
-
#accordionTop .accordion-toggle:hover {
|
18 |
-
text-decoration: none;
|
19 |
-
background-color: rgba(255, 255, 255, 0.6);
|
20 |
-
}
|
21 |
-
#accordionTop .accordion-toggle:focus {
|
22 |
-
box-shadow: none;
|
23 |
-
}
|
24 |
-
#accordionTop .accordion-group {
|
25 |
-
margin-bottom: 15px;
|
26 |
-
}
|
27 |
-
#accordionTop .accordion-inner {
|
28 |
-
background-color: rgba(255, 255, 255, 0.6);
|
29 |
-
}
|
30 |
-
#ButtonBuyNow {
|
31 |
-
margin: 20px;
|
32 |
-
}
|
33 |
-
#ButtonActivate {
|
34 |
-
margin: 5px 2px 0;
|
35 |
-
}
|
36 |
-
.licenseForm button {
|
37 |
-
display: block;
|
38 |
-
}
|
39 |
-
|
40 |
-
</style>
|
41 |
-
|
42 |
-
<div class="container-fluid">
|
43 |
-
<div class="row content-help">
|
44 |
-
<div class="col-5">
|
45 |
-
<div class="module-headline">
|
46 |
-
<h4>License Summary</h4>
|
47 |
-
</div>
|
48 |
-
<table class="table table-hover table-sm table-responsive">
|
49 |
-
<?php foreach ( $vars[ 'license_table' ] as $varKey => $licenseValue ) : ?>
|
50 |
-
<?php $sClasses = ( $varKey == 'last_errors' && !empty( $licenseValue ) ) ? 'table-warning' : ''; ?>
|
51 |
-
<tr>
|
52 |
-
<th scope="row"><?php echo $strings[ $varKey ]; ?>:</th>
|
53 |
-
<td class="<?php echo $sClasses; ?>"><?php echo $licenseValue; ?></td>
|
54 |
-
</tr>
|
55 |
-
<?php endforeach; ?>
|
56 |
-
</table>
|
57 |
-
<hr />
|
58 |
-
|
59 |
-
<h4>License Actions</h4>
|
60 |
-
|
61 |
-
<div class="row">
|
62 |
-
<div class="col card">
|
63 |
-
<form method="post" class="licenseForm">
|
64 |
-
<?php foreach ( $ajax[ 'license_handling' ] as $sAjKey => $sAjVal ) : ?>
|
65 |
-
<input type="hidden" name="<?php echo $sAjKey; ?>" value="<?php echo $sAjVal; ?>" />
|
66 |
-
<?php endforeach; ?>
|
67 |
-
<input type="hidden" name="license-action" value="check" />
|
68 |
-
<div class="form-group">
|
69 |
-
<label>Check License Availability For This Site</label>
|
70 |
-
<button class="btn btn-info" type="submit"
|
71 |
-
<?php echo $flags[ 'button_enabled_check' ] ? '' : 'disabled="disabled"'; ?> >
|
72 |
-
Check License
|
73 |
-
</button>
|
74 |
-
|
75 |
-
|
76 |
-
<div class="form-text text-muted">
|
77 |
-
<p class="font-weight-bold"><br />Be sure to have first activated your URL in your
|
78 |
-
<a target="_blank" href="<?php echo $aHrefs[ 'keyless_cp' ]; ?>">Keyless Activation control panel</a>.</p>
|
79 |
-
<ul>
|
80 |
-
<li>URL To Activate: <?php echo $vars[ 'activation_url' ]; ?></li>
|
81 |
-
<li>Licenses may only be checked once in 20 seconds. Checks more frequent than this will
|
82 |
-
automatically be skipped</li>
|
83 |
-
</ul>
|
84 |
-
</div>
|
85 |
-
</div>
|
86 |
-
</form>
|
87 |
-
|
88 |
-
<form method="post" id="ConnectionDebug">
|
89 |
-
<?php foreach ( $ajax[ 'connection_debug' ] as $sAjKey => $sAjVal ) : ?>
|
90 |
-
<input type="hidden" name="<?php echo $sAjKey; ?>" value="<?php echo $sAjVal; ?>" />
|
91 |
-
<?php endforeach; ?>
|
92 |
-
<button class="btn btn-link btn-sm float-right p-0" type="submit">[Debug]</button>
|
93 |
-
</form>
|
94 |
-
</div>
|
95 |
-
</div>
|
96 |
-
|
97 |
-
<?php if ( false && $flags[ 'has_license_key' ] ) : ?>
|
98 |
-
<div class="row">
|
99 |
-
<div class="col card">
|
100 |
-
<form method="post" class="licenseForm">
|
101 |
-
|
102 |
-
<?php foreach ( $ajax[ 'license_handling' ] as $sAjKey => $sAjVal ) : ?>
|
103 |
-
<input type="hidden" name="<?php echo $sAjKey; ?>" value="<?php echo $sAjVal; ?>" />
|
104 |
-
<?php endforeach; ?>
|
105 |
-
|
106 |
-
<input type="hidden" name="license-action" value="remove" />
|
107 |
-
<div class="form-group">
|
108 |
-
<label>Remove Current License</label>
|
109 |
-
<button class="btn btn-warning" type="submit"
|
110 |
-
<?php echo $flags[ 'button_enabled_remove' ] ? '' : 'disabled="disabled"'; ?> >
|
111 |
-
Remove
|
112 |
-
</button>
|
113 |
-
<span class="form-text text-muted">Important: This will remove all Shield Security Pro features.</span>
|
114 |
-
</div>
|
115 |
-
</form>
|
116 |
-
</div>
|
117 |
-
</div>
|
118 |
-
<?php endif; ?>
|
119 |
-
</div>
|
120 |
-
|
121 |
-
<div class="col-7">
|
122 |
-
<div id="accordion">
|
123 |
-
|
124 |
-
<div class="card gopro-card">
|
125 |
-
<div class="card-header" id="headingOne">
|
126 |
-
<h5 class="mb-0">
|
127 |
-
<button class="btn btn-link" data-toggle="collapse" data-target="#collone"
|
128 |
-
aria-expanded="true" aria-controls="collone">
|
129 |
-
→ Shield Pro gives you ...
|
130 |
-
</button>
|
131 |
-
</h5>
|
132 |
-
</div>
|
133 |
-
|
134 |
-
<div id="collone" class="collapse show" aria-labelledby="headingOne"
|
135 |
-
data-parent="#accordion">
|
136 |
-
<div class="card-body">
|
137 |
-
<dl>
|
138 |
-
<dt>Plugin and Theme Vulnerability Scanner</dt>
|
139 |
-
<dd>Alerts to plugin/theme vulnerabilities.
|
140 |
-
Shield can then automatically upgrade as updates become available.
|
141 |
-
</dd>
|
142 |
-
|
143 |
-
<dt>Catch Hacks Immediately - Plugins and Themes Guard</dt>
|
144 |
-
<dd>Be alerted to ANY unauthorized changes to plugins/themes.</dd>
|
145 |
-
|
146 |
-
<dt>Powerful User Password Policies</dt>
|
147 |
-
<dd>Ensures that all users maintain strong passwords.</dd>
|
148 |
-
|
149 |
-
<dt>Support for WooCommerce & other 3rd party plugins</dt>
|
150 |
-
<dd>Provide tighter security for your WooCommerce customers.
|
151 |
-
</dd>
|
152 |
-
|
153 |
-
<dt>Exclusive Customer Support</dt>
|
154 |
-
<dd>Technical support for Shield is exclusive to Pro customers.</dd>
|
155 |
-
|
156 |
-
<dt>Import and Export of plugin options</dt>
|
157 |
-
<dd>Automatically import settings directly from 1 site to another.</dd>
|
158 |
-
|
159 |
-
<dt>Exclusive Early-Access </dt>
|
160 |
-
<dd>Be 1st to get new security features, as soon as they're available.</dd>
|
161 |
-
|
162 |
-
<dt>Unlimited Audit Trail</dt>
|
163 |
-
<dd>Retain logs for as long as you need - no limits.</dd>
|
164 |
-
|
165 |
-
<dt>Customize text shown to visitors</dt>
|
166 |
-
<dd>Edit customer-facing messages/text of the Shield plugin.</dd>
|
167 |
-
</dl>
|
168 |
-
</div>
|
169 |
-
</div>
|
170 |
-
</div>
|
171 |
-
|
172 |
-
<div class="card gopro-card">
|
173 |
-
<div class="card-header" id="headingTwo">
|
174 |
-
<h5 class="mb-0">
|
175 |
-
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#colltwo"
|
176 |
-
aria-expanded="false" aria-controls="colltwo">
|
177 |
-
→ Coming Soon...
|
178 |
-
</button>
|
179 |
-
</h5>
|
180 |
-
</div>
|
181 |
-
<div id="colltwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordion">
|
182 |
-
<div class="card-body">
|
183 |
-
<dl>
|
184 |
-
<dt>White Label</dt>
|
185 |
-
<dd>Re-Brand Shield Security as your own!</dd>
|
186 |
-
|
187 |
-
<dt>Select individual plugins for automatic updates</dt>
|
188 |
-
<dd>You'll soon be able to select individual plugins for automatic updates. Right now it's all or nothing.</dd>
|
189 |
-
|
190 |
-
<dt>Improved performance/optimizations for PHP 5.6+</dt>
|
191 |
-
<dd>We're rewriting your favourite security plugin to take full advantage of the latest PHP developments.</dd>
|
192 |
-
|
193 |
-
<dt>Statistic and Reporting</dt>
|
194 |
-
<dd>You'll be able to review and generate reports on keys security events on your sites.</dd>
|
195 |
-
|
196 |
-
<dt>And Much More...</dt>
|
197 |
-
<dd>With your continued support, we'll add more and more features...</dd>
|
198 |
-
</dl>
|
199 |
-
</div>
|
200 |
-
</div>
|
201 |
-
</div>
|
202 |
-
|
203 |
-
<div class="card gopro-card">
|
204 |
-
<div class="card-header" id="headingThree">
|
205 |
-
<h5 class="mb-0">
|
206 |
-
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collthree"
|
207 |
-
aria-expanded="false" aria-controls="collthree">
|
208 |
-
→ How To Get Shield Pro?
|
209 |
-
</button>
|
210 |
-
</h5>
|
211 |
-
</div>
|
212 |
-
<div id="collthree" class="collapse" aria-labelledby="headingThree" data-parent="#accordion">
|
213 |
-
<div class="card-body">
|
214 |
-
|
215 |
-
<p>One Dollar Plugin is our new Plugin Store. We're building a collection of high-quality,
|
216 |
-
highly reliable WordPress plugins for a fraction of the normal cost - making premium WordPress
|
217 |
-
plugins available to everyone.
|
218 |
-
</p>
|
219 |
-
<p>Shield Pro is our first One Dollar Plugin and is sold for the equivalent of
|
220 |
-
$1/month per site ($12/year)</p>
|
221 |
-
<ol>
|
222 |
-
<li>Just grab a new license from the
|
223 |
-
<a href="https://icwp.io/buyshieldpro" target="_blank">One Dollar Plugin here</a>.</li>
|
224 |
-
<li>Activate your license on your sites using the 'Activate Key' button.</li>
|
225 |
-
</ol>
|
226 |
-
|
227 |
-
<p class="text-center">
|
228 |
-
<a href="https://icwp.io/buyshieldpro" target="_blank" id="ButtonBuyNow"
|
229 |
-
class="btn btn-large btn-success">
|
230 |
-
Upgrade To Shield Pro Now →</a>
|
231 |
-
</p>
|
232 |
-
</div>
|
233 |
-
</div>
|
234 |
-
</div>
|
235 |
-
</div>
|
236 |
-
</div>
|
237 |
-
|
238 |
-
</div>
|
239 |
-
</div>
|
240 |
-
<hr />
|
241 |
-
|
242 |
-
<script type="text/javascript">
|
243 |
-
var iCWP_WPSF_LicenseHandler = new function () {
|
244 |
-
|
245 |
-
var bRequestCurrentlyRunning = false;
|
246 |
-
|
247 |
-
/**
|
248 |
-
*/
|
249 |
-
var submitLicenseForm = function ( event ) {
|
250 |
-
iCWP_WPSF_BodyOverlay.show();
|
251 |
-
|
252 |
-
if ( bRequestCurrentlyRunning ) {
|
253 |
-
return false;
|
254 |
-
}
|
255 |
-
bRequestCurrentlyRunning = true;
|
256 |
-
event.preventDefault();
|
257 |
-
|
258 |
-
var $oForm = jQuery( this );
|
259 |
-
jQuery.post( ajaxurl, $oForm.serialize(),
|
260 |
-
function ( oResponse ) {
|
261 |
-
if ( typeof oResponse !== 'undefined' && typeof oResponse.data !== 'undefined' ) {
|
262 |
-
iCWP_WPSF_Toaster.showMessage( oResponse.data.message, oResponse.data.success );
|
263 |
-
// iCWP_WPSF_Growl.showMessage( oResponse.data.message, oResponse.data.success );
|
264 |
-
}
|
265 |
-
}
|
266 |
-
).always( function () {
|
267 |
-
bRequestCurrentlyRunning = false;
|
268 |
-
// iCWP_WPSF_BodyOverlay.hide();
|
269 |
-
setTimeout( function () {
|
270 |
-
location.reload( true );
|
271 |
-
}, 2000 );
|
272 |
-
}
|
273 |
-
);
|
274 |
-
};
|
275 |
-
|
276 |
-
this.initialise = function () {
|
277 |
-
jQuery( document ).ready( function () {
|
278 |
-
jQuery( document ).on( "submit", "form.licenseForm", submitLicenseForm );
|
279 |
-
} );
|
280 |
-
};
|
281 |
-
}();
|
282 |
-
|
283 |
-
var iCWP_WPSF_ConnectionDebug = new function () {
|
284 |
-
/**
|
285 |
-
*/
|
286 |
-
var connectionDebug = function ( event ) {
|
287 |
-
iCWP_WPSF_BodyOverlay.show();
|
288 |
-
event.preventDefault();
|
289 |
-
|
290 |
-
var $oForm = jQuery( this );
|
291 |
-
jQuery.post( ajaxurl, $oForm.serialize(),
|
292 |
-
function ( oResponse ) {
|
293 |
-
alert( oResponse.data.message );
|
294 |
-
}
|
295 |
-
).always( function () {
|
296 |
-
iCWP_WPSF_BodyOverlay.hide();
|
297 |
-
}
|
298 |
-
);
|
299 |
-
};
|
300 |
-
|
301 |
-
this.initialise = function () {
|
302 |
-
jQuery( document ).ready( function () {
|
303 |
-
jQuery( document ).on( "submit", "form#ConnectionDebug", connectionDebug );
|
304 |
-
} );
|
305 |
-
};
|
306 |
-
}();
|
307 |
-
|
308 |
-
iCWP_WPSF_LicenseHandler.initialise();
|
309 |
-
iCWP_WPSF_ConnectionDebug.initialise();
|
310 |
-
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/features/feature-base.twig
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
</div>
|
11 |
<div class="page-header">
|
12 |
<h2>
|
13 |
-
<a id="pluginlogo_32" class="header-icon32" href="https://
|
14 |
{{ sPageTitle|raw }}
|
15 |
</h2>
|
16 |
</div>
|
10 |
</div>
|
11 |
<div class="page-header">
|
12 |
<h2>
|
13 |
+
<a id="pluginlogo_32" class="header-icon32" href="https://shsec.io/2k" target="_blank"></a>
|
14 |
{{ sPageTitle|raw }}
|
15 |
</h2>
|
16 |
</div>
|
templates/twig/notices/compat-sgoptimize.twig
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{% extends "/notices/base-error.twig" %}
|
2 |
+
|
3 |
+
{% block notice_body %}
|
4 |
+
<p>{{ strings.message }}
|
5 |
+
<a href="https://shsec.io/g7" target="_blank">{{ strings.learn_more }}</a>
|
6 |
+
<p><a href="#" id="SGOptimizerTurnOff">{{ strings.sgoptimizer_turnoff }}</a></p>
|
7 |
+
|
8 |
+
<script type="text/javascript">
|
9 |
+
jQuery( document ).on(
|
10 |
+
'click',
|
11 |
+
'a#SGOptimizerTurnOff',
|
12 |
+
function () {
|
13 |
+
iCWP_WPSF_BodyOverlay.show();
|
14 |
+
jQuery.get( ajaxurl, {{ ajax.sgoptimizer_turnoff|raw }} )
|
15 |
+
.always(
|
16 |
+
function () {
|
17 |
+
location.reload();
|
18 |
+
}
|
19 |
+
);
|
20 |
+
}
|
21 |
+
);
|
22 |
+
|
23 |
+
|
24 |
+
</script>
|
25 |
+
{% endblock %}
|
templates/twig/notices/rate-plugin.twig
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
<p>A lot of work goes into Shield Security, and we need your help to spread the word about it. :)
|
5 |
<p>Even just a 1-liner review that says you're happy with it, will help us immensely.</p>
|
6 |
<p>
|
7 |
-
<a href="https://
|
8 |
Click to leave a review on WordPress.org →</a>
|
9 |
</p>
|
10 |
{% endblock %}
|
4 |
<p>A lot of work goes into Shield Security, and we need your help to spread the word about it. :)
|
5 |
<p>Even just a 1-liner review that says you're happy with it, will help us immensely.</p>
|
6 |
<p>
|
7 |
+
<a href="https://shsec.io/wpsfreview" class="button button-primary" target="_blank">
|
8 |
Click to leave a review on WordPress.org →</a>
|
9 |
</p>
|
10 |
{% endblock %}
|
templates/twig/snippets/comment_form_botbox.twig
CHANGED
@@ -1,82 +1 @@
|
|
1 |
-
|
2 |
-
<p id="{{ form_id }}"></p>
|
3 |
-
<input type="hidden" id="_sugar_sweet_email" name="sugar_sweet_email" value="" />
|
4 |
-
<input type="hidden" id="_botts" name="botts" value="{{ ts }}" />
|
5 |
-
<input type="hidden" id="_comment_token" name="comment_token" value="{{ token }}" />
|
6 |
-
|
7 |
-
<script type="text/javascript">
|
8 |
-
|
9 |
-
function reenableButton{{ form_id }}() {
|
10 |
-
let nRemaining = {{ cooldown }} - nTimerCounter{{ form_id }};
|
11 |
-
subbutton{{ form_id }}.value = "{{ js_comment_wait|raw }}";
|
12 |
-
if ( nTimerCounter{{ form_id }} >= {{ cooldown }} ) {
|
13 |
-
subbutton{{ form_id }}.value = origButtonValue{{ form_id }};
|
14 |
-
subbutton{{ form_id }}.disabled = false;
|
15 |
-
clearInterval( sCountdownTimer{{ form_id }} );
|
16 |
-
}
|
17 |
-
nTimerCounter{{ form_id }}++;
|
18 |
-
}
|
19 |
-
|
20 |
-
function redisableButton{{ form_id }}() {
|
21 |
-
subbutton{{ form_id }}.value = "{{ comment_reload }}";
|
22 |
-
subbutton{{ form_id }}.disabled = true;
|
23 |
-
}
|
24 |
-
|
25 |
-
let oForm = document.getElementById( '{{ form_id }}' );
|
26 |
-
let cb{{ form_id }} = document.createElement( 'input' );
|
27 |
-
cb{{ form_id }}.type = 'checkbox';
|
28 |
-
cb{{ form_id }}.id = 'checkbox{{ form_id }}';
|
29 |
-
cb{{ form_id }}.name = 'checkbox{{ form_id }}';
|
30 |
-
cb{{ form_id }}.style.width = '25px';
|
31 |
-
cb{{ form_id }}.onclick = function () {
|
32 |
-
cb_name{{ form_id }}.value = cb{{ form_id }}.name;
|
33 |
-
};
|
34 |
-
|
35 |
-
let label{{ form_id }} = document.createElement( 'label' );
|
36 |
-
let labelspan{{ form_id }} = document.createElement( 'span' );
|
37 |
-
label{{ form_id }}.htmlFor = 'checkbox{{ form_id }}';
|
38 |
-
labelspan{{ form_id }}.innerHTML = "{{ confirm|raw }}";
|
39 |
-
|
40 |
-
let cb_name{{ form_id }} = document.createElement( 'input' );
|
41 |
-
cb_name{{ form_id }}.type = 'hidden';
|
42 |
-
cb_name{{ form_id }}.name = 'cb_nombre';
|
43 |
-
|
44 |
-
oForm.appendChild( label{{ form_id }} );
|
45 |
-
label{{ form_id }}.appendChild( cb{{ form_id }} );
|
46 |
-
label{{ form_id }}.appendChild( labelspan{{ form_id }} );
|
47 |
-
oForm.appendChild( cb_name{{ form_id }} );
|
48 |
-
|
49 |
-
let frm{{ form_id }} = cb{{ form_id }}.form;
|
50 |
-
frm{{ form_id }}.onsubmit = function() {
|
51 |
-
if ( cb{{ form_id }}.checked !== true ) {
|
52 |
-
alert( "{{ alert|raw }}" );
|
53 |
-
return false;
|
54 |
-
}
|
55 |
-
return true;
|
56 |
-
};
|
57 |
-
|
58 |
-
{% if cooldown > 0 or expire > 0 %}
|
59 |
-
|
60 |
-
let subbuttonList{{ form_id }} = frm{{ form_id }}.querySelectorAll( 'input[type="submit"]' );
|
61 |
-
|
62 |
-
if ( typeof (subbuttonList{{ form_id }} ) !== "undefined" ) {
|
63 |
-
|
64 |
-
subbutton{{ form_id }} = subbuttonList{{ form_id }}[ 0 ];
|
65 |
-
|
66 |
-
if ( typeof (subbutton{{ form_id }}) !== "undefined" ) {
|
67 |
-
|
68 |
-
{% if cooldown > 0 %}
|
69 |
-
subbutton{{ form_id }}.disabled = true;
|
70 |
-
origButtonValue{{ form_id }} = subbutton{{ form_id }}.value;
|
71 |
-
nTimerCounter{{ form_id }} = 0;
|
72 |
-
reenableButton{{ form_id }}();
|
73 |
-
sCountdownTimer{{ form_id }} = setInterval( reenableButton{{ form_id }}, 1000 );
|
74 |
-
{% endif %}
|
75 |
-
|
76 |
-
{% if expire > 0 %}
|
77 |
-
sTimeoutTimer{{ form_id }} = setTimeout( redisableButton{{ form_id }}, (1000 * {{ expire }} -1000) );
|
78 |
-
{% endif %}
|
79 |
-
}
|
80 |
-
}
|
81 |
-
{% endif %}
|
82 |
-
</script>
|
1 |
+
<p id="{{ uniq }}"></p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wizard/slides/welcome/optin.twig
CHANGED
@@ -18,7 +18,7 @@
|
|
18 |
<hr />
|
19 |
|
20 |
<h6>Bonus: Join our new Facebook group</h6>
|
21 |
-
<p><a href="https://
|
22 |
Click here to request access to our new Facebook group</a> where you can ask questions
|
23 |
and help others with WordPress security and in particular, the Shield Security plugin.</p>
|
24 |
|
18 |
<hr />
|
19 |
|
20 |
<h6>Bonus: Join our new Facebook group</h6>
|
21 |
+
<p><a href="https://shsec.io/cu" target="_blank">
|
22 |
Click here to request access to our new Facebook group</a> where you can ask questions
|
23 |
and help others with WordPress security and in particular, the Shield Security plugin.</p>
|
24 |
|
templates/twig/wpadmin_pages/base.twig
CHANGED
@@ -41,3 +41,6 @@
|
|
41 |
</div>
|
42 |
</div>
|
43 |
{% endif %}
|
|
|
|
|
|
41 |
</div>
|
42 |
</div>
|
43 |
{% endif %}
|
44 |
+
|
45 |
+
{% block inline_scripts %}
|
46 |
+
{% endblock %}
|
templates/twig/wpadmin_pages/insights/base.twig
CHANGED
@@ -95,4 +95,7 @@
|
|
95 |
{% endblock %}
|
96 |
|
97 |
{% block inline_styles %}
|
|
|
|
|
|
|
98 |
{% endblock %}
|
95 |
{% endblock %}
|
96 |
|
97 |
{% block inline_styles %}
|
98 |
+
{% endblock %}
|
99 |
+
|
100 |
+
{% block inline_scripts %}
|
101 |
{% endblock %}
|
templates/twig/wpadmin_pages/insights/insights/stats.twig
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
<div class="row" id="SectionStats">
|
2 |
-
{% for stat in vars.insight_stats %}
|
3 |
-
<div class="col-md-2">
|
4 |
-
<div class="stat card text-center"
|
5 |
-
{% if stat.tooltip is defined %}
|
6 |
-
title="{{ stat.tooltip }}"
|
7 |
-
{% endif %}
|
8 |
-
>
|
9 |
-
<div class="card-header">{{ stat.title }}</div>
|
10 |
-
<div class="card-body">{{ stat.val }}</div>
|
11 |
-
</div>
|
12 |
-
</div>
|
13 |
-
{% endfor %}
|
14 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wpadmin_pages/insights/license/license.twig
CHANGED
@@ -206,20 +206,17 @@
|
|
206 |
<div id="collthree" class="collapse" aria-labelledby="headingThree" data-parent="#accordion">
|
207 |
<div class="card-body">
|
208 |
|
209 |
-
<p>
|
210 |
-
|
211 |
-
plugins available to everyone.
|
212 |
-
</p>
|
213 |
-
<p>Shield Pro is our first One Dollar Plugin and is sold for the equivalent of
|
214 |
-
$1/month per site ($12/year)</p>
|
215 |
<ol>
|
216 |
<li>Just grab a new license from the
|
217 |
-
<a href="https://
|
218 |
-
<li>
|
|
|
219 |
</ol>
|
220 |
|
221 |
<p class="text-center">
|
222 |
-
<a href="https://
|
223 |
class="btn btn-large btn-success">
|
224 |
Upgrade To Shield Pro Now →</a>
|
225 |
</p>
|
206 |
<div id="collthree" class="collapse" aria-labelledby="headingThree" data-parent="#accordion">
|
207 |
<div class="card-body">
|
208 |
|
209 |
+
<p>Shield Security Pro is available from our online store and may be purchased
|
210 |
+
in US Dollar, €uros, or £GBPounds</p>
|
|
|
|
|
|
|
|
|
211 |
<ol>
|
212 |
<li>Just grab a new license from the
|
213 |
+
<a href="https://shsec.io/buyshieldpro" target="_blank">Shield Pro store</a>.</li>
|
214 |
+
<li>Register your site URL with our control panel.</li>
|
215 |
+
<li>Activate your license on your sites using the 'Check License' button.</li>
|
216 |
</ol>
|
217 |
|
218 |
<p class="text-center">
|
219 |
+
<a href="https://shsec.io/buyshieldpro" target="_blank" id="ButtonBuyNow"
|
220 |
class="btn btn-large btn-success">
|
221 |
Upgrade To Shield Pro Now →</a>
|
222 |
</p>
|
templates/twig/wpadmin_pages/insights/original/audit_trail.twig
DELETED
@@ -1,34 +0,0 @@
|
|
1 |
-
<div id="SectionAuditTrail" class="insights_widget card w-100">
|
2 |
-
<div class="card-header">
|
3 |
-
<h5 class="card-title">Audit Trail</h5>
|
4 |
-
<h6 class="card-subtitle mb-2 text-muted">20 most recent Audit Trail events</h6>
|
5 |
-
</div>
|
6 |
-
<div class="card-body overflow_container">
|
7 |
-
{% if flags.has_audit_trail_entries %}
|
8 |
-
<div class="overflow_inner">
|
9 |
-
<table class="table table-hover table-sm mb-0">
|
10 |
-
<thead><tr>
|
11 |
-
<th>Date</th>
|
12 |
-
<th>Message</th>
|
13 |
-
<th>User</th>
|
14 |
-
<th>IP</th>
|
15 |
-
</tr></thead>
|
16 |
-
<tbody>
|
17 |
-
{% for audit_entry in vars.audit_trail_recent %}
|
18 |
-
<tr>
|
19 |
-
<td>{{ audit_entry.created_at }}</td>
|
20 |
-
<td>{{ audit_entry.message }}</td>
|
21 |
-
<td>{{ audit_entry.wp_username }}</td>
|
22 |
-
<td>{{ audit_entry.ip }}</td>
|
23 |
-
</tr>
|
24 |
-
{% endfor %}
|
25 |
-
</tbody>
|
26 |
-
</table>
|
27 |
-
</div>
|
28 |
-
{#<a href="#" class="card-link">Card link</a>#}
|
29 |
-
{#<a href="#" class="card-link">Another link</a>#}
|
30 |
-
{% else %}
|
31 |
-
<h6 class="card-subtitle mb-2 text-muted">No Audit Trail entries (yet).</h6>
|
32 |
-
{% endif %}
|
33 |
-
</div>
|
34 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wpadmin_pages/insights/original/index.twig
DELETED
@@ -1,202 +0,0 @@
|
|
1 |
-
{% extends '/wpadmin_pages/base.twig' %}
|
2 |
-
|
3 |
-
{% block h1heading %}<h1>{{ strings.page_title }}</h1>{% endblock %}
|
4 |
-
|
5 |
-
{% block page_head %}
|
6 |
-
{% endblock %}
|
7 |
-
|
8 |
-
{% block page_main %}
|
9 |
-
<div class="row">
|
10 |
-
{#<div class="col-6">#}
|
11 |
-
{#{% include '/wpadmin_pages/insights/original/title.twig' %}#}
|
12 |
-
{#</div>#}
|
13 |
-
<div class="col-12">
|
14 |
-
{% include '/wpadmin_pages/insights/original/stats.twig' %}
|
15 |
-
</div>
|
16 |
-
</div>
|
17 |
-
<div class="row">
|
18 |
-
<div class="col-lg-7">
|
19 |
-
{% include '/wpadmin_pages/insights/original/notices.twig' %}
|
20 |
-
</div>
|
21 |
-
<div class="col-lg-5">
|
22 |
-
{% include '/wpadmin_pages/insights/notes/admin_notes.twig' %}
|
23 |
-
</div>
|
24 |
-
</div>
|
25 |
-
<div class="row">
|
26 |
-
<div class="col-lg-7">
|
27 |
-
{% include '/wpadmin_pages/insights/audit/audit_trail.twig' %}
|
28 |
-
</div>
|
29 |
-
<div class="col-lg-5">
|
30 |
-
{% include '/wpadmin_pages/insights/original/recent_events.twig' %}
|
31 |
-
</div>
|
32 |
-
</div>
|
33 |
-
<div class="row">
|
34 |
-
<div class="col">
|
35 |
-
</div>
|
36 |
-
</div>
|
37 |
-
{% endblock %}
|
38 |
-
|
39 |
-
{% block page_foot %}
|
40 |
-
{% include '/wpadmin_pages/insights/original/mod_summary.twig' %}
|
41 |
-
{% endblock %}
|
42 |
-
|
43 |
-
{% block inline_styles %}
|
44 |
-
<style>
|
45 |
-
#odp-body-container {
|
46 |
-
font-size: 13px;
|
47 |
-
}
|
48 |
-
.insights_widget.card {
|
49 |
-
border: 1px solid rgba(0, 0, 0, 0.1);
|
50 |
-
border-radius: 3px;
|
51 |
-
box-shadow: 2px 2px 1px rgba(0, 0, 0, 0.07);
|
52 |
-
padding: 0 0 3px 0;
|
53 |
-
max-width: 100%;
|
54 |
-
}
|
55 |
-
.insights_widget .card-body {
|
56 |
-
padding: 0 0 0 0;
|
57 |
-
}
|
58 |
-
.overflow_container {
|
59 |
-
max-height: 350px;
|
60 |
-
overflow-x: hidden;
|
61 |
-
overflow-y: auto;
|
62 |
-
padding-bottom: 1rem;
|
63 |
-
}
|
64 |
-
.overflow_inner {
|
65 |
-
padding: 1rem;
|
66 |
-
}
|
67 |
-
.overflow_inner dl {
|
68 |
-
margin-bottom: 1px;
|
69 |
-
}
|
70 |
-
.title_row th,
|
71 |
-
.title_row td {
|
72 |
-
background-color: #fbfbfb;
|
73 |
-
}
|
74 |
-
.message_row th,
|
75 |
-
.message_row td {
|
76 |
-
border-top: 1px solid #e9edf1; /** make bootstrap border lighter */
|
77 |
-
}
|
78 |
-
td.cell_delete_note {
|
79 |
-
max-width: 20px;
|
80 |
-
}
|
81 |
-
.icon-sign {
|
82 |
-
font-size: 14px;
|
83 |
-
}
|
84 |
-
#NewAdminNote textarea {
|
85 |
-
height: 64px;
|
86 |
-
}
|
87 |
-
.btn.note_delete {
|
88 |
-
padding: 0.1rem 0.3rem 0.3rem;
|
89 |
-
line-height: 9px;
|
90 |
-
}
|
91 |
-
#SectionAuditTrail table {
|
92 |
-
font-size: 12px;
|
93 |
-
}
|
94 |
-
#wpbody-content {
|
95 |
-
padding-bottom: 0;
|
96 |
-
}
|
97 |
-
#wpfooter {
|
98 |
-
display: none;
|
99 |
-
}
|
100 |
-
#odp-PageFoot {
|
101 |
-
position: sticky;
|
102 |
-
bottom: 0;
|
103 |
-
z-index: 2;
|
104 |
-
margin-top: 30px;
|
105 |
-
}
|
106 |
-
#SectionStats {
|
107 |
-
}
|
108 |
-
.stat.card {
|
109 |
-
text-align: center;
|
110 |
-
padding: 0;
|
111 |
-
}
|
112 |
-
.stat.card .card-body {
|
113 |
-
font-size: 18px;
|
114 |
-
}
|
115 |
-
#ModSummary {
|
116 |
-
border-bottom: 1px solid #aaaaaa;
|
117 |
-
border-top: 1px solid #aaaaaa;
|
118 |
-
background-color: #ffffff;
|
119 |
-
}
|
120 |
-
table td.mod-summary {
|
121 |
-
height: 52px;
|
122 |
-
text-align: center;
|
123 |
-
}
|
124 |
-
table td.mod-summary:hover {
|
125 |
-
background-color: #f0f0f0;
|
126 |
-
}
|
127 |
-
.mod-summary > a {
|
128 |
-
width: 32px;
|
129 |
-
height: 32px;
|
130 |
-
margin: auto;
|
131 |
-
display: inline-block;
|
132 |
-
}
|
133 |
-
.mod-summary > a:hover {
|
134 |
-
background-color: #f6f6f6;
|
135 |
-
}
|
136 |
-
.mod-summary.state-enabled > a {
|
137 |
-
color: rgba(69, 119, 0, 1);
|
138 |
-
}
|
139 |
-
.mod-summary.state-disabled > a {
|
140 |
-
color: rgba(173, 84, 0, 0.85);
|
141 |
-
}
|
142 |
-
.mod-icon {
|
143 |
-
font-size: 32px;
|
144 |
-
display: block;
|
145 |
-
}
|
146 |
-
.mod-icon:hover {
|
147 |
-
text-decoration: none;
|
148 |
-
}
|
149 |
-
.mod-plugin .mod-icon:before {
|
150 |
-
content: "\f111";
|
151 |
-
}
|
152 |
-
.mod-admin_access_restriction .mod-icon:before {
|
153 |
-
content: "\f332";
|
154 |
-
}
|
155 |
-
.mod-firewall .mod-icon:before {
|
156 |
-
content: "\f479";
|
157 |
-
}
|
158 |
-
.mod-user_management .mod-icon:before {
|
159 |
-
content: "\f307";
|
160 |
-
}
|
161 |
-
.mod-hack_protect .mod-icon:before {
|
162 |
-
content: "\f153";
|
163 |
-
}
|
164 |
-
.mod-headers .mod-icon:before {
|
165 |
-
content: "\f163";
|
166 |
-
}
|
167 |
-
.mod-login_protect .mod-icon:before {
|
168 |
-
content: "\f112";
|
169 |
-
}
|
170 |
-
.mod-comments_filter .mod-icon:before {
|
171 |
-
content: "\f125";
|
172 |
-
}
|
173 |
-
.mod-autoupdates .mod-icon:before {
|
174 |
-
content: "\f463";
|
175 |
-
}
|
176 |
-
.mod-lockdown .mod-icon:before {
|
177 |
-
content: "\f160";
|
178 |
-
}
|
179 |
-
.mod-audit_trail .mod-icon:before {
|
180 |
-
content: "\f115";
|
181 |
-
}
|
182 |
-
.mod-traffic .mod-icon:before {
|
183 |
-
content: "\f177";
|
184 |
-
}
|
185 |
-
.mod-ips .mod-icon:before {
|
186 |
-
content: "\f230";
|
187 |
-
}
|
188 |
-
.mod-license .mod-icon:before {
|
189 |
-
content: "\f525";
|
190 |
-
}
|
191 |
-
</style>
|
192 |
-
|
193 |
-
|
194 |
-
<script type="text/javascript">
|
195 |
-
jQuery( document ).ready( function () {
|
196 |
-
jQuery( '.stat.card' ).tooltip( {
|
197 |
-
placement: 'bottom',
|
198 |
-
trigger: 'hover'
|
199 |
-
} );
|
200 |
-
} );
|
201 |
-
</script>
|
202 |
-
{% endblock %}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wpadmin_pages/insights/original/mod_summary.twig
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
<div class="row" style="height: 15px;background-color: #e4e4e4;">
|
2 |
-
<div class="col"></div>
|
3 |
-
</div>
|
4 |
-
<div class="row" id="ModSummary">
|
5 |
-
<div class="col">
|
6 |
-
<table class="table table-borderless mb-0 w-100">
|
7 |
-
<tr>
|
8 |
-
{% for mod in vars.summary %}
|
9 |
-
<td class="mod-summary mod-{{ mod.slug }}
|
10 |
-
state-{% if mod.enabled %}enabled{% else %}disabled{% endif %}"
|
11 |
-
>
|
12 |
-
<a class="mod-icon dashicons"
|
13 |
-
href="{{ mod.href }}"
|
14 |
-
title="{{ mod.name }}">
|
15 |
-
</a>
|
16 |
-
</td>
|
17 |
-
{% endfor %}
|
18 |
-
</tr>
|
19 |
-
</table>
|
20 |
-
</div>
|
21 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wpadmin_pages/insights/original/notices.twig
DELETED
@@ -1,58 +0,0 @@
|
|
1 |
-
<div id="SectionNotices" class="insights_widget card w-100">
|
2 |
-
<div class="card-header">
|
3 |
-
<h5 class="card-title">Security Notices
|
4 |
-
<span class="badge {% if flags.has_notices %}badge-warning{% else %}badge-success{% endif %}">
|
5 |
-
{{ vars.insight_notices_count }}
|
6 |
-
</span>
|
7 |
-
</h5>
|
8 |
-
<h6 class="card-subtitle text-muted">Potential security issues on your site <em>right now</em></h6>
|
9 |
-
</div>
|
10 |
-
<div class="card-body overflow_container">
|
11 |
-
|
12 |
-
{% if flags.has_notices %}
|
13 |
-
<div class="overflow_inner p-0">
|
14 |
-
<table class="table mb-0">
|
15 |
-
{% for notice_section in vars.insight_notices %}
|
16 |
-
{% if notice_section.count > 0 %}
|
17 |
-
<tr class="title_row">
|
18 |
-
<th colspan="4">
|
19 |
-
<h6 class="m-0">
|
20 |
-
{{ notice_section.title }}
|
21 |
-
<span class="text-muted" style="font-size: smaller;">({{ notice_section.count }})</span>
|
22 |
-
</h6>
|
23 |
-
</th>
|
24 |
-
</tr>
|
25 |
-
|
26 |
-
{% for notice in notice_section.messages %}
|
27 |
-
<tr class="message_row">
|
28 |
-
<td class="empty_cell"> </td>
|
29 |
-
<th>{{ notice.title }}:</th>
|
30 |
-
<td>
|
31 |
-
<span class="icon-exclamation-sign icon-sign">⚠</span> {{ notice.message }}
|
32 |
-
{% if notice.rec is defined %}
|
33 |
-
<br /><span class="text-muted">
|
34 |
-
<span class="icon-exclamation-sign icon-sign">☛</span>
|
35 |
-
{{ notice.rec|default('') }}</span>
|
36 |
-
{% endif %}
|
37 |
-
</td>
|
38 |
-
<td class="text-right text-nowrap">
|
39 |
-
{% if notice.href is not empty %}
|
40 |
-
<a href="{{ notice.href }}" target="_blank">
|
41 |
-
{{ notice.action|default( strings.more_info ) }} ↗
|
42 |
-
</a>
|
43 |
-
{% endif %}
|
44 |
-
</td>
|
45 |
-
</tr>
|
46 |
-
{% endfor %}
|
47 |
-
{% endif %}
|
48 |
-
{% endfor %}
|
49 |
-
</table>
|
50 |
-
</div>
|
51 |
-
{% else %}
|
52 |
-
<div class="alert alert-success">
|
53 |
-
There are no important security notices at this time. This is a wonderful thing! :)
|
54 |
-
</div>
|
55 |
-
{% endif %}
|
56 |
-
|
57 |
-
</div>
|
58 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wpadmin_pages/insights/original/recent_events.twig
DELETED
@@ -1,18 +0,0 @@
|
|
1 |
-
<div id="SectionRecentEvents" class="insights_widget card w-100">
|
2 |
-
<div class="card-header">
|
3 |
-
<h5 class="card-title">Recent Events</h5>
|
4 |
-
<h6 class="card-subtitle text-muted">{{ strings.box_receve_subtitle }}</h6>
|
5 |
-
</div>
|
6 |
-
<div class="card-body overflow_container">
|
7 |
-
<div class="overflow_inner">
|
8 |
-
{% for insight_event in vars.insight_events %}
|
9 |
-
<dl class="row">
|
10 |
-
<dt class="col-6">{{ insight_event.name }}:</dt>
|
11 |
-
<dd class="col-6">{{ insight_event.val }}</dd>
|
12 |
-
</dl>
|
13 |
-
{% endfor %}
|
14 |
-
</div>
|
15 |
-
{#<a href="#" class="card-link">Card link</a>#}
|
16 |
-
{#<a href="#" class="card-link">Another link</a>#}
|
17 |
-
</div>
|
18 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wpadmin_pages/insights/original/stats.twig
DELETED
@@ -1,20 +0,0 @@
|
|
1 |
-
<div class="row" id="SectionStats">
|
2 |
-
{% for stat in vars.insight_stats %}
|
3 |
-
<div class="col-md-1">
|
4 |
-
<div class="stat card"
|
5 |
-
{% if stat.tooltip is defined %}
|
6 |
-
title="{{ stat.tooltip }}"
|
7 |
-
{% endif %}
|
8 |
-
>
|
9 |
-
<div class="card-header">
|
10 |
-
{{ stat.title }}
|
11 |
-
</div>
|
12 |
-
<div class="card-body">
|
13 |
-
{{ stat.val }}
|
14 |
-
</div>
|
15 |
-
</div>
|
16 |
-
</div>
|
17 |
-
{% endfor %}
|
18 |
-
</div>
|
19 |
-
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wpadmin_pages/insights/original/title.twig
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
<div id="SectionTitle" class="insights_widget card w-100">
|
2 |
-
<div class="card-header">
|
3 |
-
<h5 class="card-title mb-0">{{ strings.box_welcome_title }}</h5>
|
4 |
-
</div>
|
5 |
-
<div class="card-body overflow_container">
|
6 |
-
<div class="overflow_inner">
|
7 |
-
<p>This <span class="font-weight-bold">Insights Dashboard</span> is new with v6.7.0
|
8 |
-
<br />It's a 1st version, designed
|
9 |
-
to provide a high-level summary of your WordPress site security, and Shield activity.</p>
|
10 |
-
<p>If you have suggestions or feedback, please let us know
|
11 |
-
<a href="https://icwp.io/shieldsecuritygroupfb" target="_blank">
|
12 |
-
in our <span class="badge badge-info">new</span> Facebook group</a>.</p>
|
13 |
-
{% if flags.is_pro %}
|
14 |
-
<p>Thank you for your support with your Shield Pro purchase. :)</p>
|
15 |
-
{% else %}
|
16 |
-
<p>For just $1/month, get all the extra features and 1-on-1 technical support -
|
17 |
-
<a href="https://icwp.io/cw" class="btn btn-outline-success">Go Pro Today!</a></p>
|
18 |
-
{% endif %}
|
19 |
-
</div>
|
20 |
-
{#<a href="#" class="card-link">Card link</a>#}
|
21 |
-
{#<a href="#" class="card-link">Another link</a>#}
|
22 |
-
</div>
|
23 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
templates/twig/wpadmin_pages/insights/{insights → overview}/index.twig
RENAMED
@@ -3,15 +3,15 @@
|
|
3 |
{% block page_main %}
|
4 |
<div class="row">
|
5 |
<div class="col-12 insights_section">
|
6 |
-
{% include '/wpadmin_pages/insights/
|
7 |
</div>
|
8 |
</div>
|
9 |
<div class="row">
|
10 |
<div class="col-xl-6 col-lg-12 insights_section">
|
11 |
-
{% include '/wpadmin_pages/insights/
|
12 |
</div>
|
13 |
<div class="col-xl-6 col-lg-12 insights_section">
|
14 |
-
{% include '/wpadmin_pages/insights/
|
15 |
</div>
|
16 |
</div>
|
17 |
|
@@ -58,16 +58,61 @@
|
|
58 |
data-featherlight-iframe-height="675"> </a>
|
59 |
{% endif %}
|
60 |
</div>
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
jQuery( '#collapseConfigSummary' ).on( 'shown.bs.collapse', function () {
|
63 |
jQuery( 'html, body' ).animate( {
|
64 |
scrollTop: jQuery( "#collapseConfigSummaryTitle" ).offset().top - 115
|
65 |
}, 750 );
|
66 |
} );
|
67 |
{% if flags.show_guided_tour %}
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
{% endif %}
|
72 |
</script>
|
73 |
{% endblock %}
|
3 |
{% block page_main %}
|
4 |
<div class="row">
|
5 |
<div class="col-12 insights_section">
|
6 |
+
{% include '/wpadmin_pages/insights/overview/stats.twig' %}
|
7 |
</div>
|
8 |
</div>
|
9 |
<div class="row">
|
10 |
<div class="col-xl-6 col-lg-12 insights_section">
|
11 |
+
{% include '/wpadmin_pages/insights/overview/notices.twig' %}
|
12 |
</div>
|
13 |
<div class="col-xl-6 col-lg-12 insights_section">
|
14 |
+
{% include '/wpadmin_pages/insights/overview/recent_events.twig' %}
|
15 |
</div>
|
16 |
</div>
|
17 |
|
58 |
data-featherlight-iframe-height="675"> </a>
|
59 |
{% endif %}
|
60 |
</div>
|
61 |
+
{% endblock %}
|
62 |
+
|
63 |
+
{% block inline_styles %}
|
64 |
+
<style>
|
65 |
+
.ct-series-a .ct-line {
|
66 |
+
/* Set the colour of this series line */
|
67 |
+
stroke: green;
|
68 |
+
/* Control the thikness of your lines */
|
69 |
+
stroke-width: 2px;
|
70 |
+
/* Create a dashed line with a pattern */
|
71 |
+
stroke-dasharray: 3px 1px;
|
72 |
+
}
|
73 |
+
|
74 |
+
/* This selector overrides the points style on line charts. Points on line charts are actually just very short strokes. This allows you to customize even the point size in CSS */
|
75 |
+
.ct-series-a .ct-point {
|
76 |
+
/* Colour of your points */
|
77 |
+
stroke: green;
|
78 |
+
/* Size of your points */
|
79 |
+
stroke-width: 4px;
|
80 |
+
/* Make your points appear as squares */
|
81 |
+
stroke-linecap: square;
|
82 |
+
}
|
83 |
+
</style>
|
84 |
+
{% endblock %}
|
85 |
+
|
86 |
+
{% block inline_scripts %}
|
87 |
+
<script type="text/javascript">
|
88 |
+
jQuery( document ).ready( function () {
|
89 |
+
|
90 |
+
{% for stat in vars.insight_stats %}
|
91 |
+
jQuery( '#statcard-{{ stat.id }} .card-body .stat-chart' ).icwpWpsfAjaxChart(
|
92 |
+
{
|
93 |
+
'ajax_render':{{ ajax.render_chart_post|raw }},
|
94 |
+
'req_params': {
|
95 |
+
'render_location': "insights-overview-statcard",
|
96 |
+
'chart_params': {
|
97 |
+
'stat_id': "{{ stat.id }}",
|
98 |
+
}
|
99 |
+
}
|
100 |
+
}
|
101 |
+
);
|
102 |
+
{% endfor %}
|
103 |
+
|
104 |
+
} );
|
105 |
+
</script>
|
106 |
+
<script type="text/javascript">
|
107 |
jQuery( '#collapseConfigSummary' ).on( 'shown.bs.collapse', function () {
|
108 |
jQuery( 'html, body' ).animate( {
|
109 |
scrollTop: jQuery( "#collapseConfigSummaryTitle" ).offset().top - 115
|
110 |
}, 750 );
|
111 |
} );
|
112 |
{% if flags.show_guided_tour %}
|
113 |
+
window.onload = function () {
|
114 |
+
jQuery( '#IntroVideo' ).click();
|
115 |
+
};
|
116 |
{% endif %}
|
117 |
</script>
|
118 |
{% endblock %}
|
templates/twig/wpadmin_pages/insights/{insights → overview}/notices.twig
RENAMED
File without changes
|
templates/twig/wpadmin_pages/insights/{insights → overview}/recent_events.twig
RENAMED
File without changes
|
templates/twig/wpadmin_pages/insights/overview/stats.twig
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="row" id="SectionStats">
|
2 |
+
{% for stat in vars.insight_stats %}
|
3 |
+
<div class="col-lg-2 col-md-4">
|
4 |
+
<div class="stat card text-center" id="statcard-{{ stat.id }}"
|
5 |
+
{% if stat.tooltip is defined %}title="{{ stat.tooltip }}"{% endif %}
|
6 |
+
>
|
7 |
+
<div class="card-header">
|
8 |
+
<p class="mb-0">{{ stat.title }}</p>
|
9 |
+
<span>({{ stat.title_sub }})</span>
|
10 |
+
</div>
|
11 |
+
<div class="card-body">
|
12 |
+
<div class="stat-chart"
|
13 |
+
{% if stat.tooltip_chart is defined %}title="{{ stat.tooltip_chart }}"{% endif %}></div>
|
14 |
+
<h6 style="font-size: small" {% if stat.tooltip_p is defined %}title="{{ stat.tooltip_p }}"{% endif %}>{{ stat.val }}</h6>
|
15 |
+
</div>
|
16 |
+
</div>
|
17 |
+
</div>
|
18 |
+
{% endfor %}
|
19 |
+
</div>
|
templates/twig/wpadmin_pages/insights/reports/index.twig
CHANGED
@@ -19,11 +19,9 @@
|
|
19 |
</div>
|
20 |
{% endblock %}
|
21 |
|
22 |
-
{% block
|
23 |
-
|
24 |
-
<script>
|
25 |
-
let $oChartOffense;
|
26 |
|
|
|
27 |
jQuery( document ).ready( function () {
|
28 |
|
29 |
let $oChartOffense = jQuery( '#ChartDaily' ).icwpWpsfAjaxChart(
|
19 |
</div>
|
20 |
{% endblock %}
|
21 |
|
22 |
+
{% block inline_scripts %}
|
|
|
|
|
|
|
23 |
|
24 |
+
<script type="text/javascript">
|
25 |
jQuery( document ).ready( function () {
|
26 |
|
27 |
let $oChartOffense = jQuery( '#ChartDaily' ).icwpWpsfAjaxChart(
|
unsupported.php
CHANGED
@@ -17,7 +17,7 @@ function icwp_wpsf_unsupported_php() {
|
|
17 |
|
18 |
sprintf( 'Shield Security Plugin - Unsupported PHP Version: %s', PHP_VERSION ),
|
19 |
implode( '<br/>', $aText ),
|
20 |
-
'https://
|
21 |
sprintf( 'Click here for more info' ),
|
22 |
add_query_arg(
|
23 |
array(
|
17 |
|
18 |
sprintf( 'Shield Security Plugin - Unsupported PHP Version: %s', PHP_VERSION ),
|
19 |
implode( '<br/>', $aText ),
|
20 |
+
'https://shsec.io/dl',
|
21 |
sprintf( 'Click here for more info' ),
|
22 |
add_query_arg(
|
23 |
array(
|