Version Description
(2022-02-08) =
Release notes: New Reports engine with more criteria, reports management & more
-
New activity log event IDs
- ID 6059: Changed the site's title.
- ID 4021: Changed the website URL in the user profile.
- ID 4013: User has been activated on a multisite network.
-
New features & functionality
- Hooks to allow users to change the columns in reports or ad value from non-default columns. Refer to the list of hooks in WP Activity Log for more information.
- New UI for "Enable/Disable event IDs" with search and filtering functionality.
- New filter that allows user to add metadata to user information popup. Refer to the List of hooks in WP Activity Log for more information.
- The new Activity Log for TablePress extension.
-
Improvements
- Changed the database schema for improved storing of data, and faster writing and reading. After the upgrade the plugin will launch the upgrade process which might take some time to complete, depending on the amount of data in the activity log.
- Improved the coverage of changes done to a website via REST API.
- Removed obsolete code used for advertorial events in the activity log viewer.
- All plugin settings now have the wsal_ prefix automatically added to them.
- Rewritten some of the settings help text in the plugin to better explain the settings.
- Removed obsolete settings & code of the old file integrity scanner (now part of Website File Changes Monitor plugin).
- Removed obsolete reference to the old file changes scanner in the daily summary email.
- Made a number of JS strings available for translation.
- Removed a number of plugin settings from autoload for improved performance.
- Improved the plugin's metadata and added the licensing information.
- Long URL strings in activity log events are now automatically truncated. Full URL can be seen with just a click.
- Removed forced database table collation: plugin now uses the default WordPress table collation.
- Updated the "Help & Contact Us" page; improved text and added more relevant information.
- Improved several UI sections in the Third Party Connections module.
- Improved the check for writing activity log to external database; now it is less restrictive and faster.
-
Security fix
- Upgraded the Freemius SDK to version 2.4.3.
-
Bug fixes
- Fixed: Database error when trying to log in with a non-existing user and a login notification is enabled.
- Fixed: In some edge cases the plugin was creating an empty "external database" connection string.
- Fixed a number of typos in the text of activity log events.
- Fixed: Auto complete in the Delete activity log data section was not returning the correct list of objects.
- Fixed: Wrong object reported for event ID 5029.
- Fixed: Event ID 4000 not reported when front-end sensor is disabled.
- Fixed: "Unknown connection type" reported back setting up a third party connection on specific versions of WordPress.
- Fixed: Event ID 6320 (added / removed connection) reported instead of event ID 6321 (modified connection).
- Fixed: Function that was running on "add_filter" instead of "add_action" - Support ticket.
- Fixed: PHP warning about OPCacheUtils.php in specific setups.
- Fixed: Edge case in which other plugins couldn't be installed or updated when WP Activity Log was activated.
Refer to the complete plugin changelog for more detailed information about what was new, improved and fixed in previous versions of the WP Activity Log plugin.
Download this release
Release Info
Developer | WPWhiteSecurity |
Plugin | WP Security Audit Log |
Version | 4.4.0 |
Comparing to | |
See all releases |
Code changes from version 4.3.6 to 4.4.0
- classes/AbstractSensor.php +3 -2
- classes/Adapters/ActiveRecordInterface.php +33 -20
- classes/Adapters/MetaInterface.php +3 -5
- classes/Adapters/MySQL/ActiveRecordAdapter.php +551 -602
- classes/Adapters/MySQL/MetaAdapter.php +18 -20
- classes/Adapters/MySQL/OccurrenceAdapter.php +225 -152
- classes/Adapters/MySQL/QueryAdapter.php +15 -16
- classes/Adapters/MySQL/TmpUserAdapter.php +7 -12
- classes/Adapters/OccurrenceInterface.php +51 -10
- classes/Adapters/QueryInterface.php +1 -0
- classes/Alert.php +19 -14
- classes/AlertFormatter.php +12 -0
- classes/AlertManager.php +127 -458
- classes/AuditLogGridView.php +2 -3
- classes/AuditLogListView.php +6 -16
- classes/Connector/ConnectorFactory.php +66 -17
- classes/Connector/ConnectorInterface.php +13 -1
- classes/Connector/MySQLDB.php +44 -19
- classes/Helpers/Options.php +16 -29
- classes/Loggers/Database.php +2 -61
- classes/MainWpApi.php +483 -0
- classes/Models/ActiveRecord.php +61 -51
- classes/Models/Meta.php +2 -2
- classes/Models/Occurrence.php +206 -59
- classes/Models/Query.php +4 -3
- classes/Multisite/NetworkWide/AbstractTracker.php +1 -1
- classes/Multisite/NetworkWide/TrackerInterface.php +2 -2
- classes/ReportArgs.php +184 -76
- classes/SensorManager.php +15 -12
- classes/Sensors/Content.php +108 -89
- classes/Sensors/FrontendRegister.php +0 -62
- classes/Sensors/LogInOut.php +10 -13
- classes/Sensors/Multisite.php +13 -9
- classes/Sensors/MultisiteSignUp.php +95 -0
- classes/Sensors/Public.php +0 -64
- classes/Sensors/Register.php +82 -0
- classes/Sensors/System.php +18 -0
- classes/Sensors/UserProfile.php +107 -35
- classes/Settings.php +31 -27
- classes/ThirdPartyExtensions/AbstractExtension.php +8 -0
- classes/ThirdPartyExtensions/BBPressExtension.php +8 -4
- classes/ThirdPartyExtensions/GravityFormsExtension.php +6 -2
- classes/ThirdPartyExtensions/TablePressExtension.php +9 -5
- classes/ThirdPartyExtensions/WFCMExtension.php +117 -0
- classes/ThirdPartyExtensions/WPFormsExtension.php +6 -2
- classes/ThirdPartyExtensions/WooCommerceExtension.php +6 -2
- classes/ThirdPartyExtensions/YoastSeoExtension.php +6 -2
- classes/Upgrade/MetadataMigration.php +195 -0
- classes/Upgrade/Upgrade_43000_to_44400.php +174 -0
- classes/Utilities/FileSystemUtils.php +47 -0
- classes/Utilities/PluginInstallAndActivate.php +7 -6
- classes/Utilities/PluginInstallerAction.php +18 -7
- classes/Utilities/RequestUtils.php +11 -0
- classes/Utilities/UserUtils.php +28 -7
- classes/ViewManager.php +1 -49
- classes/Views/AuditLog.php +32 -19
- classes/Views/EmailNotifications.php +2 -2
- classes/Views/Help.php +14 -8
- classes/Views/Reports.php +2 -2
- classes/Views/Search.php +2 -2
- classes/Views/Settings.php +44 -25
- classes/Views/SetupWizard.php +7 -6
- classes/Views/ToggleAlerts.php +460 -370
- classes/Views/addons/html-view.php +2 -0
- css/admin-notices.css +12 -1
- defaults.php +58 -3
- img/addons/wfcm.png +0 -0
- img/help/c4wp.jpg +0 -0
- img/help/password-policy-manager.jpg +0 -0
- img/help/wp-2fa-img.jpg +0 -0
- js/auditlog.js +7 -0
- js/common.js +51 -35
- languages/index.php +4 -0
- languages/wp-security-audit-log.pot +725 -689
- license.txt +674 -0
- readme.txt +48 -7
- third-party/freemius/wordpress-sdk/includes/class-freemius.php +25 -2
- third-party/freemius/wordpress-sdk/includes/managers/class-fs-admin-notice-manager.php +7 -2
- third-party/freemius/wordpress-sdk/includes/sdk/Exceptions/ArgumentNotExistException.php +5 -1
- third-party/freemius/wordpress-sdk/includes/sdk/Exceptions/EmptyArgumentException.php +5 -1
- third-party/freemius/wordpress-sdk/includes/sdk/Exceptions/Exception.php +5 -1
- third-party/freemius/wordpress-sdk/includes/sdk/Exceptions/InvalidArgumentException.php +5 -1
- third-party/freemius/wordpress-sdk/includes/sdk/Exceptions/OAuthException.php +5 -1
- third-party/freemius/wordpress-sdk/includes/sdk/FreemiusBase.php +4 -0
- third-party/freemius/wordpress-sdk/includes/sdk/FreemiusWordPress.php +4 -1
- third-party/freemius/wordpress-sdk/require.php +5 -1
- third-party/freemius/wordpress-sdk/start.php +1 -1
- third-party/freemius/wordpress-sdk/templates/account/partials/addon.php +6 -1
- third-party/freemius/wordpress-sdk/templates/ajax-loader.php +6 -1
- third-party/freemius/wordpress-sdk/templates/debug.php +8 -2
- third-party/freemius/wordpress-sdk/templates/firewall-issues-js.php +10 -6
- third-party/freemius/wordpress-sdk/templates/partials/network-activation.php +6 -1
- third-party/freemius/wordpress-sdk/templates/sticky-admin-notice-js.php +4 -2
- third-party/vendor/autoload.php +7 -0
- third-party/vendor/composer/ClassLoader.php +445 -0
- third-party/vendor/composer/LICENSE +21 -0
- third-party/vendor/composer/autoload_classmap.php +12 -0
- third-party/vendor/composer/autoload_namespaces.php +9 -0
- third-party/vendor/composer/autoload_psr4.php +9 -0
- third-party/vendor/composer/autoload_real.php +46 -0
- third-party/vendor/composer/autoload_static.php +21 -0
- third-party/vendor/deliciousbrains/wp-background-processing/classes/wp-async-request.php +157 -0
- third-party/vendor/deliciousbrains/wp-background-processing/classes/wp-background-process.php +440 -0
- third-party/vendor/deliciousbrains/wp-background-processing/wp-background-processing.php +25 -0
- third-party/vendor/mirazmac/php-requirements-checker/src/Checker.php +780 -0
- third-party/vendor/mirazmac/php-requirements-checker/usage/usage.php +23 -0
- third-party/vendor/scoper-autoload.php +7 -0
- wp-security-audit-log.php +141 -213
classes/AbstractSensor.php
CHANGED
@@ -43,7 +43,7 @@ abstract class WSAL_AbstractSensor {
|
|
43 |
* @return boolean
|
44 |
*/
|
45 |
protected function IsMultisite() {
|
46 |
-
return
|
47 |
}
|
48 |
|
49 |
/**
|
@@ -60,7 +60,8 @@ abstract class WSAL_AbstractSensor {
|
|
60 |
*/
|
61 |
protected function Log( $type, $message, $args ) {
|
62 |
$this->plugin->alerts->Trigger(
|
63 |
-
$type,
|
|
|
64 |
'Message' => $message,
|
65 |
'Context' => $args,
|
66 |
'Trace' => debug_backtrace(),
|
43 |
* @return boolean
|
44 |
*/
|
45 |
protected function IsMultisite() {
|
46 |
+
return $this->plugin->IsMultisite();
|
47 |
}
|
48 |
|
49 |
/**
|
60 |
*/
|
61 |
protected function Log( $type, $message, $args ) {
|
62 |
$this->plugin->alerts->Trigger(
|
63 |
+
$type,
|
64 |
+
array(
|
65 |
'Message' => $message,
|
66 |
'Context' => $args,
|
67 |
'Trace' => debug_backtrace(),
|
classes/Adapters/ActiveRecordInterface.php
CHANGED
@@ -20,17 +20,20 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
20 |
interface WSAL_Adapters_ActiveRecordInterface {
|
21 |
|
22 |
/**
|
23 |
-
*
|
|
|
|
|
|
|
24 |
*/
|
25 |
public function IsInstalled();
|
26 |
|
27 |
/**
|
28 |
-
* Install.
|
29 |
*/
|
30 |
public function Install();
|
31 |
|
32 |
/**
|
33 |
-
*
|
34 |
*/
|
35 |
public function Uninstall();
|
36 |
|
@@ -43,49 +46,59 @@ interface WSAL_Adapters_ActiveRecordInterface {
|
|
43 |
public function Load( $cond = '%d', $args = array( 1 ) );
|
44 |
|
45 |
/**
|
46 |
-
* Save.
|
47 |
*
|
48 |
-
* @param object $
|
|
|
49 |
*/
|
50 |
public function Save( $activeRecord );
|
51 |
|
52 |
/**
|
53 |
-
* Delete.
|
54 |
*
|
55 |
-
* @param object $
|
|
|
56 |
*/
|
57 |
public function Delete( $activeRecord );
|
58 |
|
59 |
/**
|
60 |
-
* Load
|
61 |
*
|
62 |
-
* @param string $cond
|
63 |
-
* @param array
|
|
|
|
|
64 |
*/
|
65 |
public function LoadMulti( $cond, $args = array() );
|
66 |
|
67 |
/**
|
68 |
-
* Load and call
|
|
|
69 |
*
|
70 |
-
* @param
|
71 |
-
* @param string
|
72 |
-
* @param array
|
73 |
*/
|
74 |
public function LoadAndCallForEach( $callback, $cond = '%d', $args = array( 1 ) );
|
75 |
|
76 |
/**
|
77 |
-
* Count.
|
|
|
78 |
*
|
79 |
-
* @param string $cond
|
80 |
-
* @param array $args
|
|
|
81 |
*/
|
82 |
public function Count( $cond = '%d', $args = array( 1 ) );
|
83 |
|
84 |
/**
|
85 |
-
*
|
|
|
|
|
|
|
86 |
*
|
87 |
-
* @
|
88 |
-
* @
|
89 |
*/
|
90 |
public function LoadMultiQuery( $query, $args = array() );
|
91 |
|
20 |
interface WSAL_Adapters_ActiveRecordInterface {
|
21 |
|
22 |
/**
|
23 |
+
* Returns whether table structure is installed or not.
|
24 |
+
*
|
25 |
+
* @deprecated
|
26 |
+
* @return boolean
|
27 |
*/
|
28 |
public function IsInstalled();
|
29 |
|
30 |
/**
|
31 |
+
* Install this ActiveRecord structure into DB.
|
32 |
*/
|
33 |
public function Install();
|
34 |
|
35 |
/**
|
36 |
+
* Remove this ActiveRecord structure from DB.
|
37 |
*/
|
38 |
public function Uninstall();
|
39 |
|
46 |
public function Load( $cond = '%d', $args = array( 1 ) );
|
47 |
|
48 |
/**
|
49 |
+
* Save an active record into DB.
|
50 |
*
|
51 |
+
* @param object $active_record - ActiveRecord object.
|
52 |
+
* @return integer|boolean - Either the number of modified/inserted rows or false on failure.
|
53 |
*/
|
54 |
public function Save( $activeRecord );
|
55 |
|
56 |
/**
|
57 |
+
* Delete DB record.
|
58 |
*
|
59 |
+
* @param object $active_record - ActiveRecord object.
|
60 |
+
* @return int|boolean - Either the amount of deleted rows or False on error.
|
61 |
*/
|
62 |
public function Delete( $activeRecord );
|
63 |
|
64 |
/**
|
65 |
+
* Load multiple records from DB.
|
66 |
*
|
67 |
+
* @param string $cond (Optional) Load condition (eg: 'some_id = %d' ).
|
68 |
+
* @param array $args (Optional) Load condition arguments (rg: array(45) ).
|
69 |
+
*
|
70 |
+
* @return self[] List of loaded records.
|
71 |
*/
|
72 |
public function LoadMulti( $cond, $args = array() );
|
73 |
|
74 |
/**
|
75 |
+
* Load multiple records from DB and call a callback for each record.
|
76 |
+
* This function is very memory-efficient, it doesn't load records in bulk.
|
77 |
*
|
78 |
+
* @param callable $callback The callback to invoke.
|
79 |
+
* @param string $cond (Optional) Load condition.
|
80 |
+
* @param array $args (Optional) Load condition arguments.
|
81 |
*/
|
82 |
public function LoadAndCallForEach( $callback, $cond = '%d', $args = array( 1 ) );
|
83 |
|
84 |
/**
|
85 |
+
* Count records in the DB matching a condition.
|
86 |
+
* If no parameters are given, this counts the number of records in the DB table.
|
87 |
*
|
88 |
+
* @param string $cond (Optional) Query condition.
|
89 |
+
* @param array $args (Optional) Condition arguments.
|
90 |
+
* @return int Number of matching records.
|
91 |
*/
|
92 |
public function Count( $cond = '%d', $args = array( 1 ) );
|
93 |
|
94 |
/**
|
95 |
+
* Similar to LoadMulti but allows the use of a full SQL query.
|
96 |
+
*
|
97 |
+
* @param string $query Full SQL query.
|
98 |
+
* @param array $args (Optional) Query arguments.
|
99 |
*
|
100 |
+
* @return array List of loaded records.
|
101 |
+
* @throws Exception
|
102 |
*/
|
103 |
public function LoadMultiQuery( $query, $args = array() );
|
104 |
|
classes/Adapters/MetaInterface.php
CHANGED
@@ -20,16 +20,14 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
20 |
interface WSAL_Adapters_MetaInterface {
|
21 |
|
22 |
/**
|
23 |
-
*
|
24 |
*
|
25 |
-
* @param
|
26 |
-
*
|
27 |
-
* @return int ID of the new meta data
|
28 |
*/
|
29 |
public function DeleteByOccurrenceIds( $occurrence_ids );
|
30 |
|
31 |
/**
|
32 |
-
* Load by name and occurrence id.
|
33 |
*
|
34 |
* @param string $meta_name - Meta name.
|
35 |
* @param int $occurrence_id - Occurrence ID.
|
20 |
interface WSAL_Adapters_MetaInterface {
|
21 |
|
22 |
/**
|
23 |
+
* Deletes meta data belonging to given occurrences.
|
24 |
*
|
25 |
+
* @param int[] $occurrence_ids - Array of occurrence IDs.
|
|
|
|
|
26 |
*/
|
27 |
public function DeleteByOccurrenceIds( $occurrence_ids );
|
28 |
|
29 |
/**
|
30 |
+
* Load meta by name and occurrence id.
|
31 |
*
|
32 |
* @param string $meta_name - Meta name.
|
33 |
* @param int $occurrence_id - Occurrence ID.
|
classes/Adapters/MySQL/ActiveRecordAdapter.php
CHANGED
@@ -17,6 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
17 |
*
|
18 |
* MySQL generic table used for Save, Read, Create or Delete
|
19 |
* elements in the Database.
|
|
|
20 |
* There are also the functions used in the Report Add-On to get the reports.
|
21 |
*
|
22 |
* @package wsal
|
@@ -44,32 +45,79 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
44 |
*/
|
45 |
protected $_idkey = '';
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
/**
|
48 |
* Method: Constructor.
|
49 |
*
|
50 |
-
* @param object $
|
51 |
*/
|
52 |
-
public function __construct( $
|
53 |
-
$this->connection = $
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
-
*
|
58 |
*
|
59 |
-
* @
|
|
|
|
|
|
|
|
|
60 |
*/
|
61 |
-
public function
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
-
*
|
67 |
*
|
68 |
-
* @return
|
69 |
*/
|
70 |
-
public function
|
71 |
-
|
72 |
-
return $_wpdb->base_prefix . $this->_table;
|
73 |
}
|
74 |
|
75 |
/**
|
@@ -79,16 +127,51 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
79 |
*/
|
80 |
public function GetWPTable() {
|
81 |
global $wpdb;
|
|
|
82 |
return $wpdb->base_prefix . $this->_table;
|
83 |
}
|
84 |
|
85 |
/**
|
86 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
*
|
88 |
* @return string
|
89 |
*/
|
90 |
-
|
91 |
-
|
|
|
|
|
92 |
}
|
93 |
|
94 |
/**
|
@@ -99,7 +182,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
99 |
public function GetColumns() {
|
100 |
$model = $this->GetModel();
|
101 |
|
102 |
-
if (
|
103 |
$this->_column_cache = array();
|
104 |
foreach ( array_keys( get_object_vars( $model ) ) as $col ) {
|
105 |
if ( trim( $col ) && $col[0] != '_' ) {
|
@@ -107,37 +190,68 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
107 |
}
|
108 |
}
|
109 |
}
|
|
|
110 |
return $this->_column_cache;
|
111 |
}
|
112 |
|
113 |
/**
|
114 |
-
*
|
115 |
-
*
|
116 |
-
* @deprecated
|
117 |
-
* @return boolean
|
118 |
*/
|
119 |
-
public function
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
// Table transient.
|
124 |
-
$wsal_table_transient = 'wsal_' . strtolower( $this->GetTable() ) . '_status';
|
125 |
-
$wsal_db_table_status = get_transient( $wsal_table_transient );
|
126 |
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
}
|
132 |
-
|
|
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
-
*
|
|
|
|
|
137 |
*/
|
138 |
-
|
139 |
-
|
140 |
-
$_wpdb->query( $this->_GetInstallQuery() );
|
141 |
}
|
142 |
|
143 |
/**
|
@@ -149,7 +263,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
149 |
}
|
150 |
|
151 |
/**
|
152 |
-
*
|
153 |
*/
|
154 |
public function Uninstall() {
|
155 |
$_wpdb = $this->connection;
|
@@ -170,14 +284,21 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
170 |
|
171 |
// Query table exists.
|
172 |
$table_exists_query = "SHOW TABLES LIKE '" . $this->GetTable() . "'";
|
|
|
173 |
return $_wpdb->query( $table_exists_query );
|
174 |
}
|
175 |
|
176 |
/**
|
177 |
-
*
|
178 |
*
|
179 |
-
* @
|
180 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
*/
|
182 |
public function Save( $active_record ) {
|
183 |
$_wpdb = $this->connection;
|
@@ -185,7 +306,8 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
185 |
$data = array();
|
186 |
$format = array();
|
187 |
|
188 |
-
|
|
|
189 |
if ( $key == $this->_idkey ) {
|
190 |
$_id_index = $index;
|
191 |
}
|
@@ -195,14 +317,17 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
195 |
if ( is_int( $copy->$key ) ) {
|
196 |
$deffmt = '%d';
|
197 |
}
|
|
|
198 |
if ( is_float( $copy->$key ) ) {
|
199 |
$deffmt = '%f';
|
200 |
}
|
|
|
201 |
if ( is_array( $copy->$key ) || is_object( $copy->$key ) ) {
|
202 |
$data[ $key ] = WSAL_Helpers_DataHelper::JsonEncode( $val );
|
203 |
} else {
|
204 |
$data[ $key ] = $val;
|
205 |
}
|
|
|
206 |
$format[] = $deffmt;
|
207 |
}
|
208 |
|
@@ -216,6 +341,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
216 |
if ( false !== $result && $_wpdb->insert_id ) {
|
217 |
$copy->setId( $_wpdb->insert_id );
|
218 |
}
|
|
|
219 |
return $result;
|
220 |
}
|
221 |
|
@@ -223,13 +349,14 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
223 |
* Load record from DB (Single row).
|
224 |
*
|
225 |
* @param string $cond - (Optional) Load condition.
|
226 |
-
* @param array
|
227 |
*
|
228 |
* @return array
|
229 |
*/
|
230 |
public function Load( $cond = '%d', $args = array( 1 ) ) {
|
231 |
$_wpdb = $this->connection;
|
232 |
$sql = $_wpdb->prepare( 'SELECT * FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args );
|
|
|
233 |
return $_wpdb->get_row( $sql, ARRAY_A );
|
234 |
}
|
235 |
|
@@ -237,7 +364,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
237 |
* Load records from DB (Multi rows).
|
238 |
*
|
239 |
* @param string $cond Load condition.
|
240 |
-
* @param array
|
241 |
*
|
242 |
* @return array
|
243 |
* @throws Exception
|
@@ -249,20 +376,22 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
249 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
250 |
$result[] = $this->getModel()->LoadData( $data );
|
251 |
}
|
|
|
252 |
return $result;
|
253 |
}
|
254 |
|
255 |
/**
|
256 |
-
*
|
257 |
-
*
|
258 |
-
* @param object $active_record - ActiveRecord object.
|
259 |
-
* @return int|boolean - Either the amount of deleted rows or False on error.
|
260 |
*/
|
261 |
public function Delete( $active_record ) {
|
262 |
-
$_wpdb
|
|
|
263 |
return $_wpdb->delete(
|
264 |
$this->GetTable(),
|
265 |
-
|
|
|
|
|
|
|
266 |
);
|
267 |
}
|
268 |
|
@@ -270,24 +399,19 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
270 |
* Delete records in DB matching a query.
|
271 |
*
|
272 |
* @param string $query Full SQL query.
|
273 |
-
* @param array
|
274 |
*
|
275 |
* @return int|bool
|
276 |
*/
|
277 |
public function DeleteQuery( $query, $args = array() ) {
|
278 |
-
$_wpdb
|
279 |
-
$sql
|
|
|
280 |
return $_wpdb->query( $sql );
|
281 |
}
|
282 |
|
283 |
/**
|
284 |
-
*
|
285 |
-
*
|
286 |
-
* @param string $cond (Optional) Load condition (eg: 'some_id = %d' ).
|
287 |
-
* @param array $args (Optional) Load condition arguments (rg: array(45) ).
|
288 |
-
*
|
289 |
-
* @return self[] List of loaded records.
|
290 |
-
* @throws Exception
|
291 |
*/
|
292 |
public function LoadMulti( $cond, $args = array() ) {
|
293 |
$_wpdb = $this->connection;
|
@@ -298,16 +422,12 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
298 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
299 |
$result[] = $this->getModel()->LoadData( $data );
|
300 |
}
|
|
|
301 |
return $result;
|
302 |
}
|
303 |
|
304 |
/**
|
305 |
-
*
|
306 |
-
* This function is very memory-efficient, it doesn't load records in bulk.
|
307 |
-
*
|
308 |
-
* @param callable $callback The callback to invoke.
|
309 |
-
* @param string $cond (Optional) Load condition.
|
310 |
-
* @param array $args (Optional) Load condition arguments.
|
311 |
*/
|
312 |
public function LoadAndCallForEach( $callback, $cond = '%d', $args = array( 1 ) ) {
|
313 |
$_wpdb = $this->connection;
|
@@ -319,16 +439,12 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
319 |
}
|
320 |
|
321 |
/**
|
322 |
-
*
|
323 |
-
* If no parameters are given, this counts the number of records in the DB table.
|
324 |
-
*
|
325 |
-
* @param string $cond (Optional) Query condition.
|
326 |
-
* @param array $args (Optional) Condition arguments.
|
327 |
-
* @return int Number of matching records.
|
328 |
*/
|
329 |
public function Count( $cond = '%d', $args = array( 1 ) ) {
|
330 |
$_wpdb = $this->connection;
|
331 |
$sql = $_wpdb->prepare( 'SELECT COUNT(*) FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args );
|
|
|
332 |
return (int) $_wpdb->get_var( $sql );
|
333 |
}
|
334 |
|
@@ -336,23 +452,19 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
336 |
* Count records in the DB matching a query.
|
337 |
*
|
338 |
* @param string $query Full SQL query.
|
339 |
-
* @param array $args
|
|
|
340 |
* @return int Number of matching records.
|
341 |
*/
|
342 |
public function CountQuery( $query, $args = array() ) {
|
343 |
$_wpdb = $this->connection;
|
344 |
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
|
|
345 |
return (int) $_wpdb->get_var( $sql );
|
346 |
}
|
347 |
|
348 |
/**
|
349 |
-
*
|
350 |
-
*
|
351 |
-
* @param string $query Full SQL query.
|
352 |
-
* @param array $args (Optional) Query arguments.
|
353 |
-
*
|
354 |
-
* @return array List of loaded records.
|
355 |
-
* @throws Exception
|
356 |
*/
|
357 |
public function LoadMultiQuery( $query, $args = array() ) {
|
358 |
$_wpdb = $this->connection;
|
@@ -361,629 +473,496 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
361 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
362 |
$result[] = $this->getModel()->LoadData( $data );
|
363 |
}
|
|
|
364 |
return $result;
|
365 |
}
|
366 |
|
367 |
/**
|
368 |
-
*
|
369 |
*
|
370 |
-
* @param
|
371 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
372 |
*/
|
373 |
-
|
374 |
-
$_wpdb = $this->connection;
|
375 |
-
$class = get_class( $this );
|
376 |
-
$copy = new $class( $this->connection );
|
377 |
-
$table_name = ( $prefix ) ? $this->GetWPTable() : $this->GetTable();
|
378 |
-
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
379 |
|
380 |
-
|
381 |
-
|
382 |
-
switch ( true ) {
|
383 |
-
case $key == $copy->_idkey:
|
384 |
-
$sql .= $key . ' BIGINT NOT NULL AUTO_INCREMENT,' . PHP_EOL;
|
385 |
-
break;
|
386 |
-
case is_int( $copy->$key ):
|
387 |
-
$sql .= $key . ' BIGINT NOT NULL,' . PHP_EOL;
|
388 |
-
break;
|
389 |
-
case is_float( $copy->$key ):
|
390 |
-
$sql .= $key . ' DOUBLE NOT NULL,' . PHP_EOL;
|
391 |
-
break;
|
392 |
-
case is_string( $copy->$key ):
|
393 |
-
$maxlength = $key . '_maxlength';
|
394 |
-
if ( property_exists( $class, $maxlength ) ) {
|
395 |
-
$sql .= $key . ' VARCHAR(' . (int) $class::$$maxlength . ') NOT NULL,' . PHP_EOL;
|
396 |
-
} else {
|
397 |
-
$sql .= $key . ' LONGTEXT NOT NULL,' . PHP_EOL;
|
398 |
-
}
|
399 |
-
break;
|
400 |
-
case is_bool( $copy->$key ):
|
401 |
-
$sql .= $key . ' BIT NOT NULL,' . PHP_EOL;
|
402 |
-
break;
|
403 |
-
case is_array( $copy->$key ):
|
404 |
-
case is_object( $copy->$key ):
|
405 |
-
$sql .= $key . ' LONGTEXT NOT NULL,' . PHP_EOL;
|
406 |
-
break;
|
407 |
-
default:
|
408 |
-
}
|
409 |
-
}
|
410 |
|
411 |
-
|
|
|
412 |
|
413 |
-
|
|
|
|
|
414 |
|
415 |
-
if ( ! empty( $
|
416 |
-
$
|
|
|
|
|
|
|
|
|
|
|
417 |
}
|
418 |
|
419 |
-
return $
|
420 |
}
|
421 |
|
422 |
/**
|
423 |
-
*
|
424 |
-
* of WSAL to LONGTEXT.
|
425 |
*
|
426 |
-
* @
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
/**
|
436 |
-
* Must return SQL for removing table (at a minimum, it should be ` 'DROP TABLE ' . $this->_table `).
|
437 |
*
|
438 |
* @return string
|
439 |
*/
|
440 |
-
|
441 |
-
|
442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
443 |
|
444 |
-
|
445 |
-
|
446 |
-
*
|
447 |
-
* @param int $_user_id - User ID.
|
448 |
-
* @return string comma separated users login
|
449 |
-
*/
|
450 |
-
private function GetUserNames( $_user_id ) {
|
451 |
-
global $wpdb;
|
452 |
|
453 |
-
$
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
$
|
458 |
-
$users_array = array();
|
459 |
-
foreach ( $result as $item ) {
|
460 |
-
$users_array[] = '"' . $item['user_login'] . '"';
|
461 |
-
}
|
462 |
-
$user_names = implode( ', ', $users_array );
|
463 |
}
|
464 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
465 |
}
|
466 |
|
467 |
/**
|
468 |
-
*
|
469 |
*
|
470 |
* @param WSAL_ReportArgs $report_args Report arguments.
|
471 |
-
* @param int $_next_date - (Optional) Created on >.
|
472 |
-
* @param int $_limit - (Optional) Limit.
|
473 |
*
|
474 |
-
* @return
|
475 |
*/
|
476 |
-
|
477 |
-
|
478 |
-
$_wpdb = $this->connection;
|
479 |
-
$_wpdb->set_charset( $_wpdb->dbh, 'utf8mb4', 'utf8mb4_general_ci' );
|
480 |
-
|
481 |
-
// Tables.
|
482 |
-
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
483 |
-
$table_meta = $meta->GetTable(); // Metadata.
|
484 |
-
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
485 |
-
$table_occ = $occurrence->GetTable(); // Occurrences.
|
486 |
-
|
487 |
-
$condition_date = ! empty( $_next_date ) ? ' AND occ.created_on < ' . $_next_date : '';
|
488 |
-
|
489 |
-
$_site_id = 'null';
|
490 |
$sites_negate_expression = '';
|
491 |
if ( $report_args->site__in ) {
|
492 |
$_site_id = $this->formatArrayForQuery( $report_args->site__in );
|
493 |
-
}
|
494 |
$_site_id = $this->formatArrayForQuery( $report_args->site__not_in );
|
495 |
$sites_negate_expression = 'NOT';
|
496 |
}
|
497 |
|
498 |
-
$_user_id =
|
499 |
$users_negate_expression = '';
|
500 |
-
$users_subselect_operand = 'OR';
|
501 |
if ( $report_args->user__in ) {
|
502 |
$_user_id = $this->formatArrayForQuery( $report_args->user__in );
|
503 |
-
}
|
504 |
$_user_id = $this->formatArrayForQuery( $report_args->user__not_in );
|
505 |
$users_negate_expression = 'NOT';
|
506 |
-
$users_subselect_operand = 'AND';
|
507 |
}
|
508 |
|
509 |
$user_names = $this->GetUserNames( $_user_id );
|
510 |
|
511 |
-
$_role_name =
|
512 |
$roles_negate_expression = '';
|
513 |
if ( $report_args->role__in ) {
|
514 |
$_role_name = $this->formatArrayForQueryRegex( $report_args->role__in );
|
515 |
-
}
|
516 |
$_role_name = $this->formatArrayForQueryRegex( $report_args->role__not_in );
|
517 |
$roles_negate_expression = 'NOT';
|
518 |
}
|
519 |
|
520 |
-
$_alert_code
|
|
|
521 |
if ( $report_args->code__in ) {
|
522 |
$_alert_code = $this->formatArrayForQuery( $report_args->code__in );
|
|
|
|
|
|
|
523 |
}
|
524 |
|
525 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
526 |
if ( $report_args->post_type__in ) {
|
527 |
$_post_types = $this->formatArrayForQueryRegex( $report_args->post_type__in );
|
|
|
|
|
|
|
528 |
}
|
529 |
|
530 |
-
$_post_statuses
|
|
|
531 |
if ( $report_args->post_status__in ) {
|
532 |
$_post_statuses = $this->formatArrayForQueryRegex( $report_args->post_status__in );
|
|
|
|
|
|
|
533 |
}
|
534 |
|
535 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
536 |
$objects_negate_expression = '';
|
537 |
if ( $report_args->object__in ) {
|
538 |
$_objects = $this->formatArrayForQuery( $report_args->object__in );
|
539 |
-
}
|
540 |
$_objects = $this->formatArrayForQuery( $report_args->object__not_in );
|
541 |
$objects_negate_expression = 'NOT';
|
542 |
}
|
543 |
|
544 |
-
$_event_types =
|
545 |
$event_types_negate_expression = '';
|
546 |
if ( $report_args->type__in ) {
|
547 |
$_event_types = $this->formatArrayForQuery( $report_args->type__in );
|
548 |
-
}
|
549 |
-
$_event_types
|
550 |
$event_types_negate_expression = 'NOT';
|
551 |
}
|
552 |
|
553 |
-
$_start_timestamp =
|
554 |
if ( $report_args->start_date ) {
|
555 |
$start_datetime = DateTime::createFromFormat( 'Y-m-d H:i:s', $report_args->start_date . ' 00:00:00' );
|
556 |
$_start_timestamp = $start_datetime->format( 'U' );
|
557 |
}
|
558 |
|
559 |
-
$_end_timestamp =
|
560 |
if ( $report_args->end_date ) {
|
561 |
$end_datetime = DateTime::createFromFormat( 'Y-m-d H:i:s', $report_args->end_date . ' 23:59:59' );
|
562 |
$_end_timestamp = $end_datetime->format( 'U' );
|
563 |
}
|
564 |
|
565 |
-
$
|
566 |
-
|
567 |
-
|
568 |
-
{$users_negate_expression} EXISTS( SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='CurrentUserID' AND find_in_set( meta.value, @userId ) > 0)
|
569 |
-
$users_subselect_operand
|
570 |
-
{$users_negate_expression} EXISTS( SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='Username' AND replace(meta.value, '\"', '' ) IN ( $user_names ) )
|
571 |
-
)
|
572 |
-
)";
|
573 |
-
|
574 |
-
if ( 'null' === $_post_types && 'null' === $_post_statuses ) {
|
575 |
-
$sql = "SELECT DISTINCT
|
576 |
-
occ.id,
|
577 |
-
occ.alert_id,
|
578 |
-
occ.site_id,
|
579 |
-
occ.created_on,
|
580 |
-
replace(replace(replace((SELECT t1.value FROM $table_meta AS t1 WHERE t1.name = 'CurrentUserRoles' AND t1.occurrence_id = occ.id LIMIT 1), '[', ''), ']', ''), '\\'', '') AS roles,
|
581 |
-
(SELECT replace(t2.value, '\"','') FROM $table_meta as t2 WHERE t2.name = 'ClientIP' AND t2.occurrence_id = occ.id LIMIT 1) AS ip,
|
582 |
-
(SELECT replace(t3.value, '\"', '') FROM $table_meta as t3 WHERE t3.name = 'UserAgent' AND t3.occurrence_id = occ.id LIMIT 1) AS ua,
|
583 |
-
COALESCE(
|
584 |
-
(SELECT replace(t4.value, '\"', '') FROM $table_meta as t4 WHERE t4.name = 'Username' AND t4.occurrence_id = occ.id LIMIT 1),
|
585 |
-
(SELECT replace(t5.value, '\"', '') FROM $table_meta as t5 WHERE t5.name = 'CurrentUserID' AND t5.occurrence_id = occ.id LIMIT 1)
|
586 |
-
) as user_id,
|
587 |
-
(SELECT replace(t6.value, '\"', '') FROM $table_meta as t6 WHERE t6.name = 'Object' AND t6.occurrence_id = occ.id LIMIT 1) AS object,
|
588 |
-
(SELECT replace(t7.value, '\"', '') FROM $table_meta as t7 WHERE t7.name = 'EventType' AND t7.occurrence_id = occ.id LIMIT 1) AS event_type
|
589 |
-
FROM $table_occ AS occ
|
590 |
-
JOIN $table_meta AS meta ON meta.occurrence_id = occ.id
|
591 |
-
WHERE
|
592 |
-
(
|
593 |
-
@siteId is NULL
|
594 |
-
OR
|
595 |
-
{$sites_negate_expression} find_in_set( occ.site_id, @siteId ) > 0
|
596 |
-
)
|
597 |
-
AND {$users_condition}
|
598 |
-
AND (
|
599 |
-
@roleName is NULL
|
600 |
-
OR (
|
601 |
-
meta.name = 'CurrentUserRoles'
|
602 |
-
AND
|
603 |
-
replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') {$roles_negate_expression} REGEXP @roleName
|
604 |
-
)
|
605 |
-
)
|
606 |
-
AND (
|
607 |
-
@object is NULL
|
608 |
-
OR
|
609 |
-
{$objects_negate_expression} EXISTS( SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='Object' AND find_in_set( meta.value, @object ) > 0 )
|
610 |
-
)
|
611 |
-
AND (
|
612 |
-
@eventType is NULL
|
613 |
-
OR
|
614 |
-
{$event_types_negate_expression} EXISTS( SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='EventType' AND find_in_set( meta.value, @eventType ) > 0)
|
615 |
-
)
|
616 |
-
AND ( @alertCode is NULL OR find_in_set( occ.alert_id, @alertCode ) > 0)
|
617 |
-
AND ( @startTimestamp is NULL OR occ.created_on >= @startTimestamp )
|
618 |
-
AND ( @endTimestamp is NULL OR occ.created_on <= @endTimestamp )
|
619 |
-
{$condition_date}
|
620 |
-
ORDER BY
|
621 |
-
created_on DESC
|
622 |
-
";
|
623 |
-
} else {
|
624 |
-
$sql = "SELECT
|
625 |
-
occ.id,
|
626 |
-
occ.alert_id,
|
627 |
-
occ.site_id,
|
628 |
-
occ.created_on,
|
629 |
-
replace(replace(replace((SELECT t1.value FROM $table_meta AS t1 WHERE t1.name = 'CurrentUserRoles' AND t1.occurrence_id = occ.id LIMIT 1), '[', ''), ']', ''), '\\'', '') AS roles,
|
630 |
-
(SELECT replace(t2.value, '\"','') FROM $table_meta as t2 WHERE t2.name = 'ClientIP' AND t2.occurrence_id = occ.id LIMIT 1) AS ip,
|
631 |
-
(SELECT replace(t3.value, '\"', '') FROM $table_meta as t3 WHERE t3.name = 'UserAgent' AND t3.occurrence_id = occ.id LIMIT 1) AS ua,
|
632 |
-
COALESCE(
|
633 |
-
(SELECT replace(t4.value, '\"', '') FROM $table_meta as t4 WHERE t4.name = 'Username' AND t4.occurrence_id = occ.id LIMIT 1),
|
634 |
-
(SELECT replace(t5.value, '\"', '') FROM $table_meta as t5 WHERE t5.name = 'CurrentUserID' AND t5.occurrence_id = occ.id LIMIT 1)
|
635 |
-
) as user_id,
|
636 |
-
(SELECT replace(t6.value, '\"', '') FROM $table_meta as t6 WHERE t6.name = 'Object' AND t6.occurrence_id = occ.id LIMIT 1) AS object,
|
637 |
-
(SELECT replace(t7.value, '\"', '') FROM $table_meta as t7 WHERE t7.name = 'EventType' AND t7.occurrence_id = occ.id LIMIT 1) AS event_type
|
638 |
-
FROM
|
639 |
-
$table_occ as occ
|
640 |
-
WHERE
|
641 |
-
(
|
642 |
-
@siteId is NULL
|
643 |
-
OR
|
644 |
-
{$sites_negate_expression} find_in_set(occ.site_id, @siteId) > 0
|
645 |
-
)
|
646 |
-
AND {$users_condition}
|
647 |
-
AND (
|
648 |
-
@roleName is NULL
|
649 |
-
OR
|
650 |
-
{$roles_negate_expression} EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='CurrentUserRoles' AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName)
|
651 |
-
)
|
652 |
-
AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
|
653 |
-
AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
|
654 |
-
AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
|
655 |
-
AND (
|
656 |
-
@postType is NULL
|
657 |
-
OR
|
658 |
-
EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='PostType' AND find_in_set(meta.value, @postType) > 0)
|
659 |
-
)
|
660 |
-
AND (
|
661 |
-
@postStatus is NULL
|
662 |
-
OR
|
663 |
-
EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='PostStatus' AND find_in_set(meta.value, @postStatus) > 0)
|
664 |
-
)
|
665 |
-
AND (
|
666 |
-
@object is NULL
|
667 |
-
OR
|
668 |
-
{$objects_negate_expression} EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='Object' AND find_in_set(meta.value, @object) > 0)
|
669 |
-
)
|
670 |
-
AND (
|
671 |
-
@eventType is NULL
|
672 |
-
OR
|
673 |
-
{$event_types_negate_expression} EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='EventType' AND find_in_set(meta.value, @eventType) > 0)
|
674 |
-
)
|
675 |
-
{$condition_date}
|
676 |
-
ORDER BY
|
677 |
-
created_on DESC
|
678 |
-
";
|
679 |
}
|
680 |
|
681 |
-
|
682 |
-
|
683 |
-
$_wpdb->query( "SET @postType = $_post_types" );
|
684 |
-
$_wpdb->query( "SET @postStatus = $_post_statuses" );
|
685 |
-
$_wpdb->query( "SET @object = $_objects" );
|
686 |
-
$_wpdb->query( "SET @eventType = $_event_types" );
|
687 |
-
$_wpdb->query( "SET @roleName = $_role_name" );
|
688 |
-
$_wpdb->query( "SET @alertCode = $_alert_code" );
|
689 |
-
$_wpdb->query( "SET @startTimestamp = $_start_timestamp" );
|
690 |
-
$_wpdb->query( "SET @endTimestamp = $_end_timestamp" );
|
691 |
-
|
692 |
-
if ( ! empty( $_limit ) ) {
|
693 |
-
$sql .= " LIMIT {$_limit}";
|
694 |
}
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
|
|
699 |
}
|
700 |
|
701 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
702 |
}
|
703 |
|
704 |
/**
|
705 |
-
*
|
706 |
-
* Check if criteria are matching in the DB.
|
707 |
*
|
708 |
-
* @
|
709 |
-
* @
|
710 |
*/
|
711 |
-
|
712 |
-
$
|
713 |
-
|
714 |
-
$_post_types = $criteria['post_types'];
|
715 |
-
$_post_statuses = $criteria['post_statuses'];
|
716 |
-
$_role_name = $criteria['roleName'];
|
717 |
-
$_alert_code = $criteria['alertCode'];
|
718 |
-
$_start_timestamp = $criteria['startTimestamp'];
|
719 |
-
$_end_timestamp = $criteria['endTimestamp'];
|
720 |
-
$_ip_address = $criteria['ipAddress'];
|
721 |
-
|
722 |
-
$_wpdb = $this->connection;
|
723 |
-
$_wpdb->set_charset( $_wpdb->dbh, 'utf8mb4', 'utf8mb4_general_ci' );
|
724 |
-
// Tables.
|
725 |
-
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
726 |
-
$table_meta = $meta->GetTable(); // Metadata.
|
727 |
-
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
728 |
-
$table_occ = $occurrence->GetTable(); // Occurrences.
|
729 |
|
730 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
731 |
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName
|
743 |
-
))
|
744 |
-
AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
|
745 |
-
AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
|
746 |
-
AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
|
747 |
-
AND (@ipAddress is NULL OR (meta.name = 'ClientIP' AND find_in_set(meta.value, @ipAddress) > 0))
|
748 |
-
";
|
749 |
-
} else {
|
750 |
-
$sql = "SELECT COUNT(DISTINCT occ.id)
|
751 |
-
FROM $table_occ AS occ
|
752 |
-
WHERE
|
753 |
-
(@siteId is NULL OR find_in_set(occ.site_id, @siteId) > 0)
|
754 |
-
AND (
|
755 |
-
@userId is NULL
|
756 |
-
OR (
|
757 |
-
EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='CurrentUserID' AND find_in_set(meta.value, @userId) > 0)
|
758 |
-
OR
|
759 |
-
EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='Username' AND replace(meta.value, '\"', '') IN ($user_names))
|
760 |
-
)
|
761 |
-
)
|
762 |
-
AND (
|
763 |
-
@roleName is NULL
|
764 |
-
OR
|
765 |
-
EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='CurrentUserRoles' AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName)
|
766 |
-
)
|
767 |
-
AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
|
768 |
-
AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
|
769 |
-
AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
|
770 |
-
AND (
|
771 |
-
@ipAddress is NULL
|
772 |
-
OR
|
773 |
-
EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='ClientIP' AND find_in_set(meta.value, @ipAddress) > 0)
|
774 |
-
)
|
775 |
-
AND (
|
776 |
-
@postType is NULL
|
777 |
-
OR
|
778 |
-
EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='PostType' AND find_in_set(meta.value, @postType) > 0)
|
779 |
-
)
|
780 |
-
AND (
|
781 |
-
@postStatus is NULL
|
782 |
-
OR
|
783 |
-
EXISTS(SELECT 1 FROM $table_meta as meta WHERE meta.occurrence_id = occ.id AND meta.name='PostStatus' AND find_in_set(meta.value, @postStatus) > 0)
|
784 |
-
)
|
785 |
-
";
|
786 |
}
|
787 |
|
788 |
-
|
789 |
-
|
790 |
-
$_wpdb->query( "SET @postType = $_post_types" );
|
791 |
-
$_wpdb->query( "SET @postStatus = $_post_statuses" );
|
792 |
-
$_wpdb->query( "SET @roleName = $_role_name" );
|
793 |
-
$_wpdb->query( "SET @alertCode = $_alert_code" );
|
794 |
-
$_wpdb->query( "SET @startTimestamp = $_start_timestamp" );
|
795 |
-
$_wpdb->query( "SET @endTimestamp = $_end_timestamp" );
|
796 |
-
$_wpdb->query( "SET @ipAddress = $_ip_address" );
|
797 |
|
798 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
799 |
}
|
800 |
|
801 |
/**
|
802 |
* Function used in WSAL reporting extension.
|
803 |
-
*
|
804 |
*
|
805 |
-
* @param WSAL_ReportArgs $report_args
|
806 |
-
* @param int $_limit - (Optional) Limit.
|
807 |
*
|
808 |
-
* @return
|
809 |
*/
|
810 |
-
public function
|
|
|
811 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
812 |
global $wpdb;
|
813 |
$_wpdb = $this->connection;
|
814 |
-
$_wpdb->set_charset( $_wpdb->dbh, 'utf8mb4', 'utf8mb4_general_ci' );
|
815 |
|
816 |
// Tables.
|
817 |
-
$
|
818 |
-
$
|
819 |
-
|
820 |
-
$table_occ = $occurrence->GetTable(); // Occurrences.
|
821 |
// Get temp table `wsal_tmp_users`.
|
822 |
-
$tmp_users = new WSAL_Adapters_MySQL_TmpUser( $
|
823 |
// If the table exist.
|
824 |
if ( $tmp_users->IsInstalled() ) {
|
825 |
-
$table_users = $tmp_users->GetTable();
|
826 |
$this->TempUsers( $table_users );
|
827 |
} else {
|
828 |
$table_users = $wpdb->users;
|
829 |
}
|
830 |
|
831 |
-
|
832 |
-
$
|
833 |
-
if ( $report_args->site__in ) {
|
834 |
-
$_site_id = $this->formatArrayForQuery( $report_args->site__in );
|
835 |
-
} else if ( $report_args->site__not_in ) {
|
836 |
-
$_site_id = $this->formatArrayForQuery( $report_args->site__not_in );
|
837 |
-
$sites_negate_expression = 'NOT';
|
838 |
-
}
|
839 |
-
|
840 |
-
$_user_id = 'null';
|
841 |
-
$users_negate_expression = '';
|
842 |
-
if ( $report_args->user__in ) {
|
843 |
-
$_user_id = $this->formatArrayForQuery( $report_args->user__in );
|
844 |
-
} else if ( $report_args->user__not_in ) {
|
845 |
-
$_user_id = $this->formatArrayForQuery( $report_args->user__not_in );
|
846 |
-
$users_negate_expression = 'NOT';
|
847 |
-
}
|
848 |
|
849 |
-
|
850 |
-
$
|
851 |
-
|
852 |
-
|
853 |
-
} else if ( $report_args->role__not_in ) {
|
854 |
-
$_role_name = $this->formatArrayForQueryRegex( $report_args->role__not_in );
|
855 |
-
$roles_negate_expression = 'NOT';
|
856 |
-
}
|
857 |
|
858 |
-
|
859 |
-
|
860 |
-
$_alert_code = $this->formatArrayForQuery( $report_args->code__in );
|
861 |
}
|
862 |
|
863 |
-
|
864 |
-
|
865 |
-
if ( $report_args->ip__in ) {
|
866 |
-
$_ip_address = $this->formatArrayForQuery( $report_args->ip__in );
|
867 |
-
} else if ( $report_args->ip__not_in ) {
|
868 |
-
$_ip_address = $this->formatArrayForQuery( $report_args->ip__not_in );
|
869 |
-
$ip_address_negate_expression = 'NOT';
|
870 |
}
|
871 |
|
872 |
-
$
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
882 |
}
|
883 |
|
884 |
-
$
|
885 |
|
886 |
-
$
|
887 |
-
|
888 |
-
|
889 |
-
$_wpdb->query( "SET @alertCode = $_alert_code" );
|
890 |
-
$_wpdb->query( "SET @startTimestamp = $_start_timestamp" );
|
891 |
-
$_wpdb->query( "SET @endTimestamp = $_end_timestamp" );
|
892 |
-
$_wpdb->query( "SET @ipAddress = $_ip_address" );
|
893 |
-
|
894 |
-
$sql = "SELECT DISTINCT *
|
895 |
-
FROM (SELECT DISTINCT
|
896 |
-
occ.site_id,
|
897 |
-
CONVERT((SELECT replace(t1.value, '\"', '') FROM $table_meta as t1 WHERE t1.name = 'Username' AND t1.occurrence_id = occ.id LIMIT 1) using UTF8) AS user_login ,
|
898 |
-
CONVERT((SELECT replace(t3.value, '\"','') FROM $table_meta as t3 WHERE t3.name = 'ClientIP' AND t3.occurrence_id = occ.id LIMIT 1) using UTF8) AS ip
|
899 |
FROM $table_occ AS occ
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
OR
|
905 |
-
{$sites_negate_expression} find_in_set(occ.site_id, @siteId) > 0
|
906 |
-
)
|
907 |
-
AND (
|
908 |
-
@userId is NULL
|
909 |
-
OR $users_negate_expression (
|
910 |
-
( meta.name = 'CurrentUserID' AND find_in_set(meta.value, @userId) > 0 )
|
911 |
-
OR
|
912 |
-
( meta.name = 'Username' AND replace(meta.value, '\"', '') IN ($user_names) )
|
913 |
-
)
|
914 |
-
)
|
915 |
-
AND (
|
916 |
-
@roleName is NULL
|
917 |
-
OR (
|
918 |
-
meta.name = 'CurrentUserRoles' AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') {$roles_negate_expression} REGEXP @roleName
|
919 |
-
)
|
920 |
-
)
|
921 |
-
AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
|
922 |
-
AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
|
923 |
-
AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
|
924 |
-
AND (@ipAddress is NULL OR (meta.name = 'ClientIP' AND {$ip_address_negate_expression} find_in_set(meta.value, @ipAddress) > 0))
|
925 |
-
HAVING user_login IS NOT NULL
|
926 |
-
UNION ALL
|
927 |
-
SELECT DISTINCT
|
928 |
-
occ.site_id,
|
929 |
-
CONVERT((SELECT u.user_login
|
930 |
-
FROM $table_meta as t2
|
931 |
-
JOIN $table_users AS u ON u.ID = replace(t2.value, '\"', '')
|
932 |
-
WHERE t2.name = 'CurrentUserID'
|
933 |
-
AND t2.occurrence_id = occ.id
|
934 |
-
GROUP BY u.ID
|
935 |
-
LIMIT 1) using UTF8) AS user_login,
|
936 |
-
CONVERT((SELECT replace(t4.value, '\"','') FROM $table_meta as t4 WHERE t4.name = 'ClientIP' AND t4.occurrence_id = occ.id LIMIT 1) using UTF8) AS ip
|
937 |
FROM $table_occ AS occ
|
938 |
-
JOIN $
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
HAVING user_login IS NOT NULL) ip_logins
|
953 |
-
WHERE user_login NOT IN ('Unregistered user', 'Plugins', 'Plugin')
|
954 |
-
ORDER BY user_login ASC
|
955 |
-
";
|
956 |
-
|
957 |
-
if ( ! empty( $_limit ) ) {
|
958 |
-
$sql .= " LIMIT {$_limit}";
|
959 |
}
|
960 |
|
961 |
-
$
|
962 |
-
$results
|
963 |
-
|
964 |
-
|
965 |
-
// Get the display_name only for the first row & if the user_login changed from the previous row.
|
966 |
-
$row->display_name = '';
|
967 |
-
if ( 0 == $key || ( $key > 1 && $results[ ( $key - 1 ) ]->user_login != $row->user_login ) ) {
|
968 |
-
$sql = "SELECT t5.display_name FROM $wpdb->users AS t5 WHERE t5.user_login = \"$row->user_login\"";
|
969 |
-
$display_name = $wpdb->get_var( $sql );
|
970 |
-
$row->display_name = $display_name;
|
971 |
-
}
|
972 |
|
973 |
-
|
974 |
-
|
975 |
-
'site_id' => $row->site_id,
|
976 |
-
'user_login' => $row->user_login,
|
977 |
-
'display_name' => $row->display_name,
|
978 |
-
'ips' => array(),
|
979 |
-
);
|
980 |
-
}
|
981 |
|
982 |
-
|
983 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
984 |
}
|
985 |
|
986 |
-
return $
|
987 |
}
|
988 |
|
989 |
/**
|
@@ -1013,51 +992,21 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
1013 |
/**
|
1014 |
* Updates records in DB matching a query.
|
1015 |
*
|
1016 |
-
* @param string
|
1017 |
-
* @param array
|
1018 |
-
* Both $data columns and $data values should be "raw" (neither should be SQL
|
1019 |
-
* Sending a null value will cause the column to be set to NULL - the
|
1020 |
-
* format is ignored in this case.
|
1021 |
-
* @param array
|
1022 |
* Multiple clauses will be joined with ANDs.
|
1023 |
* Both $where columns and $where values should be "raw".
|
1024 |
-
* Sending a null value will create an IS NULL comparison - the corresponding
|
|
|
|
|
1025 |
* @return int|false The number of rows updated, or false on error.
|
1026 |
* @since 4.1.3
|
1027 |
*/
|
1028 |
public function UpdateQuery( $table, $data, $where ) {
|
1029 |
return $this->connection->update( $table, $data, $where );
|
1030 |
}
|
1031 |
-
|
1032 |
-
/**
|
1033 |
-
* @inheritDoc
|
1034 |
-
*/
|
1035 |
-
public function GetModel() {
|
1036 |
-
// implement in subclass
|
1037 |
-
}
|
1038 |
-
|
1039 |
-
/**
|
1040 |
-
* @param array $data
|
1041 |
-
*
|
1042 |
-
* @return string
|
1043 |
-
* @since 4.3.2
|
1044 |
-
*/
|
1045 |
-
protected function formatArrayForQuery( $data ) {
|
1046 |
-
return "'" . implode( ',', $data ) . "'";
|
1047 |
-
}
|
1048 |
-
|
1049 |
-
/**
|
1050 |
-
* @param array $data
|
1051 |
-
*
|
1052 |
-
* @return string
|
1053 |
-
* @since 4.3.2
|
1054 |
-
*/
|
1055 |
-
protected function formatArrayForQueryRegex( $data ) {
|
1056 |
-
$result = array();
|
1057 |
-
foreach ( $data as $item ) {
|
1058 |
-
array_push( $result, esc_sql( preg_quote( $item ) ) );
|
1059 |
-
}
|
1060 |
-
|
1061 |
-
return "'" . implode( '|', $result ) . "'";
|
1062 |
-
}
|
1063 |
}
|
17 |
*
|
18 |
* MySQL generic table used for Save, Read, Create or Delete
|
19 |
* elements in the Database.
|
20 |
+
*
|
21 |
* There are also the functions used in the Report Add-On to get the reports.
|
22 |
*
|
23 |
* @package wsal
|
45 |
*/
|
46 |
protected $_idkey = '';
|
47 |
|
48 |
+
/**
|
49 |
+
* Local cache for a list of columns.
|
50 |
+
*
|
51 |
+
* @var string[]
|
52 |
+
*/
|
53 |
+
protected $_column_cache = [];
|
54 |
+
|
55 |
/**
|
56 |
* Method: Constructor.
|
57 |
*
|
58 |
+
* @param object $connection - DB connection object.
|
59 |
*/
|
60 |
+
public function __construct( $connection ) {
|
61 |
+
$this->connection = $connection;
|
62 |
}
|
63 |
|
64 |
/**
|
65 |
+
* Works out the grouping data entities for given statistical report type.
|
66 |
*
|
67 |
+
* @param int $statistics_report_type Statistical report type.
|
68 |
+
* @param string $grouping_period Period to use for data grouping.
|
69 |
+
*
|
70 |
+
* @return string[]|null
|
71 |
+
* @since 4.4.0
|
72 |
*/
|
73 |
+
public static function get_grouping( $statistics_report_type, $grouping_period ) {
|
74 |
+
$grouping = null;
|
75 |
+
if ( ! is_null( $statistics_report_type ) ) {
|
76 |
+
$grouping = array( 'site' );
|
77 |
+
if ( ! is_null( $grouping_period ) ) {
|
78 |
+
array_push( $grouping, $grouping_period );
|
79 |
+
}
|
80 |
+
|
81 |
+
switch ( $statistics_report_type ) {
|
82 |
+
case WSAL_Rep_Common::DIFFERENT_IP:
|
83 |
+
array_push( $grouping, 'users' );
|
84 |
+
array_push( $grouping, 'ips' );
|
85 |
+
break;
|
86 |
+
case WSAL_Rep_Common::ALL_IPS:
|
87 |
+
array_push( $grouping, 'ips' );
|
88 |
+
break;
|
89 |
+
case WSAL_Rep_Common::LOGIN_ALL:
|
90 |
+
case WSAL_Rep_Common::LOGIN_BY_USER:
|
91 |
+
case WSAL_Rep_Common::LOGIN_BY_ROLE:
|
92 |
+
case WSAL_Rep_Common::PUBLISHED_ALL:
|
93 |
+
case WSAL_Rep_Common::PUBLISHED_BY_USER:
|
94 |
+
case WSAL_Rep_Common::PUBLISHED_BY_ROLE:
|
95 |
+
case WSAL_Rep_Common::ALL_USERS:
|
96 |
+
array_push( $grouping, 'users' );
|
97 |
+
break;
|
98 |
+
|
99 |
+
case WSAL_Rep_Common::VIEWS_ALL:
|
100 |
+
array_push( $grouping, 'posts' );
|
101 |
+
break;
|
102 |
+
|
103 |
+
case WSAL_Rep_Common::VIEWS_BY_USER:
|
104 |
+
case WSAL_Rep_Common::VIEWS_BY_ROLE:
|
105 |
+
array_push( $grouping, 'users' );
|
106 |
+
array_push( $grouping, 'posts' );
|
107 |
+
break;
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
return $grouping;
|
112 |
}
|
113 |
|
114 |
/**
|
115 |
+
* Method: Get connection.
|
116 |
*
|
117 |
+
* @return object – DB connection object.
|
118 |
*/
|
119 |
+
public function get_connection() {
|
120 |
+
return $this->connection;
|
|
|
121 |
}
|
122 |
|
123 |
/**
|
127 |
*/
|
128 |
public function GetWPTable() {
|
129 |
global $wpdb;
|
130 |
+
|
131 |
return $wpdb->base_prefix . $this->_table;
|
132 |
}
|
133 |
|
134 |
/**
|
135 |
+
* @inheritDoc
|
136 |
+
*/
|
137 |
+
public function Install() {
|
138 |
+
$_wpdb = $this->connection;
|
139 |
+
$_wpdb->query( $this->_GetInstallQuery() );
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Table install query.
|
144 |
+
*
|
145 |
+
* @param string|false $prefix - (Optional) Table prefix.
|
146 |
+
*
|
147 |
+
* @return string - Must return SQL for creating table.
|
148 |
+
*/
|
149 |
+
protected function _GetInstallQuery( $prefix = false ) {
|
150 |
+
$_wpdb = $this->connection;
|
151 |
+
$class = get_class( $this );
|
152 |
+
$copy = new $class( $this->connection );
|
153 |
+
$table_name = $this->GetTable();
|
154 |
+
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
155 |
+
$cols = $this->GetColumns();
|
156 |
+
foreach ( $cols as $key ) {
|
157 |
+
$sql .= $this->_GetSqlColumnDefinition( $copy, $key );
|
158 |
+
}
|
159 |
+
|
160 |
+
$sql .= $this->GetTableOptions() . PHP_EOL;
|
161 |
+
$sql .= ') ' . $_wpdb->get_charset_collate();
|
162 |
+
|
163 |
+
return $sql;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Returns table name.
|
168 |
*
|
169 |
* @return string
|
170 |
*/
|
171 |
+
public function GetTable() {
|
172 |
+
$_wpdb = $this->connection;
|
173 |
+
|
174 |
+
return $_wpdb->base_prefix . $this->_table;
|
175 |
}
|
176 |
|
177 |
/**
|
182 |
public function GetColumns() {
|
183 |
$model = $this->GetModel();
|
184 |
|
185 |
+
if ( empty( $this->_column_cache ) ) {
|
186 |
$this->_column_cache = array();
|
187 |
foreach ( array_keys( get_object_vars( $model ) ) as $col ) {
|
188 |
if ( trim( $col ) && $col[0] != '_' ) {
|
190 |
}
|
191 |
}
|
192 |
}
|
193 |
+
|
194 |
return $this->_column_cache;
|
195 |
}
|
196 |
|
197 |
/**
|
198 |
+
* @inheritDoc
|
|
|
|
|
|
|
199 |
*/
|
200 |
+
public function GetModel() {
|
201 |
+
return new WSAL_Models_Query();
|
202 |
+
}
|
|
|
|
|
|
|
|
|
203 |
|
204 |
+
/**
|
205 |
+
* Generate SQL column definition string for the CREATE TABLE statement.
|
206 |
+
*
|
207 |
+
* @param object $copy
|
208 |
+
* @param string $key
|
209 |
+
*
|
210 |
+
* @return string
|
211 |
+
*/
|
212 |
+
protected function _GetSqlColumnDefinition( $copy, $key ) {
|
213 |
+
$result = ' ';
|
214 |
+
switch ( true ) {
|
215 |
+
case ( $key === $this->_idkey ):
|
216 |
+
$result .= $key . ' BIGINT NOT NULL AUTO_INCREMENT,' . PHP_EOL;
|
217 |
+
break;
|
218 |
+
case is_int( $copy->$key ):
|
219 |
+
$result .= $key . ' BIGINT NOT NULL,' . PHP_EOL;
|
220 |
+
break;
|
221 |
+
case is_float( $copy->$key ):
|
222 |
+
$result .= $key . ' DOUBLE NOT NULL,' . PHP_EOL;
|
223 |
+
break;
|
224 |
+
case is_string( $copy->$key ):
|
225 |
+
$maxlength = $key . '_maxlength';
|
226 |
+
if ( property_exists( $copy, $maxlength ) ) {
|
227 |
+
// The double `$$` is intentional.
|
228 |
+
$result .= $key . ' VARCHAR(' . (int) $copy::$$maxlength . ') NOT NULL,' . PHP_EOL;
|
229 |
+
} else {
|
230 |
+
$result .= $key . ' LONGTEXT NOT NULL,' . PHP_EOL;
|
231 |
+
}
|
232 |
+
break;
|
233 |
+
case is_bool( $copy->$key ):
|
234 |
+
$result .= $key . ' BIT NOT NULL,' . PHP_EOL;
|
235 |
+
break;
|
236 |
+
case is_array( $copy->$key ):
|
237 |
+
case is_object( $copy->$key ):
|
238 |
+
$result .= $key . ' LONGTEXT NOT NULL,' . PHP_EOL;
|
239 |
+
break;
|
240 |
+
default:
|
241 |
+
// fallback for any other columns would go here
|
242 |
+
break;
|
243 |
}
|
244 |
+
|
245 |
+
return $result;
|
246 |
}
|
247 |
|
248 |
/**
|
249 |
+
* SQL table options (constraints, foreign keys, indexes etc).
|
250 |
+
*
|
251 |
+
* @return string
|
252 |
*/
|
253 |
+
protected function GetTableOptions() {
|
254 |
+
return ' PRIMARY KEY (' . $this->_idkey . ')';
|
|
|
255 |
}
|
256 |
|
257 |
/**
|
263 |
}
|
264 |
|
265 |
/**
|
266 |
+
* @inheritDoc
|
267 |
*/
|
268 |
public function Uninstall() {
|
269 |
$_wpdb = $this->connection;
|
284 |
|
285 |
// Query table exists.
|
286 |
$table_exists_query = "SHOW TABLES LIKE '" . $this->GetTable() . "'";
|
287 |
+
|
288 |
return $_wpdb->query( $table_exists_query );
|
289 |
}
|
290 |
|
291 |
/**
|
292 |
+
* Must return SQL for removing table (at a minimum, it should be ` 'DROP TABLE ' . $this->_table `).
|
293 |
*
|
294 |
+
* @return string
|
295 |
+
*/
|
296 |
+
protected function _GetUninstallQuery() {
|
297 |
+
return 'DROP TABLE IF EXISTS ' . $this->GetTable();
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* @inheritDoc
|
302 |
*/
|
303 |
public function Save( $active_record ) {
|
304 |
$_wpdb = $this->connection;
|
306 |
$data = array();
|
307 |
$format = array();
|
308 |
|
309 |
+
$columns = $this->GetColumns();
|
310 |
+
foreach ( $columns as $index => $key ) {
|
311 |
if ( $key == $this->_idkey ) {
|
312 |
$_id_index = $index;
|
313 |
}
|
317 |
if ( is_int( $copy->$key ) ) {
|
318 |
$deffmt = '%d';
|
319 |
}
|
320 |
+
|
321 |
if ( is_float( $copy->$key ) ) {
|
322 |
$deffmt = '%f';
|
323 |
}
|
324 |
+
|
325 |
if ( is_array( $copy->$key ) || is_object( $copy->$key ) ) {
|
326 |
$data[ $key ] = WSAL_Helpers_DataHelper::JsonEncode( $val );
|
327 |
} else {
|
328 |
$data[ $key ] = $val;
|
329 |
}
|
330 |
+
|
331 |
$format[] = $deffmt;
|
332 |
}
|
333 |
|
341 |
if ( false !== $result && $_wpdb->insert_id ) {
|
342 |
$copy->setId( $_wpdb->insert_id );
|
343 |
}
|
344 |
+
|
345 |
return $result;
|
346 |
}
|
347 |
|
349 |
* Load record from DB (Single row).
|
350 |
*
|
351 |
* @param string $cond - (Optional) Load condition.
|
352 |
+
* @param array $args - (Optional) Load condition arguments.
|
353 |
*
|
354 |
* @return array
|
355 |
*/
|
356 |
public function Load( $cond = '%d', $args = array( 1 ) ) {
|
357 |
$_wpdb = $this->connection;
|
358 |
$sql = $_wpdb->prepare( 'SELECT * FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args );
|
359 |
+
|
360 |
return $_wpdb->get_row( $sql, ARRAY_A );
|
361 |
}
|
362 |
|
364 |
* Load records from DB (Multi rows).
|
365 |
*
|
366 |
* @param string $cond Load condition.
|
367 |
+
* @param array $args (Optional) Load condition arguments.
|
368 |
*
|
369 |
* @return array
|
370 |
* @throws Exception
|
376 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
377 |
$result[] = $this->getModel()->LoadData( $data );
|
378 |
}
|
379 |
+
|
380 |
return $result;
|
381 |
}
|
382 |
|
383 |
/**
|
384 |
+
* @inheritDoc
|
|
|
|
|
|
|
385 |
*/
|
386 |
public function Delete( $active_record ) {
|
387 |
+
$_wpdb = $this->connection;
|
388 |
+
|
389 |
return $_wpdb->delete(
|
390 |
$this->GetTable(),
|
391 |
+
array(
|
392 |
+
$this->_idkey => $active_record->getId(),
|
393 |
+
),
|
394 |
+
array( '%d' )
|
395 |
);
|
396 |
}
|
397 |
|
399 |
* Delete records in DB matching a query.
|
400 |
*
|
401 |
* @param string $query Full SQL query.
|
402 |
+
* @param array $args (Optional) Query arguments.
|
403 |
*
|
404 |
* @return int|bool
|
405 |
*/
|
406 |
public function DeleteQuery( $query, $args = array() ) {
|
407 |
+
$_wpdb = $this->connection;
|
408 |
+
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
409 |
+
|
410 |
return $_wpdb->query( $sql );
|
411 |
}
|
412 |
|
413 |
/**
|
414 |
+
* @inheritDoc
|
|
|
|
|
|
|
|
|
|
|
|
|
415 |
*/
|
416 |
public function LoadMulti( $cond, $args = array() ) {
|
417 |
$_wpdb = $this->connection;
|
422 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
423 |
$result[] = $this->getModel()->LoadData( $data );
|
424 |
}
|
425 |
+
|
426 |
return $result;
|
427 |
}
|
428 |
|
429 |
/**
|
430 |
+
* @inheritDoc
|
|
|
|
|
|
|
|
|
|
|
431 |
*/
|
432 |
public function LoadAndCallForEach( $callback, $cond = '%d', $args = array( 1 ) ) {
|
433 |
$_wpdb = $this->connection;
|
439 |
}
|
440 |
|
441 |
/**
|
442 |
+
* @inheritDoc
|
|
|
|
|
|
|
|
|
|
|
443 |
*/
|
444 |
public function Count( $cond = '%d', $args = array( 1 ) ) {
|
445 |
$_wpdb = $this->connection;
|
446 |
$sql = $_wpdb->prepare( 'SELECT COUNT(*) FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args );
|
447 |
+
|
448 |
return (int) $_wpdb->get_var( $sql );
|
449 |
}
|
450 |
|
452 |
* Count records in the DB matching a query.
|
453 |
*
|
454 |
* @param string $query Full SQL query.
|
455 |
+
* @param array $args (Optional) Query arguments.
|
456 |
+
*
|
457 |
* @return int Number of matching records.
|
458 |
*/
|
459 |
public function CountQuery( $query, $args = array() ) {
|
460 |
$_wpdb = $this->connection;
|
461 |
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
462 |
+
|
463 |
return (int) $_wpdb->get_var( $sql );
|
464 |
}
|
465 |
|
466 |
/**
|
467 |
+
* @inheritDoc
|
|
|
|
|
|
|
|
|
|
|
|
|
468 |
*/
|
469 |
public function LoadMultiQuery( $query, $args = array() ) {
|
470 |
$_wpdb = $this->connection;
|
473 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
474 |
$result[] = $this->getModel()->LoadData( $data );
|
475 |
}
|
476 |
+
|
477 |
return $result;
|
478 |
}
|
479 |
|
480 |
/**
|
481 |
+
* Retrieves report data for generic (alerts based) report. Function used in WSAL reporting extension.
|
482 |
*
|
483 |
+
* @param WSAL_ReportArgs $report_args Report arguments.
|
484 |
+
* @param int $next_date (Optional) Created on >.
|
485 |
+
* @param int $limit (Optional) Limit.
|
486 |
+
* @param int $statistics_report_type Statistics report type.
|
487 |
+
* @param string $grouping_period Period to use for data grouping.
|
488 |
+
*
|
489 |
+
* @return array Report results
|
490 |
*/
|
491 |
+
public function get_report_data( $report_args, $next_date = null, $limit = 0, $statistics_report_type = null, $grouping_period = null ) {
|
|
|
|
|
|
|
|
|
|
|
492 |
|
493 |
+
// Figure out the grouping statement and the columns' selection.
|
494 |
+
$grouping = self::get_grouping( $statistics_report_type, $grouping_period );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
495 |
|
496 |
+
// Build the SQL query and runs it.
|
497 |
+
$query = $this->build_reporting_query( $report_args, false, $grouping, $next_date, $limit );
|
498 |
|
499 |
+
// Statistical reports expect data as array, regular reports use objects.
|
500 |
+
$result_format = is_null( $statistics_report_type ) ? OBJECT : ARRAY_A;
|
501 |
+
$results = $this->connection->get_results( $query, $result_format );
|
502 |
|
503 |
+
if ( ! empty( $results ) ) {
|
504 |
+
$last_item = end( $results );
|
505 |
+
if ( is_object( $last_item ) && property_exists( $last_item, 'created_on' ) ) {
|
506 |
+
$results['lastDate'] = $last_item->created_on;
|
507 |
+
} elseif ( is_array( $last_item ) && array_key_exists( 'created_on', $last_item ) ) {
|
508 |
+
$results['lastDate'] = $last_item['created_on'];
|
509 |
+
}
|
510 |
}
|
511 |
|
512 |
+
return $results;
|
513 |
}
|
514 |
|
515 |
/**
|
516 |
+
* Builds an SQL query for the main report.
|
|
|
517 |
*
|
518 |
+
* @param WSAL_ReportArgs $report_args Report arguments.
|
519 |
+
* @param bool $count_only If true, the resulting query will only provide a count of matching entries
|
520 |
+
* is
|
521 |
+
* returned.
|
522 |
+
* @param array $grouping Grouping criteria. Drives the selected columns as well as the GROUP BY
|
523 |
+
* statement. Only null value prevents grouping. Empty array means to group by
|
524 |
+
* time period only.
|
525 |
+
* @param int $next_date (Optional) Created on >.
|
526 |
+
* @param int $limit (Optional) Limit.
|
|
|
|
|
527 |
*
|
528 |
* @return string
|
529 |
*/
|
530 |
+
private function build_reporting_query( $report_args, $count_only, $grouping = null, $next_date = null, $limit = 0 ) {
|
531 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
532 |
+
$table_occ = $occurrence->GetTable();
|
533 |
+
|
534 |
+
if ( $count_only ) {
|
535 |
+
$select_fields = array( 'COUNT(1) as count' );
|
536 |
+
$group_by = array( 'occ.id' );
|
537 |
+
} elseif ( is_null( $grouping ) ) {
|
538 |
+
$select_fields = array(
|
539 |
+
"occ.id",
|
540 |
+
"occ.alert_id",
|
541 |
+
"occ.site_id",
|
542 |
+
"occ.created_on",
|
543 |
+
"replace( replace( replace( occ.user_roles, '[', ''), ']', ''), '\\'', '') AS roles",
|
544 |
+
"occ.client_ip AS ip",
|
545 |
+
"occ.user_agent AS ua",
|
546 |
+
"COALESCE( occ.username, occ.user_id ) as user_id",
|
547 |
+
"occ.object",
|
548 |
+
"occ.event_type",
|
549 |
+
"occ.post_id",
|
550 |
+
"occ.post_type",
|
551 |
+
"occ.post_status",
|
552 |
+
);
|
553 |
+
} else {
|
554 |
+
$select_fields = array();
|
555 |
+
$group_by = array();
|
556 |
+
foreach ( $grouping as $grouping_item ) {
|
557 |
+
switch ($grouping_item) {
|
558 |
+
case 'site':
|
559 |
+
array_push( $select_fields, 'site_id' );
|
560 |
+
array_push( $group_by, 'site_id' );
|
561 |
+
break;
|
562 |
+
case 'users':
|
563 |
+
array_push( $select_fields, "COALESCE( occ.username, occ.user_id ) as user" );
|
564 |
+
array_push( $group_by, 'user' );
|
565 |
+
break;
|
566 |
+
case 'posts':
|
567 |
+
array_push( $select_fields, 'post_id' );
|
568 |
+
array_push( $group_by, 'post_id' );
|
569 |
+
break;
|
570 |
+
case 'day':
|
571 |
+
array_push( $select_fields, 'DATE_FORMAT( FROM_UNIXTIME( occ.created_on ), "%Y-%m-%d" ) AS period' );
|
572 |
+
array_push( $group_by, 'period' );
|
573 |
+
break;
|
574 |
+
case 'week':
|
575 |
+
array_push( $select_fields, 'DATE_FORMAT( FROM_UNIXTIME( occ.created_on ), "%Y-%u" ) AS period' );
|
576 |
+
array_push( $group_by, 'period' );
|
577 |
+
break;
|
578 |
+
case 'month':
|
579 |
+
array_push( $select_fields, 'DATE_FORMAT( FROM_UNIXTIME( occ.created_on ), "%Y-%m" ) AS period' );
|
580 |
+
array_push( $group_by, 'period' );
|
581 |
+
break;
|
582 |
+
}
|
583 |
+
}
|
584 |
|
585 |
+
array_push( $select_fields, 'COUNT(*) as count' );
|
586 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
587 |
|
588 |
+
$sql = 'SELECT ' . implode( ',', $select_fields ) . ' FROM ' . $table_occ . ' AS occ ';
|
589 |
+
|
590 |
+
$sql .= $this->build_where_statement( $report_args );
|
591 |
+
if ( ! empty( $next_date ) ) {
|
592 |
+
$sql .= ' AND occ.created_on < ' . $next_date;
|
|
|
|
|
|
|
|
|
|
|
593 |
}
|
594 |
+
|
595 |
+
if ( isset( $group_by ) && ! empty( $group_by ) ) {
|
596 |
+
$sql .= " GROUP BY " . implode( ',', $group_by );
|
597 |
+
$orderby_parts = array_map( function ( $item ) {
|
598 |
+
return 'period' === $item ? $item . ' DESC ' : $item . ' ASC ';
|
599 |
+
}, $group_by );
|
600 |
+
|
601 |
+
$sql .= " ORDER BY " . implode( ',', $orderby_parts );
|
602 |
+
} else {
|
603 |
+
$sql .= " ORDER BY created_on DESC ";
|
604 |
+
}
|
605 |
+
|
606 |
+
if ( ! empty( $limit ) ) {
|
607 |
+
$sql .= " LIMIT {$limit}";
|
608 |
+
}
|
609 |
+
|
610 |
+
return $sql;
|
611 |
}
|
612 |
|
613 |
/**
|
614 |
+
* Generates SQL where statement based on given report args.
|
615 |
*
|
616 |
* @param WSAL_ReportArgs $report_args Report arguments.
|
|
|
|
|
617 |
*
|
618 |
+
* @return string
|
619 |
*/
|
620 |
+
private function build_where_statement( $report_args ) {
|
621 |
+
$_site_id = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
622 |
$sites_negate_expression = '';
|
623 |
if ( $report_args->site__in ) {
|
624 |
$_site_id = $this->formatArrayForQuery( $report_args->site__in );
|
625 |
+
} elseif ( $report_args->site__not_in ) {
|
626 |
$_site_id = $this->formatArrayForQuery( $report_args->site__not_in );
|
627 |
$sites_negate_expression = 'NOT';
|
628 |
}
|
629 |
|
630 |
+
$_user_id = null;
|
631 |
$users_negate_expression = '';
|
|
|
632 |
if ( $report_args->user__in ) {
|
633 |
$_user_id = $this->formatArrayForQuery( $report_args->user__in );
|
634 |
+
} elseif ( $report_args->user__not_in ) {
|
635 |
$_user_id = $this->formatArrayForQuery( $report_args->user__not_in );
|
636 |
$users_negate_expression = 'NOT';
|
|
|
637 |
}
|
638 |
|
639 |
$user_names = $this->GetUserNames( $_user_id );
|
640 |
|
641 |
+
$_role_name = null;
|
642 |
$roles_negate_expression = '';
|
643 |
if ( $report_args->role__in ) {
|
644 |
$_role_name = $this->formatArrayForQueryRegex( $report_args->role__in );
|
645 |
+
} elseif ( $report_args->role__not_in ) {
|
646 |
$_role_name = $this->formatArrayForQueryRegex( $report_args->role__not_in );
|
647 |
$roles_negate_expression = 'NOT';
|
648 |
}
|
649 |
|
650 |
+
$_alert_code = null;
|
651 |
+
$alert_code_negate_expression = '';
|
652 |
if ( $report_args->code__in ) {
|
653 |
$_alert_code = $this->formatArrayForQuery( $report_args->code__in );
|
654 |
+
} elseif ( $report_args->code__not_in ) {
|
655 |
+
$_alert_code = $this->formatArrayForQuery( $report_args->code__not_in );
|
656 |
+
$alert_code_negate_expression = 'NOT';
|
657 |
}
|
658 |
|
659 |
+
$_post_ids = null;
|
660 |
+
$post_ids_negate_expression = '';
|
661 |
+
if ( $report_args->post__in ) {
|
662 |
+
$_post_ids = $this->formatArrayForQueryRegex( $report_args->post__in );
|
663 |
+
} elseif ( $report_args->post__not_in ) {
|
664 |
+
$_post_ids = $this->formatArrayForQueryRegex( $report_args->post__not_in );
|
665 |
+
$post_ids_negate_expression = 'NOT';
|
666 |
+
}
|
667 |
+
|
668 |
+
$_post_types = null;
|
669 |
+
$post_types_negate_expression = '';
|
670 |
if ( $report_args->post_type__in ) {
|
671 |
$_post_types = $this->formatArrayForQueryRegex( $report_args->post_type__in );
|
672 |
+
} elseif ( $report_args->post_type__not_in ) {
|
673 |
+
$_post_types = $this->formatArrayForQueryRegex( $report_args->post_type__not_in );
|
674 |
+
$post_types_negate_expression = 'NOT';
|
675 |
}
|
676 |
|
677 |
+
$_post_statuses = null;
|
678 |
+
$post_statuses_negate_expression = '';
|
679 |
if ( $report_args->post_status__in ) {
|
680 |
$_post_statuses = $this->formatArrayForQueryRegex( $report_args->post_status__in );
|
681 |
+
} else if ( $report_args->post_status__not_in ) {
|
682 |
+
$_post_statuses = $this->formatArrayForQueryRegex( $report_args->post_status__not_in );
|
683 |
+
$post_statuses_negate_expression = 'NOT';
|
684 |
}
|
685 |
|
686 |
+
$_ip_addresses = null;
|
687 |
+
$ip_addresses_negate_expression = '';
|
688 |
+
if ( $report_args->ip__in ) {
|
689 |
+
$_ip_addresses = $this->formatArrayForQuery( $report_args->ip__in );
|
690 |
+
} else if ( $report_args->ip__not_in ) {
|
691 |
+
$_ip_addresses = $this->formatArrayForQuery( $report_args->ip__not_in );
|
692 |
+
$ip_addresses_negate_expression = 'NOT';
|
693 |
+
}
|
694 |
+
|
695 |
+
$_objects = null;
|
696 |
$objects_negate_expression = '';
|
697 |
if ( $report_args->object__in ) {
|
698 |
$_objects = $this->formatArrayForQuery( $report_args->object__in );
|
699 |
+
} elseif ( $report_args->object__not_in ) {
|
700 |
$_objects = $this->formatArrayForQuery( $report_args->object__not_in );
|
701 |
$objects_negate_expression = 'NOT';
|
702 |
}
|
703 |
|
704 |
+
$_event_types = null;
|
705 |
$event_types_negate_expression = '';
|
706 |
if ( $report_args->type__in ) {
|
707 |
$_event_types = $this->formatArrayForQuery( $report_args->type__in );
|
708 |
+
} elseif ( $report_args->type__not_in ) {
|
709 |
+
$_event_types = $this->formatArrayForQuery( $report_args->type__not_in );
|
710 |
$event_types_negate_expression = 'NOT';
|
711 |
}
|
712 |
|
713 |
+
$_start_timestamp = null;
|
714 |
if ( $report_args->start_date ) {
|
715 |
$start_datetime = DateTime::createFromFormat( 'Y-m-d H:i:s', $report_args->start_date . ' 00:00:00' );
|
716 |
$_start_timestamp = $start_datetime->format( 'U' );
|
717 |
}
|
718 |
|
719 |
+
$_end_timestamp = null;
|
720 |
if ( $report_args->end_date ) {
|
721 |
$end_datetime = DateTime::createFromFormat( 'Y-m-d H:i:s', $report_args->end_date . ' 23:59:59' );
|
722 |
$_end_timestamp = $end_datetime->format( 'U' );
|
723 |
}
|
724 |
|
725 |
+
$users_condition_parts = array();
|
726 |
+
if ( ! is_null( $_user_id ) ) {
|
727 |
+
array_push( $users_condition_parts, " {$users_negate_expression} find_in_set( occ.user_id, $_user_id ) > 0 " );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
728 |
}
|
729 |
|
730 |
+
if ( ! is_null( $user_names ) ) {
|
731 |
+
array_push( $users_condition_parts, " {$users_negate_expression} replace( occ.username, '\"', '' ) IN ( $user_names ) " );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
732 |
}
|
733 |
+
|
734 |
+
$where_statement = " WHERE 1 = 1 ";
|
735 |
+
|
736 |
+
if ( ! empty( $users_condition_parts ) ) {
|
737 |
+
$where_statement .= ' AND ( ' . implode( 'OR', $users_condition_parts ) . ' ) ';
|
738 |
}
|
739 |
|
740 |
+
if ( ! is_null( $_site_id ) ) {
|
741 |
+
$where_statement .= " AND {$sites_negate_expression} find_in_set( occ.site_id, {$_site_id} ) > 0 ";
|
742 |
+
}
|
743 |
+
|
744 |
+
if ( ! is_null( $_role_name ) ) {
|
745 |
+
$where_statement .= " AND user_roles {$roles_negate_expression} REGEXP {$_role_name} ";
|
746 |
+
}
|
747 |
+
|
748 |
+
if ( ! is_null( $_ip_addresses ) ) {
|
749 |
+
$where_statement .= " AND {$ip_addresses_negate_expression} find_in_set( occ.client_ip, {$_ip_addresses} ) > 0 ";
|
750 |
+
}
|
751 |
+
|
752 |
+
if ( ! is_null( $_objects ) ) {
|
753 |
+
$where_statement .= " AND {$objects_negate_expression} find_in_set( occ.object, {$_objects} ) > 0 ";
|
754 |
+
}
|
755 |
+
|
756 |
+
if ( ! is_null( $_event_types ) ) {
|
757 |
+
$where_statement .= " AND {$event_types_negate_expression} find_in_set( occ.event_type, {$_event_types} ) > 0 ";
|
758 |
+
}
|
759 |
+
|
760 |
+
if ( ! is_null( $_alert_code ) ) {
|
761 |
+
$where_statement .= " AND {$alert_code_negate_expression} find_in_set( occ.alert_id, {$_alert_code} ) > 0 ";
|
762 |
+
}
|
763 |
+
|
764 |
+
if ( ! is_null( $_post_ids ) ) {
|
765 |
+
$where_statement .= " AND {$post_ids_negate_expression} find_in_set( occ.post_id, {$_post_ids} ) > 0 ";
|
766 |
+
}
|
767 |
+
|
768 |
+
if ( ! is_null( $_post_statuses ) ) {
|
769 |
+
$where_statement .= " AND {$post_statuses_negate_expression} find_in_set( occ.post_status, {$_post_statuses} ) > 0 ";
|
770 |
+
}
|
771 |
+
|
772 |
+
if ( ! is_null( $_post_types ) ) {
|
773 |
+
$where_statement .= " AND {$post_types_negate_expression} find_in_set( occ.post_type, {$_post_types} ) > 0 ";
|
774 |
+
}
|
775 |
+
|
776 |
+
if ( ! is_null( $_start_timestamp ) ) {
|
777 |
+
$where_statement .= " AND occ.created_on >= {$_start_timestamp} ";
|
778 |
+
}
|
779 |
+
|
780 |
+
if ( ! is_null( $_end_timestamp ) ) {
|
781 |
+
$where_statement .= " AND occ.created_on <= {$_end_timestamp} ";
|
782 |
+
}
|
783 |
+
|
784 |
+
return $where_statement;
|
785 |
}
|
786 |
|
787 |
/**
|
788 |
+
* @param array $data
|
|
|
789 |
*
|
790 |
+
* @return string
|
791 |
+
* @since 4.3.2
|
792 |
*/
|
793 |
+
protected function formatArrayForQuery( $data ) {
|
794 |
+
return "'" . implode( ',', $data ) . "'";
|
795 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
796 |
|
797 |
+
/**
|
798 |
+
* Get Users user_login.
|
799 |
+
*
|
800 |
+
* @param int $_user_id - User ID.
|
801 |
+
*
|
802 |
+
* @return string comma separated users login
|
803 |
+
*/
|
804 |
+
private function GetUserNames( $_user_id ) {
|
805 |
+
global $wpdb;
|
806 |
|
807 |
+
$user_names = null;
|
808 |
+
if ( ! empty( $_user_id ) && 'null' != $_user_id && ! is_null( $_user_id ) ) {
|
809 |
+
$sql = 'SELECT user_login FROM ' . $wpdb->users . ' WHERE find_in_set(ID, @userId) > 0';
|
810 |
+
$wpdb->query( "SET @userId = $_user_id" );
|
811 |
+
$result = $wpdb->get_results( $sql, ARRAY_A );
|
812 |
+
$users_array = array();
|
813 |
+
foreach ( $result as $item ) {
|
814 |
+
$users_array[] = '"' . $item['user_login'] . '"';
|
815 |
+
}
|
816 |
+
$user_names = implode( ', ', $users_array );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
817 |
}
|
818 |
|
819 |
+
return $user_names;
|
820 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
821 |
|
822 |
+
/**
|
823 |
+
* @param array $data
|
824 |
+
*
|
825 |
+
* @return string
|
826 |
+
* @since 4.3.2
|
827 |
+
*/
|
828 |
+
protected function formatArrayForQueryRegex( $data ) {
|
829 |
+
$result = array();
|
830 |
+
foreach ( $data as $item ) {
|
831 |
+
array_push( $result, esc_sql( preg_quote( $item ) ) );
|
832 |
+
}
|
833 |
+
|
834 |
+
return "'" . implode( '|', $result ) . "'";
|
835 |
}
|
836 |
|
837 |
/**
|
838 |
* Function used in WSAL reporting extension.
|
839 |
+
* Check if criteria are matching in the DB.
|
840 |
*
|
841 |
+
* @param WSAL_ReportArgs $report_args - Query conditions.
|
|
|
842 |
*
|
843 |
+
* @return int count of distinct values
|
844 |
*/
|
845 |
+
public function CheckMatchReportCriteria( $report_args ) {
|
846 |
+
$query = $this->build_reporting_query( $report_args, true );
|
847 |
|
848 |
+
return (int) $this->connection->get_var( $query );
|
849 |
+
}
|
850 |
+
|
851 |
+
/**
|
852 |
+
* Retrieves report data for IP address based reports. Function is used in WSAL reporting extension.
|
853 |
+
*
|
854 |
+
* @param WSAL_ReportArgs $report_args Report arguments.
|
855 |
+
* @param int $limit (Optional) Limit.
|
856 |
+
* @param int $statistics_report_type Statistics report type.
|
857 |
+
* @param string $grouping_period Period to use for data grouping.
|
858 |
+
*
|
859 |
+
* @return array Raw report results as objects. Content depends on the report type.
|
860 |
+
*/
|
861 |
+
public function get_ip_address_report_data( $report_args, $limit = 0, $statistics_report_type = null, $grouping_period = null ) {
|
862 |
global $wpdb;
|
863 |
$_wpdb = $this->connection;
|
|
|
864 |
|
865 |
// Tables.
|
866 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
867 |
+
$table_occ = $occurrence->GetTable();
|
868 |
+
|
|
|
869 |
// Get temp table `wsal_tmp_users`.
|
870 |
+
$tmp_users = new WSAL_Adapters_MySQL_TmpUser( $_wpdb );
|
871 |
// If the table exist.
|
872 |
if ( $tmp_users->IsInstalled() ) {
|
873 |
+
$table_users = $tmp_users->GetTable();
|
874 |
$this->TempUsers( $table_users );
|
875 |
} else {
|
876 |
$table_users = $wpdb->users;
|
877 |
}
|
878 |
|
879 |
+
// Figure out the grouping statement and the columns' selection.
|
880 |
+
$grouping = self::get_grouping( $statistics_report_type, $grouping_period );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
881 |
|
882 |
+
// Figure out the selected columns and group by statement.
|
883 |
+
$group_by_columns = array(
|
884 |
+
'site_id',
|
885 |
+
);
|
|
|
|
|
|
|
|
|
886 |
|
887 |
+
if ( in_array( 'users', $grouping, true ) ) {
|
888 |
+
array_push( $group_by_columns, 'username' );
|
|
|
889 |
}
|
890 |
|
891 |
+
if ( in_array( 'ips', $grouping, true ) ) {
|
892 |
+
array_push( $group_by_columns, 'client_ip' );
|
|
|
|
|
|
|
|
|
|
|
893 |
}
|
894 |
|
895 |
+
$select_fields = $group_by_columns;
|
896 |
+
foreach ( $grouping as $grouping_item ) {
|
897 |
+
switch ( $grouping_item ) {
|
898 |
+
case 'day':
|
899 |
+
array_unshift( $select_fields, 'DATE_FORMAT( FROM_UNIXTIME( created_on ), "%Y-%m-%d" ) AS period' );
|
900 |
+
array_unshift( $group_by_columns, 'period' );
|
901 |
+
break;
|
902 |
+
case 'week':
|
903 |
+
array_unshift( $select_fields, 'DATE_FORMAT( FROM_UNIXTIME( created_on ), "%Y-%u" ) AS period' );
|
904 |
+
array_unshift( $group_by_columns, 'period' );
|
905 |
+
break;
|
906 |
+
case 'month':
|
907 |
+
array_unshift( $select_fields, 'DATE_FORMAT( FROM_UNIXTIME( created_on ), "%Y-%m" ) AS period' );
|
908 |
+
array_unshift( $group_by_columns, 'period' );
|
909 |
+
break;
|
910 |
+
}
|
911 |
}
|
912 |
|
913 |
+
$where_statement = $this->build_where_statement( $report_args );
|
914 |
|
915 |
+
$sql = "
|
916 |
+
SELECT " . implode( ',', $select_fields ) . " FROM (
|
917 |
+
SELECT occ.created_on, occ.site_id, occ.username, occ.client_ip
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
918 |
FROM $table_occ AS occ
|
919 |
+
{$where_statement}
|
920 |
+
HAVING username IS NOT NULL AND username NOT IN ( 'Unregistered user', 'Plugins', 'Plugin')
|
921 |
+
UNION ALL
|
922 |
+
SELECT occ.created_on, occ.site_id, u.user_login as username, occ.client_ip
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
923 |
FROM $table_occ AS occ
|
924 |
+
JOIN $table_users AS u ON u.ID = occ.user_id
|
925 |
+
{$where_statement}
|
926 |
+
HAVING username IS NOT NULL AND username NOT IN ( 'Unregistered user', 'Plugins', 'Plugin')
|
927 |
+
) ip_logins
|
928 |
+
GROUP BY " . implode( ',', $group_by_columns );
|
929 |
+
|
930 |
+
$orderby_parts = array_map( function ( $item ) {
|
931 |
+
return 'period' === $item ? $item . ' DESC ' : $item . ' ASC ';
|
932 |
+
}, $group_by_columns );
|
933 |
+
|
934 |
+
$sql .= " ORDER BY " . implode( ',', $orderby_parts );
|
935 |
+
|
936 |
+
if ( ! empty( $limit ) ) {
|
937 |
+
$sql .= " LIMIT {$limit}";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
938 |
}
|
939 |
|
940 |
+
$results = $_wpdb->get_results( $sql, ARRAY_A );
|
941 |
+
if ( is_array( $results ) && ! empty( $results ) ) {
|
942 |
+
return $results;
|
943 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
944 |
|
945 |
+
return array();
|
946 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
947 |
|
948 |
+
/**
|
949 |
+
* @inheritDoc
|
950 |
+
*/
|
951 |
+
public function IsInstalled() {
|
952 |
+
$_wpdb = $this->connection;
|
953 |
+
$sql = "SHOW TABLES LIKE '" . $this->GetTable() . "'";
|
954 |
+
|
955 |
+
// Table transient.
|
956 |
+
$wsal_table_transient = 'wsal_' . strtolower( $this->GetTable() ) . '_status';
|
957 |
+
$wsal_db_table_status = get_transient( $wsal_table_transient );
|
958 |
+
|
959 |
+
// If transient does not exist, then run SQL query.
|
960 |
+
if ( ! $wsal_db_table_status ) {
|
961 |
+
$wsal_db_table_status = strtolower( $_wpdb->get_var( $sql ) ) == strtolower( $this->GetTable() );
|
962 |
+
set_transient( $wsal_table_transient, $wsal_db_table_status, DAY_IN_SECONDS );
|
963 |
}
|
964 |
|
965 |
+
return $wsal_db_table_status;
|
966 |
}
|
967 |
|
968 |
/**
|
992 |
/**
|
993 |
* Updates records in DB matching a query.
|
994 |
*
|
995 |
+
* @param string $table Table name
|
996 |
+
* @param array $data Data to update (in column => value pairs).
|
997 |
+
* Both $data columns and $data values should be "raw" (neither should be SQL
|
998 |
+
* escaped). Sending a null value will cause the column to be set to NULL - the
|
999 |
+
* corresponding format is ignored in this case.
|
1000 |
+
* @param array $where A named array of WHERE clauses (in column => value pairs).
|
1001 |
* Multiple clauses will be joined with ANDs.
|
1002 |
* Both $where columns and $where values should be "raw".
|
1003 |
+
* Sending a null value will create an IS NULL comparison - the corresponding
|
1004 |
+
* format will be ignored in this case.
|
1005 |
+
*
|
1006 |
* @return int|false The number of rows updated, or false on error.
|
1007 |
* @since 4.1.3
|
1008 |
*/
|
1009 |
public function UpdateQuery( $table, $data, $where ) {
|
1010 |
return $this->connection->update( $table, $data, $where );
|
1011 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1012 |
}
|
classes/Adapters/MySQL/MetaAdapter.php
CHANGED
@@ -72,12 +72,15 @@ class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implemen
|
|
72 |
public $value = array(); // Force mixed type.
|
73 |
|
74 |
/**
|
75 |
-
*
|
76 |
*
|
77 |
* @return WSAL_Models_Meta
|
78 |
*/
|
79 |
public function GetModel() {
|
80 |
-
|
|
|
|
|
|
|
81 |
}
|
82 |
|
83 |
/**
|
@@ -90,6 +93,9 @@ class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implemen
|
|
90 |
. ' KEY occurrence_name (occurrence_id,name)';
|
91 |
}
|
92 |
|
|
|
|
|
|
|
93 |
public function DeleteByOccurrenceIds( $occurrence_ids ) {
|
94 |
if ( ! empty( $occurrence_ids ) ) {
|
95 |
$sql = 'DELETE FROM ' . $this->GetTable() . ' WHERE occurrence_id IN (' . implode( ',', $occurrence_ids ) . ')';
|
@@ -98,27 +104,19 @@ class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implemen
|
|
98 |
}
|
99 |
}
|
100 |
|
101 |
-
public function LoadByNameAndOccurrenceId( $meta_name, $occurrence_id ) {
|
102 |
-
return $this->Load( 'occurrence_id = %d AND name = %s', array( $occurrence_id, $meta_name ) );
|
103 |
-
}
|
104 |
-
|
105 |
/**
|
106 |
-
*
|
107 |
-
*
|
108 |
-
* @param int $limit - (Optional) Limit.
|
109 |
-
* @return array - Distinct values of IPs.
|
110 |
*/
|
111 |
-
public function
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
$
|
116 |
-
|
117 |
-
|
118 |
-
foreach ( $ips as $key => $ip ) {
|
119 |
-
$ips[ $key ] = str_replace( '"', '', $ip );
|
120 |
}
|
121 |
-
|
|
|
122 |
}
|
123 |
|
124 |
/**
|
72 |
public $value = array(); // Force mixed type.
|
73 |
|
74 |
/**
|
75 |
+
* @inheritDoc
|
76 |
*
|
77 |
* @return WSAL_Models_Meta
|
78 |
*/
|
79 |
public function GetModel() {
|
80 |
+
$result = new WSAL_Models_Meta();
|
81 |
+
$result->setAdapter( $this );
|
82 |
+
|
83 |
+
return $result;
|
84 |
}
|
85 |
|
86 |
/**
|
93 |
. ' KEY occurrence_name (occurrence_id,name)';
|
94 |
}
|
95 |
|
96 |
+
/**
|
97 |
+
* @inheritDoc
|
98 |
+
*/
|
99 |
public function DeleteByOccurrenceIds( $occurrence_ids ) {
|
100 |
if ( ! empty( $occurrence_ids ) ) {
|
101 |
$sql = 'DELETE FROM ' . $this->GetTable() . ' WHERE occurrence_id IN (' . implode( ',', $occurrence_ids ) . ')';
|
104 |
}
|
105 |
}
|
106 |
|
|
|
|
|
|
|
|
|
107 |
/**
|
108 |
+
* @inheritDoc
|
|
|
|
|
|
|
109 |
*/
|
110 |
+
public function LoadByNameAndOccurrenceId( $meta_name, $occurrence_id ) {
|
111 |
+
// make sure to grab the migrated meta fields from the occurrence table
|
112 |
+
if ( in_array( $meta_name, array_keys( WSAL_Models_Occurrence::$migrated_meta ) ) ) {
|
113 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->get_connection() );
|
114 |
+
$column_name = WSAL_Models_Occurrence::$migrated_meta[ $meta_name ];
|
115 |
+
|
116 |
+
return $occurrence->$column_name;
|
|
|
|
|
117 |
}
|
118 |
+
|
119 |
+
return $this->Load( 'occurrence_id = %d AND name = %s', array( $occurrence_id, $meta_name ) );
|
120 |
}
|
121 |
|
122 |
/**
|
classes/Adapters/MySQL/OccurrenceAdapter.php
CHANGED
@@ -22,9 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
22 |
class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_OccurrenceInterface {
|
23 |
|
24 |
/**
|
25 |
-
*
|
26 |
-
*
|
27 |
-
* @var string
|
28 |
*/
|
29 |
protected $_table = 'wsal_occurrences';
|
30 |
|
@@ -35,13 +33,6 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
35 |
*/
|
36 |
protected $_idkey = 'id';
|
37 |
|
38 |
-
/**
|
39 |
-
* Meta data.
|
40 |
-
*
|
41 |
-
* @var WSAL_Models_Meta
|
42 |
-
*/
|
43 |
-
protected $_meta;
|
44 |
-
|
45 |
/**
|
46 |
* Occurrence id.
|
47 |
*
|
@@ -71,92 +62,141 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
71 |
public $created_on = 0.0;
|
72 |
|
73 |
/**
|
74 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
*
|
76 |
-
* @var
|
77 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
*/
|
79 |
-
public $
|
80 |
|
81 |
/**
|
82 |
-
*
|
83 |
*
|
84 |
-
* @var
|
85 |
-
* @
|
86 |
*/
|
87 |
-
public $
|
88 |
|
89 |
/**
|
90 |
-
*
|
91 |
*
|
92 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
*/
|
94 |
protected function GetTableOptions() {
|
95 |
return parent::GetTableOptions() . ',' . PHP_EOL
|
96 |
-
|
97 |
}
|
98 |
|
99 |
/**
|
100 |
-
*
|
101 |
*
|
102 |
* @return WSAL_Models_Occurrence
|
103 |
*/
|
104 |
public function GetModel() {
|
105 |
-
|
106 |
-
|
107 |
|
108 |
-
|
109 |
-
* Returns metadata related to this event.
|
110 |
-
*
|
111 |
-
* @param object $occurence - Occurrence model instance.
|
112 |
-
* @see WSAL_Adapters_MySQL_ActiveRecord::Load()
|
113 |
-
* @return WSAL_Models_Meta
|
114 |
-
*/
|
115 |
-
public function GetMeta( $occurence ) {
|
116 |
-
if ( ! isset( $this->_meta ) ) {
|
117 |
-
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
118 |
-
$this->_meta = $meta->Load( 'occurrence_id = %d', array( $occurence->id ) );
|
119 |
-
}
|
120 |
-
return $this->_meta;
|
121 |
}
|
122 |
|
123 |
/**
|
124 |
-
*
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
public function GetMultiMeta( $occurence ) {
|
131 |
-
if ( ! isset( $this->_meta ) ) {
|
132 |
-
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
133 |
-
$this->_meta = $meta->LoadArray( 'occurrence_id = %d', array( $occurence->id ) );
|
134 |
-
}
|
135 |
-
return $this->_meta;
|
136 |
}
|
137 |
|
138 |
/**
|
139 |
-
*
|
140 |
-
*
|
141 |
-
* @param object $occurence - Occurrence model instance.
|
142 |
-
* @param string $name - Meta name.
|
143 |
-
* @see WSAL_Adapters_MySQL_ActiveRecord::Load()
|
144 |
-
* @return WSAL_Models_Meta The meta item, be sure to checked if it was loaded successfully.
|
145 |
*/
|
146 |
-
public function GetNamedMeta( $
|
147 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
148 |
|
149 |
-
return $meta->LoadByNameAndOccurrenceId( $name, $
|
150 |
}
|
151 |
|
152 |
/**
|
153 |
-
*
|
154 |
-
* Useful when you have a mix of items that could provide
|
155 |
-
* a particular detail.
|
156 |
-
*
|
157 |
-
* @param object $occurrence - Occurrence model instance.
|
158 |
-
* @param array $names - List of meta names.
|
159 |
-
* @return WSAL_Models_Meta The first meta item that exists.
|
160 |
*/
|
161 |
public function GetFirstNamedMeta( $occurrence, $names ) {
|
162 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
@@ -164,123 +204,59 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
164 |
$query = 'occurrence_id = %d AND ' . $query . ' ORDER BY name DESC LIMIT 1';
|
165 |
array_unshift( $names, $occurrence->id ); // Prepend args with occurrence id.
|
166 |
|
167 |
-
$
|
168 |
-
return $meta->getModel()->LoadData( $this->_meta );
|
169 |
-
|
170 |
-
// TODO: Do we want to reintroduce is loaded check/logic?
|
171 |
-
// return $meta->IsLoaded() ? $meta : null;
|
172 |
}
|
173 |
|
174 |
/**
|
175 |
-
*
|
176 |
-
*
|
177 |
-
* @param array $args - User arguments.
|
178 |
-
* @return WSAL_Models_Occurrence[]
|
179 |
*/
|
180 |
public function CheckKnownUsers( $args = array() ) {
|
181 |
-
$tt2 = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
182 |
return $this->LoadMultiQuery(
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
and usernameMeta.value = %s
|
190 |
-
WHERE occurrence.alert_id = %d AND occurrence.site_id = %d
|
191 |
-
AND (created_on BETWEEN %d AND %d)
|
192 |
-
GROUP BY occurrence.id',
|
193 |
$args
|
194 |
);
|
195 |
}
|
196 |
|
197 |
/**
|
198 |
-
*
|
199 |
-
*
|
200 |
-
* @param array $args - User arguments.
|
201 |
-
* @return WSAL_Models_Occurrence[]
|
202 |
*/
|
203 |
-
public function
|
204 |
-
$tt2 = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
205 |
return $this->LoadMultiQuery(
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
AND (created_on BETWEEN %d AND %d)
|
211 |
-
GROUP BY occurrence.id',
|
212 |
$args
|
213 |
);
|
214 |
}
|
215 |
|
216 |
/**
|
217 |
-
*
|
218 |
-
*
|
219 |
-
* @param array $args - User arguments.
|
220 |
-
* @return WSAL_Models_Occurrence[]
|
221 |
*/
|
222 |
public function check_alert_1003( $args = array() ) {
|
223 |
return $this->LoadMultiQuery(
|
224 |
-
'SELECT
|
225 |
-
WHERE (
|
226 |
-
AND (
|
227 |
-
AND (
|
228 |
-
GROUP BY occurrence.id',
|
229 |
$args
|
230 |
);
|
231 |
}
|
232 |
|
233 |
/**
|
234 |
-
*
|
235 |
-
*
|
236 |
-
* @param string $query - Query.
|
237 |
-
*
|
238 |
-
* @return string[]
|
239 |
-
*/
|
240 |
-
protected function prepareOccurrenceQuery( $query ) {
|
241 |
-
$search_query_parameters = array();
|
242 |
-
$search_conditions = array();
|
243 |
-
$conditions = $query->getConditions();
|
244 |
-
|
245 |
-
// BUG: not all conditions are occurence related. maybe it's just a field site_id. need seperate arrays.
|
246 |
-
if ( ! empty( $conditions ) ) {
|
247 |
-
$tmp = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
248 |
-
$s_where_clause = '';
|
249 |
-
foreach ( $conditions as $field => $value ) {
|
250 |
-
if ( ! empty( $s_where_clause ) ) {
|
251 |
-
$s_where_clause .= ' AND ';
|
252 |
-
}
|
253 |
-
$s_where_clause .= 'name = %s AND value = %s';
|
254 |
-
$search_query_parameters[] = $field;
|
255 |
-
$search_query_parameters[] = $value;
|
256 |
-
}
|
257 |
-
|
258 |
-
$search_conditions[] = 'id IN (
|
259 |
-
SELECT DISTINCT occurrence_id
|
260 |
-
FROM ' . $tmp->GetTable() . '
|
261 |
-
WHERE ' . $s_where_clause . '
|
262 |
-
)';
|
263 |
-
}
|
264 |
-
|
265 |
-
// Do something with search query parameters and search conditions - give them to the query adapter?
|
266 |
-
return $search_conditions;
|
267 |
-
}
|
268 |
-
|
269 |
-
/**
|
270 |
-
* Gets occurrence by Post_id.
|
271 |
-
*
|
272 |
-
* @param int $post_id - Post ID.
|
273 |
-
* @return WSAL_Models_Occurrence[]
|
274 |
*/
|
275 |
public function GetByPostID( $post_id ) {
|
276 |
-
$tt2 = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
277 |
return $this->LoadMultiQuery(
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
and postMeta.value = %d
|
282 |
-
GROUP BY occurrence.id
|
283 |
-
ORDER BY created_on DESC',
|
284 |
array( $post_id )
|
285 |
);
|
286 |
}
|
@@ -289,6 +265,7 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
289 |
* Create relevant indexes on the occurrence table.
|
290 |
*/
|
291 |
public function create_indexes() {
|
|
|
292 |
$db_connection = $this->get_connection();
|
293 |
// check if an index exists.
|
294 |
if ( $db_connection->query( 'SELECT COUNT(1) IndexIsThere FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() AND table_name="' . $this->GetTable() . '" AND index_name="created_on"' ) ) {
|
@@ -300,4 +277,100 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
300 |
$db_connection->query( 'CREATE INDEX created_on ON ' . $this->GetTable() . ' (created_on)' );
|
301 |
}
|
302 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
}
|
22 |
class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_OccurrenceInterface {
|
23 |
|
24 |
/**
|
25 |
+
* @inheritDoc
|
|
|
|
|
26 |
*/
|
27 |
protected $_table = 'wsal_occurrences';
|
28 |
|
33 |
*/
|
34 |
protected $_idkey = 'id';
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
/**
|
37 |
* Occurrence id.
|
38 |
*
|
62 |
public $created_on = 0.0;
|
63 |
|
64 |
/**
|
65 |
+
* Client IP address.
|
66 |
+
*
|
67 |
+
* @var string
|
68 |
+
* @since 4.4.0
|
69 |
+
*/
|
70 |
+
public $client_ip = '';
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Severity.
|
74 |
+
*
|
75 |
+
* @var int
|
76 |
+
* @since 4.4.0
|
77 |
+
*/
|
78 |
+
public $severity = '';
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Event object.
|
82 |
+
*
|
83 |
+
* @var string
|
84 |
+
* @since 4.4.0
|
85 |
+
*/
|
86 |
+
public $object = '';
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Event type.
|
90 |
+
*
|
91 |
+
* @var string
|
92 |
+
* @since 4.4.0
|
93 |
+
*/
|
94 |
+
public $event_type = '';
|
95 |
+
|
96 |
+
/**
|
97 |
+
* User agent string.
|
98 |
+
*
|
99 |
+
* @var string
|
100 |
+
* @since 4.4.0
|
101 |
+
*/
|
102 |
+
public $user_agent = '';
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Comma separated user roles of the user belonging to the event.
|
106 |
*
|
107 |
+
* @var string
|
108 |
+
* @since 4.4.0
|
109 |
+
*/
|
110 |
+
public $user_roles = '';
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Username of the user belonging to the event.
|
114 |
+
*
|
115 |
+
* @var string
|
116 |
+
* @since 4.4.0
|
117 |
+
*/
|
118 |
+
public $username = null;
|
119 |
+
|
120 |
+
/**
|
121 |
+
* User ID of the user belonging to the event.
|
122 |
+
*
|
123 |
+
* @var int
|
124 |
+
* @since 4.4.0
|
125 |
*/
|
126 |
+
public $user_id = null;
|
127 |
|
128 |
/**
|
129 |
+
* Session ID.
|
130 |
*
|
131 |
+
* @var string
|
132 |
+
* @since 4.4.0
|
133 |
*/
|
134 |
+
public $session_id = '';
|
135 |
|
136 |
/**
|
137 |
+
* Post status.
|
138 |
*
|
139 |
+
* @var string
|
140 |
+
* @since 4.4.0
|
141 |
+
*/
|
142 |
+
public $post_status = '';
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Post status.
|
146 |
+
*
|
147 |
+
* @var string
|
148 |
+
* @since 4.4.0
|
149 |
+
*/
|
150 |
+
public $post_type = '';
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Post ID.
|
154 |
+
*
|
155 |
+
* @var int
|
156 |
+
* @since 4.4.0
|
157 |
+
*/
|
158 |
+
public $post_id = 0;
|
159 |
+
|
160 |
+
/**
|
161 |
+
* @inheritDoc
|
162 |
*/
|
163 |
protected function GetTableOptions() {
|
164 |
return parent::GetTableOptions() . ',' . PHP_EOL
|
165 |
+
. ' KEY site_alert_created (site_id,alert_id,created_on)';
|
166 |
}
|
167 |
|
168 |
/**
|
169 |
+
* @inheritDoc
|
170 |
*
|
171 |
* @return WSAL_Models_Occurrence
|
172 |
*/
|
173 |
public function GetModel() {
|
174 |
+
$result = new WSAL_Models_Occurrence();
|
175 |
+
$result->setAdapter( $this );
|
176 |
|
177 |
+
return $result;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
}
|
179 |
|
180 |
/**
|
181 |
+
* @inheritDoc
|
182 |
+
*/
|
183 |
+
public function GetMultiMeta( $occurrence ) {
|
184 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
185 |
+
|
186 |
+
return $meta->LoadArray( 'occurrence_id = %d', array( $occurrence->id ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
}
|
188 |
|
189 |
/**
|
190 |
+
* @inheritDoc
|
|
|
|
|
|
|
|
|
|
|
191 |
*/
|
192 |
+
public function GetNamedMeta( $occurrence, $name ) {
|
193 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
194 |
|
195 |
+
return $meta->LoadByNameAndOccurrenceId( $name, $occurrence->id );
|
196 |
}
|
197 |
|
198 |
/**
|
199 |
+
* @inheritDoc
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
*/
|
201 |
public function GetFirstNamedMeta( $occurrence, $names ) {
|
202 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
204 |
$query = 'occurrence_id = %d AND ' . $query . ' ORDER BY name DESC LIMIT 1';
|
205 |
array_unshift( $names, $occurrence->id ); // Prepend args with occurrence id.
|
206 |
|
207 |
+
return $meta->getModel()->LoadData( $meta->Load( $query, $names ) );
|
|
|
|
|
|
|
|
|
208 |
}
|
209 |
|
210 |
/**
|
211 |
+
* @inheritDoc
|
|
|
|
|
|
|
212 |
*/
|
213 |
public function CheckKnownUsers( $args = array() ) {
|
|
|
214 |
return $this->LoadMultiQuery(
|
215 |
+
"SELECT * FROM `{$this->GetTable()}` "
|
216 |
+
. " WHERE client_ip = %s "
|
217 |
+
. " AND username = %s "
|
218 |
+
. " AND alert_id = %d "
|
219 |
+
. " AND site_id = %d "
|
220 |
+
. " AND ( created_on BETWEEN %d AND %d );",
|
|
|
|
|
|
|
|
|
221 |
$args
|
222 |
);
|
223 |
}
|
224 |
|
225 |
/**
|
226 |
+
* @inheritDoc
|
|
|
|
|
|
|
227 |
*/
|
228 |
+
public function CheckUnknownUsers( $args = array() ) {
|
|
|
229 |
return $this->LoadMultiQuery(
|
230 |
+
"SELECT * FROM `{$this->GetTable()}` "
|
231 |
+
. " WHERE client_ip = %s "
|
232 |
+
. " AND alert_id = %d "
|
233 |
+
. " AND site_id = %d "
|
234 |
+
. " AND ( created_on BETWEEN %d AND %d );",
|
|
|
235 |
$args
|
236 |
);
|
237 |
}
|
238 |
|
239 |
/**
|
240 |
+
* @inheritDoc
|
|
|
|
|
|
|
241 |
*/
|
242 |
public function check_alert_1003( $args = array() ) {
|
243 |
return $this->LoadMultiQuery(
|
244 |
+
'SELECT * FROM `' . $this->GetTable() . '`
|
245 |
+
WHERE (alert_id = %d)
|
246 |
+
AND (site_id = %d)
|
247 |
+
AND (created_on BETWEEN %d AND %d);',
|
|
|
248 |
$args
|
249 |
);
|
250 |
}
|
251 |
|
252 |
/**
|
253 |
+
* @inheritDoc
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
*/
|
255 |
public function GetByPostID( $post_id ) {
|
|
|
256 |
return $this->LoadMultiQuery(
|
257 |
+
"SELECT occurrence.* FROM `{$this->GetTable()}` "
|
258 |
+
. " WHERE post_id = %d "
|
259 |
+
. " ORDER BY created_on DESC;",
|
|
|
|
|
|
|
260 |
array( $post_id )
|
261 |
);
|
262 |
}
|
265 |
* Create relevant indexes on the occurrence table.
|
266 |
*/
|
267 |
public function create_indexes() {
|
268 |
+
$index_exists = false;
|
269 |
$db_connection = $this->get_connection();
|
270 |
// check if an index exists.
|
271 |
if ( $db_connection->query( 'SELECT COUNT(1) IndexIsThere FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() AND table_name="' . $this->GetTable() . '" AND index_name="created_on"' ) ) {
|
277 |
$db_connection->query( 'CREATE INDEX created_on ON ' . $this->GetTable() . ' (created_on)' );
|
278 |
}
|
279 |
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* @inheritDoc
|
283 |
+
*/
|
284 |
+
public function get_all_with_meta_to_migrate( $limit ) {
|
285 |
+
$meta_adapter = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
286 |
+
|
287 |
+
$meta_keys = array_map( function ( $value ) {
|
288 |
+
return '"' . $value . '"';
|
289 |
+
}, array_keys( WSAL_Models_Occurrence::$migrated_meta ) );
|
290 |
+
|
291 |
+
return $this->LoadMultiQuery(
|
292 |
+
"SELECT o.* FROM `{$this->GetTable()}` o "
|
293 |
+
. " INNER JOIN `{$meta_adapter->GetTable()}` m "
|
294 |
+
. " ON m.occurrence_id = o.id "
|
295 |
+
. " WHERE m.name IN (" . implode( ',', $meta_keys ) . ") "
|
296 |
+
. " GROUP BY o.id "
|
297 |
+
. " ORDER BY created_on DESC "
|
298 |
+
. " LIMIT 0, %d;",
|
299 |
+
array( $limit )
|
300 |
+
);
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Get distinct values of IPs.
|
305 |
+
*
|
306 |
+
* @param int $limit - (Optional) Limit.
|
307 |
+
*
|
308 |
+
* @return array - Distinct values of IPs.
|
309 |
+
*/
|
310 |
+
public function GetMatchingIPs( $limit = null ) {
|
311 |
+
$_wpdb = $this->connection;
|
312 |
+
$sql = "SELECT DISTINCT client_ip FROM {$this->GetTable()}";
|
313 |
+
if ( ! is_null( $limit ) ) {
|
314 |
+
$sql .= ' LIMIT ' . $limit;
|
315 |
+
}
|
316 |
+
$ips = $_wpdb->get_col( $sql );
|
317 |
+
$result = array();
|
318 |
+
foreach ( $ips as $ip ) {
|
319 |
+
if ( 0 === strlen( trim( $ip ) ) ) {
|
320 |
+
continue;
|
321 |
+
}
|
322 |
+
array_push( $result, $ip );
|
323 |
+
}
|
324 |
+
|
325 |
+
return array_unique( $result );
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* @inheritDoc
|
330 |
+
*
|
331 |
+
* username and user_id columns have to be added manually because function get_object_vars doesn't return
|
332 |
+
* uninitialised properties. These two cannot have the default value set because some database queries rely on
|
333 |
+
* having null values in the database.
|
334 |
+
*
|
335 |
+
* @since 4.4.0
|
336 |
+
*/
|
337 |
+
public function GetColumns() {
|
338 |
+
if ( ! empty( $this->_column_cache ) ) {
|
339 |
+
return $this->_column_cache;
|
340 |
+
}
|
341 |
+
|
342 |
+
$result = parent::GetColumns();
|
343 |
+
foreach ( [ 'username', 'user_id' ] as $extra_column ) {
|
344 |
+
if ( ! in_array( $extra_column, $result ) ) {
|
345 |
+
array_push( $result, $extra_column );
|
346 |
+
}
|
347 |
+
}
|
348 |
+
|
349 |
+
$this->_column_cache = $result;
|
350 |
+
|
351 |
+
return $result;
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* @inheritDoc
|
356 |
+
*
|
357 |
+
* @param WSAL_Models_Occurrence $copy
|
358 |
+
*
|
359 |
+
* @since 4.4.0
|
360 |
+
*/
|
361 |
+
protected function _GetSqlColumnDefinition( $copy, $key ) {
|
362 |
+
if ( 'username' === $key ) {
|
363 |
+
return " username VARCHAR(255) NULL, ";
|
364 |
+
}
|
365 |
+
|
366 |
+
if ( 'user_id' === $key ) {
|
367 |
+
return " user_id BIGINT NULL, ";
|
368 |
+
}
|
369 |
+
|
370 |
+
if ( is_string( $copy->$key ) ) {
|
371 |
+
return $key . ' VARCHAR(255) NOT NULL,' . PHP_EOL;
|
372 |
+
}
|
373 |
+
|
374 |
+
return parent::_GetSqlColumnDefinition( $copy, $key );
|
375 |
+
}
|
376 |
}
|
classes/Adapters/MySQL/QueryAdapter.php
CHANGED
@@ -19,6 +19,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
19 |
* the arguments.
|
20 |
*
|
21 |
* @package wsal
|
|
|
22 |
*/
|
23 |
class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
24 |
|
@@ -32,10 +33,10 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
32 |
/**
|
33 |
* Method: Constructor.
|
34 |
*
|
35 |
-
* @param array $
|
36 |
*/
|
37 |
-
public function __construct( $
|
38 |
-
$this->connection = $
|
39 |
}
|
40 |
|
41 |
/**
|
@@ -132,16 +133,16 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
132 |
}
|
133 |
|
134 |
/**
|
135 |
-
*
|
136 |
-
*
|
137 |
-
* @param object $query - Query object.
|
138 |
-
*
|
139 |
-
* @return WSAL_Models_ActiveRecord[]
|
140 |
*/
|
141 |
public function Execute( $query ) {
|
142 |
$args = array();
|
143 |
$sql = $this->GetSql( $query, $args );
|
144 |
|
|
|
|
|
|
|
|
|
145 |
$occurrence_adapter = $query->getConnector()->getAdapter( 'Occurrence' );
|
146 |
|
147 |
if ( in_array( $occurrence_adapter->GetTable(), $query->getFrom() ) ) {
|
@@ -152,10 +153,7 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
152 |
}
|
153 |
|
154 |
/**
|
155 |
-
*
|
156 |
-
*
|
157 |
-
* @param object $query - Query object.
|
158 |
-
* @return integer counting records.
|
159 |
*/
|
160 |
public function Count( $query ) {
|
161 |
// Back up columns, use COUNT as default column and generate sql.
|
@@ -164,7 +162,7 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
164 |
$query->addColumn( 'COUNT(*)' );
|
165 |
|
166 |
$args = array();
|
167 |
-
$sql
|
168 |
|
169 |
// Restore columns.
|
170 |
$query->setColumns( $cols );
|
@@ -185,9 +183,7 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
185 |
}
|
186 |
|
187 |
/**
|
188 |
-
*
|
189 |
-
*
|
190 |
-
* @param object $query query object.
|
191 |
*/
|
192 |
public function Delete( $query ) {
|
193 |
$result = $this->GetSqlDelete( $query );
|
@@ -296,6 +292,9 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
296 |
return $search_conditions;
|
297 |
}
|
298 |
|
|
|
|
|
|
|
299 |
public function IsConnected() {
|
300 |
return ( $this->connection && $this->connection->has_connected );
|
301 |
}
|
19 |
* the arguments.
|
20 |
*
|
21 |
* @package wsal
|
22 |
+
* @subpackage adapters
|
23 |
*/
|
24 |
class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
25 |
|
33 |
/**
|
34 |
* Method: Constructor.
|
35 |
*
|
36 |
+
* @param array $connection - Connection array.
|
37 |
*/
|
38 |
+
public function __construct( $connection ) {
|
39 |
+
$this->connection = $connection;
|
40 |
}
|
41 |
|
42 |
/**
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
+
* @inheritDoc
|
|
|
|
|
|
|
|
|
137 |
*/
|
138 |
public function Execute( $query ) {
|
139 |
$args = array();
|
140 |
$sql = $this->GetSql( $query, $args );
|
141 |
|
142 |
+
$args = array_filter( $args, function ( $item ) {
|
143 |
+
return ( '' !== $item );
|
144 |
+
} );
|
145 |
+
|
146 |
$occurrence_adapter = $query->getConnector()->getAdapter( 'Occurrence' );
|
147 |
|
148 |
if ( in_array( $occurrence_adapter->GetTable(), $query->getFrom() ) ) {
|
153 |
}
|
154 |
|
155 |
/**
|
156 |
+
* @inheritDoc
|
|
|
|
|
|
|
157 |
*/
|
158 |
public function Count( $query ) {
|
159 |
// Back up columns, use COUNT as default column and generate sql.
|
162 |
$query->addColumn( 'COUNT(*)' );
|
163 |
|
164 |
$args = array();
|
165 |
+
$sql = $this->GetSql( $query, $args );
|
166 |
|
167 |
// Restore columns.
|
168 |
$query->setColumns( $cols );
|
183 |
}
|
184 |
|
185 |
/**
|
186 |
+
* @inheritDoc
|
|
|
|
|
187 |
*/
|
188 |
public function Delete( $query ) {
|
189 |
$result = $this->GetSqlDelete( $query );
|
292 |
return $search_conditions;
|
293 |
}
|
294 |
|
295 |
+
/**
|
296 |
+
* @inheritDoc
|
297 |
+
*/
|
298 |
public function IsConnected() {
|
299 |
return ( $this->connection && $this->connection->has_connected );
|
300 |
}
|
classes/Adapters/MySQL/TmpUserAdapter.php
CHANGED
@@ -32,7 +32,7 @@ class WSAL_Adapters_MySQL_TmpUser extends WSAL_Adapters_MySQL_ActiveRecord {
|
|
32 |
protected $_table = 'wsal_tmp_users';
|
33 |
|
34 |
/**
|
35 |
-
*
|
36 |
*
|
37 |
* @return WSAL_Models_TmpUser
|
38 |
*/
|
@@ -41,22 +41,17 @@ class WSAL_Adapters_MySQL_TmpUser extends WSAL_Adapters_MySQL_ActiveRecord {
|
|
41 |
}
|
42 |
|
43 |
/**
|
44 |
-
*
|
45 |
-
*
|
46 |
-
* @param mixed $prefix - Prefix.
|
47 |
-
* @return string
|
48 |
*/
|
49 |
protected function _GetInstallQuery( $prefix = false ) {
|
50 |
$_wpdb = $this->connection;
|
51 |
$table_name = ( $prefix ) ? $this->GetWPTable() : $this->GetTable();
|
52 |
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
53 |
-
$sql
|
54 |
-
$sql
|
55 |
-
$sql
|
56 |
-
$sql
|
57 |
-
|
58 |
-
$sql .= ' DEFAULT CHARACTER SET ' . $_wpdb->charset;
|
59 |
-
}
|
60 |
return $sql;
|
61 |
}
|
62 |
}
|
32 |
protected $_table = 'wsal_tmp_users';
|
33 |
|
34 |
/**
|
35 |
+
* @inheritDoc
|
36 |
*
|
37 |
* @return WSAL_Models_TmpUser
|
38 |
*/
|
41 |
}
|
42 |
|
43 |
/**
|
44 |
+
* @inheritDoc
|
|
|
|
|
|
|
45 |
*/
|
46 |
protected function _GetInstallQuery( $prefix = false ) {
|
47 |
$_wpdb = $this->connection;
|
48 |
$table_name = ( $prefix ) ? $this->GetWPTable() : $this->GetTable();
|
49 |
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
50 |
+
$sql .= 'ID BIGINT NOT NULL,' . PHP_EOL;
|
51 |
+
$sql .= 'user_login VARCHAR(60) NOT NULL,' . PHP_EOL;
|
52 |
+
$sql .= 'INDEX (ID)' . PHP_EOL;
|
53 |
+
$sql .= ') ' . $_wpdb->get_charset_collate();
|
54 |
+
|
|
|
|
|
55 |
return $sql;
|
56 |
}
|
57 |
}
|
classes/Adapters/OccurrenceInterface.php
CHANGED
@@ -20,41 +20,82 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
20 |
interface WSAL_Adapters_OccurrenceInterface {
|
21 |
|
22 |
/**
|
23 |
-
*
|
24 |
*
|
25 |
-
* @param
|
|
|
|
|
|
|
26 |
*/
|
27 |
-
public function
|
28 |
|
29 |
/**
|
30 |
* Loads a meta item given its name.
|
31 |
*
|
32 |
-
* @param object $
|
33 |
* @param string $name - Meta name.
|
|
|
|
|
|
|
34 |
*/
|
35 |
-
public function GetNamedMeta( $
|
36 |
|
37 |
/**
|
38 |
* Returns the first meta value from a given set of names.
|
39 |
* Useful when you have a mix of items that could provide
|
40 |
* a particular detail.
|
41 |
*
|
42 |
-
* @param object $occurrence -
|
43 |
-
* @param array
|
|
|
|
|
44 |
*/
|
45 |
public function GetFirstNamedMeta( $occurrence, $names );
|
46 |
|
47 |
/**
|
48 |
* Gets occurrences of the same type by IP and Username within specified time frame.
|
49 |
*
|
50 |
-
* @param array $args -
|
|
|
|
|
51 |
*/
|
52 |
public function CheckKnownUsers( $args = array() );
|
53 |
|
54 |
/**
|
55 |
* Gets occurrences of the same type by IP within specified time frame.
|
56 |
*
|
57 |
-
* @param array $args -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
*/
|
59 |
-
public function
|
60 |
}
|
20 |
interface WSAL_Adapters_OccurrenceInterface {
|
21 |
|
22 |
/**
|
23 |
+
* Returns all metadata related to this event.
|
24 |
*
|
25 |
+
* @param WSAL_Models_Occurrence $occurrence - Occurrence model instance.
|
26 |
+
*
|
27 |
+
* @return WSAL_Models_Meta[]
|
28 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::LoadArray()
|
29 |
*/
|
30 |
+
public function GetMultiMeta( $occurrence );
|
31 |
|
32 |
/**
|
33 |
* Loads a meta item given its name.
|
34 |
*
|
35 |
+
* @param object $occurrence - Occurrence model instance.
|
36 |
* @param string $name - Meta name.
|
37 |
+
*
|
38 |
+
* @return WSAL_Models_Meta The meta item, be sure to check if it was loaded successfully.
|
39 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::Load()
|
40 |
*/
|
41 |
+
public function GetNamedMeta( $occurrence, $name );
|
42 |
|
43 |
/**
|
44 |
* Returns the first meta value from a given set of names.
|
45 |
* Useful when you have a mix of items that could provide
|
46 |
* a particular detail.
|
47 |
*
|
48 |
+
* @param object $occurrence - Occurrence model instance.
|
49 |
+
* @param array $names - List of meta names.
|
50 |
+
*
|
51 |
+
* @return WSAL_Models_Meta The first meta item that exists.
|
52 |
*/
|
53 |
public function GetFirstNamedMeta( $occurrence, $names );
|
54 |
|
55 |
/**
|
56 |
* Gets occurrences of the same type by IP and Username within specified time frame.
|
57 |
*
|
58 |
+
* @param array $args - User arguments.
|
59 |
+
*
|
60 |
+
* @return WSAL_Models_Occurrence[]
|
61 |
*/
|
62 |
public function CheckKnownUsers( $args = array() );
|
63 |
|
64 |
/**
|
65 |
* Gets occurrences of the same type by IP within specified time frame.
|
66 |
*
|
67 |
+
* @param array $args - User arguments.
|
68 |
+
*
|
69 |
+
* @return WSAL_Models_Occurrence[]
|
70 |
+
*/
|
71 |
+
public function CheckUnknownUsers( $args = array() );
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Gets occurrence by Post_id.
|
75 |
+
*
|
76 |
+
* @param int $post_id - Post ID.
|
77 |
+
*
|
78 |
+
* @return WSAL_Models_Occurrence[]
|
79 |
+
*/
|
80 |
+
public function GetByPostID( $post_id );
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Gets occurrences of the alert 1003.
|
84 |
+
*
|
85 |
+
* @param array $args - User arguments.
|
86 |
+
*
|
87 |
+
* @return WSAL_Models_Occurrence[]
|
88 |
+
*/
|
89 |
+
public function check_alert_1003( $args = array() );
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Retrieves occurrences that have metadata that needs to be migrated to the occurrences table. This relates to the
|
93 |
+
* database schema change done in version 4.4.0.
|
94 |
+
*
|
95 |
+
* @param int $limit
|
96 |
+
*
|
97 |
+
* @return WSAL_Models_Occurrence[]
|
98 |
+
* @since 4.4.0
|
99 |
*/
|
100 |
+
public function get_all_with_meta_to_migrate( $limit );
|
101 |
}
|
classes/Adapters/QueryInterface.php
CHANGED
@@ -42,6 +42,7 @@ interface WSAL_Adapters_QueryInterface {
|
|
42 |
|
43 |
/**
|
44 |
* Checks if the adapter is successfully connected.
|
|
|
45 |
* @return bool True if the adapter is connected. False otherwise.
|
46 |
* @since 4.3.2
|
47 |
*/
|
42 |
|
43 |
/**
|
44 |
* Checks if the adapter is successfully connected.
|
45 |
+
*
|
46 |
* @return bool True if the adapter is connected. False otherwise.
|
47 |
* @since 4.3.2
|
48 |
*/
|
classes/Alert.php
CHANGED
@@ -182,7 +182,7 @@ final class WSAL_Alert {
|
|
182 |
|
183 |
$end_of_line = $formatter->get_end_of_line();
|
184 |
|
185 |
-
//
|
186 |
if ( $formatter->supports_metadata() ) {
|
187 |
$metadata_result = $this->get_formatted_metadata( $formatter, $meta_data, $occurrence_id );
|
188 |
if ( ! empty( $metadata_result ) ) {
|
@@ -210,13 +210,13 @@ final class WSAL_Alert {
|
|
210 |
* Retrieves a value for a particular meta variable expression.
|
211 |
*
|
212 |
* @param string $expr Expression, eg: User->Name looks for a Name property for meta named User.
|
213 |
-
* @param array
|
214 |
*
|
215 |
* @return mixed The value nearest to the expression.
|
216 |
*/
|
217 |
protected function GetMetaExprValue( $expr, $meta_data = array() ) {
|
218 |
$expr = preg_replace( '/%/', '', $expr );
|
219 |
-
if ( 'IPAddress'
|
220 |
if ( array_key_exists( 'IPAddress', $meta_data ) ) {
|
221 |
return implode( ', ', $meta_data['IPAddress'] );
|
222 |
}
|
@@ -232,16 +232,18 @@ final class WSAL_Alert {
|
|
232 |
if ( is_scalar( $meta ) || is_null( $meta ) ) {
|
233 |
return $meta; // This isn't 100% correct.
|
234 |
}
|
235 |
-
$meta = is_array( $meta ) ? $meta[ $part ] : ( isset( $meta->$part ) ? $meta->$part : 'NULL' );
|
236 |
}
|
237 |
|
238 |
return is_scalar( $meta ) ? (string) $meta : var_export( $meta, true );
|
239 |
}
|
240 |
|
241 |
/**
|
242 |
-
*
|
243 |
-
*
|
244 |
-
* @param
|
|
|
|
|
245 |
*
|
246 |
* @return string
|
247 |
* @throws Freemius_Exception
|
@@ -252,7 +254,7 @@ final class WSAL_Alert {
|
|
252 |
$metadata_as_array = $this->get_metadata_as_array( $formatter, $meta_data, $occurrence_id );
|
253 |
if ( ! empty( $metadata_as_array ) ) {
|
254 |
|
255 |
-
$meta_result_parts =
|
256 |
foreach ( $metadata_as_array as $meta_label => $meta_expression ) {
|
257 |
if ( ! empty( $meta_expression ) ) {
|
258 |
array_push( $meta_result_parts, $meta_label . ': ' . $formatter->wrap_in_hightlight_markup( $meta_expression ) );
|
@@ -267,25 +269,28 @@ final class WSAL_Alert {
|
|
267 |
}
|
268 |
|
269 |
/**
|
270 |
-
*
|
271 |
-
*
|
272 |
-
* @param
|
|
|
|
|
273 |
*
|
274 |
* @return array
|
|
|
275 |
* @since 4.2.1
|
276 |
*/
|
277 |
public function get_metadata_as_array( $formatter, $meta_data, $occurrence_id ) {
|
278 |
-
$result =
|
279 |
if ( ! empty( $this->metadata ) ) {
|
280 |
foreach ( $this->metadata as $meta_label => $meta_token ) {
|
281 |
if ( strlen( $meta_token ) === 0 ) {
|
282 |
continue;
|
283 |
}
|
284 |
|
285 |
-
//
|
286 |
$meta_expression = $this->GetMetaExprValue( $meta_token, $meta_data );
|
287 |
|
288 |
-
//
|
289 |
$meta_expression = $formatter->format_meta_expression( $meta_token, $meta_expression, $occurrence_id );
|
290 |
|
291 |
if ( ! empty( $meta_expression ) ) {
|
182 |
|
183 |
$end_of_line = $formatter->get_end_of_line();
|
184 |
|
185 |
+
// Process metadata and links introduced as part of alert definition in version 4.2.1.
|
186 |
if ( $formatter->supports_metadata() ) {
|
187 |
$metadata_result = $this->get_formatted_metadata( $formatter, $meta_data, $occurrence_id );
|
188 |
if ( ! empty( $metadata_result ) ) {
|
210 |
* Retrieves a value for a particular meta variable expression.
|
211 |
*
|
212 |
* @param string $expr Expression, eg: User->Name looks for a Name property for meta named User.
|
213 |
+
* @param array $meta_data (Optional) Meta data relevant to expression.
|
214 |
*
|
215 |
* @return mixed The value nearest to the expression.
|
216 |
*/
|
217 |
protected function GetMetaExprValue( $expr, $meta_data = array() ) {
|
218 |
$expr = preg_replace( '/%/', '', $expr );
|
219 |
+
if ( 'IPAddress' === $expr ) {
|
220 |
if ( array_key_exists( 'IPAddress', $meta_data ) ) {
|
221 |
return implode( ', ', $meta_data['IPAddress'] );
|
222 |
}
|
232 |
if ( is_scalar( $meta ) || is_null( $meta ) ) {
|
233 |
return $meta; // This isn't 100% correct.
|
234 |
}
|
235 |
+
$meta = is_array( $meta ) && array_key_exists( $part, $meta ) ? $meta[ $part ] : ( isset( $meta->$part ) ? $meta->$part : 'NULL' );
|
236 |
}
|
237 |
|
238 |
return is_scalar( $meta ) ? (string) $meta : var_export( $meta, true );
|
239 |
}
|
240 |
|
241 |
/**
|
242 |
+
* Retrieves formatted meta data item (label and data).
|
243 |
+
*
|
244 |
+
* @param WSAL_AlertFormatter $formatter Alert formatter.
|
245 |
+
* @param array $meta_data Meta data.
|
246 |
+
* @param int $occurrence_id Occurrence ID.
|
247 |
*
|
248 |
* @return string
|
249 |
* @throws Freemius_Exception
|
254 |
$metadata_as_array = $this->get_metadata_as_array( $formatter, $meta_data, $occurrence_id );
|
255 |
if ( ! empty( $metadata_as_array ) ) {
|
256 |
|
257 |
+
$meta_result_parts = array();
|
258 |
foreach ( $metadata_as_array as $meta_label => $meta_expression ) {
|
259 |
if ( ! empty( $meta_expression ) ) {
|
260 |
array_push( $meta_result_parts, $meta_label . ': ' . $formatter->wrap_in_hightlight_markup( $meta_expression ) );
|
269 |
}
|
270 |
|
271 |
/**
|
272 |
+
* Retrieves metadata as an associative array.
|
273 |
+
*
|
274 |
+
* @param WSAL_AlertFormatter $formatter Alert formatter.
|
275 |
+
* @param array $meta_data Meta data.
|
276 |
+
* @param int $occurrence_id Occurrence ID.
|
277 |
*
|
278 |
* @return array
|
279 |
+
* @throws Freemius_Exception
|
280 |
* @since 4.2.1
|
281 |
*/
|
282 |
public function get_metadata_as_array( $formatter, $meta_data, $occurrence_id ) {
|
283 |
+
$result = array();
|
284 |
if ( ! empty( $this->metadata ) ) {
|
285 |
foreach ( $this->metadata as $meta_label => $meta_token ) {
|
286 |
if ( strlen( $meta_token ) === 0 ) {
|
287 |
continue;
|
288 |
}
|
289 |
|
290 |
+
// Pure alert meta lookup based on meta token.
|
291 |
$meta_expression = $this->GetMetaExprValue( $meta_token, $meta_data );
|
292 |
|
293 |
+
// Additional alert meta processing - handles derived or decorated alert data.
|
294 |
$meta_expression = $formatter->format_meta_expression( $meta_token, $meta_expression, $occurrence_id );
|
295 |
|
296 |
if ( ! empty( $meta_expression ) ) {
|
classes/AlertFormatter.php
CHANGED
@@ -72,6 +72,18 @@ final class WSAL_AlertFormatter {
|
|
72 |
|
73 |
return '';
|
74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
case in_array( $expression, array( '%MetaValue%', '%MetaValueOld%', '%MetaValueNew%' ) ):
|
76 |
// trim the meta value to the maximum length and append configured ellipses sequence
|
77 |
$result = mb_strlen( $value ) > $this->configuration->getMaxMetaValueLength() ? ( mb_substr( $value, 0, 50 ) . $this->configuration->getEllipsesSequence() ) : $value;
|
72 |
|
73 |
return '';
|
74 |
|
75 |
+
case in_array( $expression, array( '%path%', '%old_path%', '%FilePath%' ) ):
|
76 |
+
// concatenate directory and file paths
|
77 |
+
$max_length = 50;
|
78 |
+
if ( $this->configuration->isJsInLinksAllowed() && strlen( $value ) > $max_length ) {
|
79 |
+
$result = '<span>' . substr( $value, 0, $max_length ) . '</span>';
|
80 |
+
$result .= "<a href=\"#\" data-shortened-text='{$value}'>" . $this->configuration->getEllipsesSequence() . "</a>";
|
81 |
+
|
82 |
+
return $result;
|
83 |
+
}
|
84 |
+
|
85 |
+
return $value;
|
86 |
+
|
87 |
case in_array( $expression, array( '%MetaValue%', '%MetaValueOld%', '%MetaValueNew%' ) ):
|
88 |
// trim the meta value to the maximum length and append configured ellipses sequence
|
89 |
$result = mb_strlen( $value ) > $this->configuration->getMaxMetaValueLength() ? ( mb_substr( $value, 0, 50 ) . $this->configuration->getEllipsesSequence() ) : $value;
|
classes/AlertManager.php
CHANGED
@@ -83,15 +83,19 @@ final class WSAL_AlertManager {
|
|
83 |
public $ignored_cpts = array();
|
84 |
|
85 |
/**
|
|
|
|
|
86 |
* @var string Date format.
|
87 |
*/
|
88 |
private $date_format;
|
89 |
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
|
|
|
|
95 |
|
96 |
/**
|
97 |
* Create new AlertManager instance.
|
@@ -100,7 +104,7 @@ final class WSAL_AlertManager {
|
|
100 |
*/
|
101 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
102 |
$this->plugin = $plugin;
|
103 |
-
foreach (
|
104 |
$this->AddFromFile( $file );
|
105 |
}
|
106 |
|
@@ -233,7 +237,8 @@ final class WSAL_AlertManager {
|
|
233 |
|
234 |
// If user or user role is enable then go ahead.
|
235 |
if ( $this->CheckEnableUserRoles( $username, $roles ) ) {
|
236 |
-
|
|
|
237 |
if ( $delayed ) {
|
238 |
$this->TriggerIf( $type, $data, null );
|
239 |
} else {
|
@@ -330,15 +335,13 @@ final class WSAL_AlertManager {
|
|
330 |
/**
|
331 |
* Method: Commit an alert now.
|
332 |
*
|
333 |
-
* @param int
|
334 |
-
* @param array $data
|
335 |
-
* @param array $cond
|
336 |
-
* @param bool
|
337 |
*
|
338 |
* @return mixed
|
339 |
-
* @throws Exception - Error if alert is not registered.
|
340 |
* @internal
|
341 |
-
*
|
342 |
*/
|
343 |
protected function _CommitItem( $type, $data, $cond, $_retry = true ) {
|
344 |
// Double NOT operation here is intentional. Same as ! ( bool ) [ $value ]
|
@@ -356,7 +359,8 @@ final class WSAL_AlertManager {
|
|
356 |
} else {
|
357 |
// In general this shouldn't happen, but it could, so we handle it here.
|
358 |
/* translators: Event ID */
|
359 |
-
|
|
|
360 |
}
|
361 |
}
|
362 |
}
|
@@ -407,40 +411,41 @@ final class WSAL_AlertManager {
|
|
407 |
/**
|
408 |
* Register an alert type.
|
409 |
*
|
410 |
-
* @param string $category
|
411 |
* @param string $subcategory Subcategory name.
|
412 |
-
* @param array
|
413 |
-
*
|
414 |
-
* @throws Exception - Error if alert is already registered.
|
415 |
*/
|
416 |
public function Register( $category, $subcategory, $info ) {
|
417 |
|
418 |
-
//
|
419 |
-
$metadata =
|
420 |
-
$links =
|
421 |
$object = '';
|
422 |
$event_type = '';
|
423 |
|
424 |
$definition_items_count = count( $info );
|
425 |
-
if ( 8
|
426 |
-
//
|
427 |
list( $code, $severity, $desc, $message, $metadata, $links, $object, $event_type ) = $info;
|
428 |
-
}
|
429 |
-
//
|
430 |
list( $code, $severity, $desc, $message, $object, $event_type ) = $info;
|
431 |
} else {
|
432 |
-
//
|
433 |
list( $code, $severity, $desc, $message ) = $info;
|
434 |
}
|
435 |
|
436 |
if ( is_string( $links ) ) {
|
437 |
-
$links =
|
438 |
}
|
439 |
-
|
440 |
if ( isset( $this->_alerts[ $code ] ) ) {
|
441 |
add_action( 'admin_notices', array( $this, 'duplicate_event_notice' ) );
|
442 |
/* Translators: Event ID */
|
443 |
-
|
|
|
|
|
|
|
444 |
}
|
445 |
|
446 |
/**
|
@@ -453,7 +458,6 @@ final class WSAL_AlertManager {
|
|
453 |
* @param integer $code - Event ID.
|
454 |
*
|
455 |
* @since 4.3.2
|
456 |
-
*
|
457 |
*/
|
458 |
$metadata = apply_filters( 'wsal_event_metadata_definition', $metadata, $code );
|
459 |
|
@@ -465,8 +469,6 @@ final class WSAL_AlertManager {
|
|
465 |
*
|
466 |
* @param array $groups - An array with group name as the index and an array of group items as the value.
|
467 |
* Item values is an array of [type, code, description, message, object, event type] respectively.
|
468 |
-
*
|
469 |
-
* @throws Exception
|
470 |
*/
|
471 |
public function RegisterGroup( $groups ) {
|
472 |
foreach ( $groups as $name => $group ) {
|
@@ -856,71 +858,6 @@ final class WSAL_AlertManager {
|
|
856 |
return $is_disabled;
|
857 |
}
|
858 |
|
859 |
-
/**
|
860 |
-
* Return alerts for MainWP Extension.
|
861 |
-
*
|
862 |
-
* @param integer $limit - Number of alerts to retrieve.
|
863 |
-
* @param int|bool $offset - Events offset, otherwise false.
|
864 |
-
* @param stdClass|bool $query_args - Events query arguments, otherwise false.
|
865 |
-
*
|
866 |
-
* @return stdClass
|
867 |
-
* @throws Freemius_Exception
|
868 |
-
*/
|
869 |
-
public function get_mainwp_extension_events( $limit = 100, $offset = false, $query_args = false ) {
|
870 |
-
$mwp_events = new stdClass();
|
871 |
-
|
872 |
-
// Check if limit is not empty.
|
873 |
-
if ( empty( $limit ) ) {
|
874 |
-
return $mwp_events;
|
875 |
-
}
|
876 |
-
|
877 |
-
// Initiate query occurrence object.
|
878 |
-
$events_query = new WSAL_Models_OccurrenceQuery();
|
879 |
-
$events_query->addCondition( 'site_id = %s ', 1 ); // Set site id.
|
880 |
-
$events_query = $this->filter_query( $events_query, $query_args );
|
881 |
-
|
882 |
-
// Check query arguments.
|
883 |
-
if ( false !== $query_args ) {
|
884 |
-
if ( isset( $query_args['get_count'] ) && $query_args['get_count'] ) {
|
885 |
-
$mwp_events->total_items = $events_query->getAdapter()->Count( $events_query );
|
886 |
-
} else {
|
887 |
-
$mwp_events->total_items = false;
|
888 |
-
}
|
889 |
-
}
|
890 |
-
|
891 |
-
// Set order by.
|
892 |
-
$events_query->addOrderBy( 'created_on', true );
|
893 |
-
|
894 |
-
// Set the limit.
|
895 |
-
$events_query->setLimit( $limit );
|
896 |
-
|
897 |
-
// Set the offset.
|
898 |
-
if ( false !== $offset ) {
|
899 |
-
$events_query->setOffset( $offset );
|
900 |
-
}
|
901 |
-
|
902 |
-
// Execute the query.
|
903 |
-
/** @var \WSAL\MainWPExtension\Models\Occurrence[] $events */
|
904 |
-
$events = $events_query->getAdapter()->Execute( $events_query );
|
905 |
-
|
906 |
-
if ( ! empty( $events ) && is_array( $events ) ) {
|
907 |
-
foreach ( $events as $event ) {
|
908 |
-
// Get event meta.
|
909 |
-
$meta_data = $event->GetMetaArray();
|
910 |
-
$meta_data['UserData'] = $this->get_event_user_data( WSAL_Utilities_UsersUtils::GetUsername( $meta_data ) );
|
911 |
-
$mwp_events->events[ $event->id ] = new stdClass();
|
912 |
-
$mwp_events->events[ $event->id ]->id = $event->id;
|
913 |
-
$mwp_events->events[ $event->id ]->alert_id = $event->alert_id;
|
914 |
-
$mwp_events->events[ $event->id ]->created_on = $event->created_on;
|
915 |
-
$mwp_events->events[ $event->id ]->meta_data = $meta_data;
|
916 |
-
}
|
917 |
-
|
918 |
-
$mwp_events->users = $this->wp_users;
|
919 |
-
}
|
920 |
-
|
921 |
-
return $mwp_events;
|
922 |
-
}
|
923 |
-
|
924 |
/**
|
925 |
* Return user data array of the events.
|
926 |
*
|
@@ -1215,204 +1152,6 @@ final class WSAL_AlertManager {
|
|
1215 |
return get_event_type_data( $event_type );
|
1216 |
}
|
1217 |
|
1218 |
-
/**
|
1219 |
-
* Filter query for MWPAL.
|
1220 |
-
*
|
1221 |
-
* @param WSAL_Models_OccurrenceQuery $query - Events query.
|
1222 |
-
* @param array $query_args - Query args.
|
1223 |
-
*
|
1224 |
-
* @return WSAL_Models_OccurrenceQuery
|
1225 |
-
* @throws Freemius_Exception
|
1226 |
-
*/
|
1227 |
-
private function filter_query( $query, $query_args ) {
|
1228 |
-
if ( isset( $query_args['search_term'] ) && $query_args['search_term'] ) {
|
1229 |
-
$query->addSearchCondition( $query_args['search_term'] );
|
1230 |
-
}
|
1231 |
-
|
1232 |
-
if ( ! empty( $query_args['search_filters'] ) ) {
|
1233 |
-
// Get DB connection array.
|
1234 |
-
$connection = WpSecurityAuditLog::GetInstance()->getConnector()->getAdapter( 'Occurrence' )->get_connection();
|
1235 |
-
$connection->set_charset( $connection->dbh, 'utf8mb4', 'utf8mb4_general_ci' );
|
1236 |
-
|
1237 |
-
// Tables.
|
1238 |
-
$meta = new WSAL_Adapters_MySQL_Meta( $connection );
|
1239 |
-
$table_meta = $meta->GetTable(); // Metadata.
|
1240 |
-
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $connection );
|
1241 |
-
$table_occ = $occurrence->GetTable(); // Occurrences.
|
1242 |
-
|
1243 |
-
foreach ( $query_args['search_filters'] as $prefix => $value ) {
|
1244 |
-
if ( 'event' === $prefix ) {
|
1245 |
-
$query->addORCondition( array( 'alert_id = %s' => $value ) );
|
1246 |
-
} elseif ( in_array( $prefix, array( 'from', 'to', 'on' ), true ) ) {
|
1247 |
-
$date = DateTime::createFromFormat( $this->sanitized_date_format, $value[0] );
|
1248 |
-
$date->setTime( 0, 0 ); // Reset time to 00:00:00.
|
1249 |
-
$date_string = $date->format( 'U' );
|
1250 |
-
|
1251 |
-
if ( 'from' === $prefix ) {
|
1252 |
-
$query->addCondition( 'created_on >= %s', $date_string );
|
1253 |
-
} elseif ( 'to' === $prefix ) {
|
1254 |
-
$query->addCondition( 'created_on <= %s', strtotime( '+1 day -1 minute', $date_string ) );
|
1255 |
-
} elseif ( 'on' === $prefix ) {
|
1256 |
-
$query->addCondition( 'created_on >= %s', strtotime( '-1 day +1 day +1 second', $date_string ) );
|
1257 |
-
$query->addCondition( 'created_on <= %s', strtotime( '+1 day -1 second', $date_string ) );
|
1258 |
-
}
|
1259 |
-
} elseif ( in_array( $prefix, array( 'username', 'firstname', 'lastname' ), true ) ) {
|
1260 |
-
// User ids array.
|
1261 |
-
$user_ids = array();
|
1262 |
-
|
1263 |
-
if ( 'username' === $prefix ) {
|
1264 |
-
foreach ( $value as $username ) {
|
1265 |
-
$user = get_user_by( 'login', $username );
|
1266 |
-
|
1267 |
-
if ( ! $user ) {
|
1268 |
-
$user = get_user_by( 'slug', $username );
|
1269 |
-
}
|
1270 |
-
|
1271 |
-
if ( $user ) {
|
1272 |
-
$user_ids[] = $user->ID;
|
1273 |
-
}
|
1274 |
-
}
|
1275 |
-
} elseif ( 'firstname' === $prefix || 'lastname' === $prefix ) {
|
1276 |
-
$users = array();
|
1277 |
-
$meta_key = 'firstname' === $prefix ? 'first_name' : ( 'lastname' === $prefix ? 'last_name' : false );
|
1278 |
-
|
1279 |
-
foreach ( $value as $name ) {
|
1280 |
-
$users_array = get_users(
|
1281 |
-
array(
|
1282 |
-
'meta_key' => $meta_key,
|
1283 |
-
'meta_value' => $name,
|
1284 |
-
'fields' => array( 'ID', 'user_login' ),
|
1285 |
-
'meta_compare' => 'LIKE',
|
1286 |
-
)
|
1287 |
-
);
|
1288 |
-
|
1289 |
-
foreach ( $users_array as $user ) {
|
1290 |
-
$users[] = $user;
|
1291 |
-
}
|
1292 |
-
}
|
1293 |
-
|
1294 |
-
$usernames = array();
|
1295 |
-
|
1296 |
-
if ( ! empty( $users ) ) {
|
1297 |
-
foreach ( $users as $user ) {
|
1298 |
-
$usernames[] = $user->user_login;
|
1299 |
-
$user_ids[] = $user->ID;
|
1300 |
-
}
|
1301 |
-
}
|
1302 |
-
|
1303 |
-
$value = $usernames;
|
1304 |
-
}
|
1305 |
-
|
1306 |
-
$sql = "$table_occ.id IN ( SELECT occurrence_id FROM $table_meta as meta WHERE ";
|
1307 |
-
|
1308 |
-
if ( ! empty( $user_ids ) ) {
|
1309 |
-
$last_userid = end( $user_ids );
|
1310 |
-
$sql .= "( meta.name='CurrentUserID' AND ( ";
|
1311 |
-
|
1312 |
-
foreach ( $user_ids as $user_id ) {
|
1313 |
-
if ( $last_userid === $user_id ) {
|
1314 |
-
$sql .= "meta.value='$user_id'";
|
1315 |
-
} else {
|
1316 |
-
$sql .= "meta.value='$user_id' OR ";
|
1317 |
-
}
|
1318 |
-
}
|
1319 |
-
|
1320 |
-
$sql .= ' ) )';
|
1321 |
-
$sql .= ' OR ';
|
1322 |
-
}
|
1323 |
-
|
1324 |
-
if ( ! empty( $value ) ) {
|
1325 |
-
$last_username = end( $value );
|
1326 |
-
$sql .= "( meta.name='Username' AND ( ";
|
1327 |
-
|
1328 |
-
foreach ( $value as $username ) {
|
1329 |
-
if ( $last_username === $username ) {
|
1330 |
-
$sql .= "meta.value='%s'";
|
1331 |
-
} else {
|
1332 |
-
$sql .= "meta.value='$username' OR ";
|
1333 |
-
}
|
1334 |
-
}
|
1335 |
-
|
1336 |
-
$sql .= ' ) )';
|
1337 |
-
}
|
1338 |
-
|
1339 |
-
$sql .= ' )';
|
1340 |
-
$user_count = count( $value );
|
1341 |
-
|
1342 |
-
if ( $user_count ) {
|
1343 |
-
$query->addORCondition( array( $sql => $value[ $user_count - 1 ] ) );
|
1344 |
-
} else {
|
1345 |
-
$query->addORCondition( array( $sql => '' ) );
|
1346 |
-
}
|
1347 |
-
} elseif ( 'userrole' === $prefix ) {
|
1348 |
-
// User role search condition.
|
1349 |
-
$sql = "$table_occ.id IN ( SELECT occurrence_id FROM $table_meta as meta WHERE meta.name='CurrentUserRoles' AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP %s )";
|
1350 |
-
$value = implode( '|', $value );
|
1351 |
-
$query->addORCondition( array( $sql => $value ) );
|
1352 |
-
} elseif ( in_array( $prefix, array( 'posttype', 'poststatus', 'postid', 'postname' ), true ) ) {
|
1353 |
-
$post_meta = '';
|
1354 |
-
|
1355 |
-
if ( 'posttype' === $prefix ) {
|
1356 |
-
$post_meta = 'PostType';
|
1357 |
-
} elseif ( 'poststatus' === $prefix ) {
|
1358 |
-
$post_meta = 'PostStatus';
|
1359 |
-
} elseif ( 'postid' === $prefix ) {
|
1360 |
-
$post_meta = 'PostID';
|
1361 |
-
} elseif ( 'postname' === $prefix ) {
|
1362 |
-
$post_meta = 'PostTitle';
|
1363 |
-
}
|
1364 |
-
|
1365 |
-
// Post meta search condition.
|
1366 |
-
$sql = "$table_occ.id IN ( SELECT occurrence_id FROM $table_meta as meta WHERE meta.name='$post_meta' AND ( ";
|
1367 |
-
if ( 'postname' === $prefix ) {
|
1368 |
-
$value = array_map( array( $this, 'add_string_wildcards' ), $value );
|
1369 |
-
}
|
1370 |
-
|
1371 |
-
// Get the last value.
|
1372 |
-
$last_value = end( $value );
|
1373 |
-
|
1374 |
-
foreach ( $value as $post_meta ) {
|
1375 |
-
if ( $last_value === $post_meta ) {
|
1376 |
-
continue;
|
1377 |
-
}
|
1378 |
-
|
1379 |
-
if ( 'postname' === $prefix ) {
|
1380 |
-
$sql .= "( (meta.value LIKE '$post_meta') > 0 ) OR ";
|
1381 |
-
} else {
|
1382 |
-
$sql .= "meta.value='$post_meta' OR ";
|
1383 |
-
}
|
1384 |
-
}
|
1385 |
-
|
1386 |
-
// Add placeholder for the last value.
|
1387 |
-
if ( 'postname' === $prefix ) {
|
1388 |
-
$sql .= "( (meta.value LIKE '%s') > 0 ) ) )";
|
1389 |
-
} else {
|
1390 |
-
$sql .= "meta.value='%s' ) )";
|
1391 |
-
}
|
1392 |
-
|
1393 |
-
$query->addORCondition( array( $sql => $last_value ) );
|
1394 |
-
} elseif ( 'ip' === $prefix ) {
|
1395 |
-
// IP search condition.
|
1396 |
-
$sql = "$table_occ.id IN ( SELECT occurrence_id FROM $table_meta as meta WHERE meta.name='ClientIP' AND ( ";
|
1397 |
-
$count = count( $value );
|
1398 |
-
|
1399 |
-
foreach ( $value as $ip ) {
|
1400 |
-
if ( $value[ $count - 1 ] === $ip ) {
|
1401 |
-
$sql .= "meta.value='%s'";
|
1402 |
-
} else {
|
1403 |
-
$sql .= "meta.value='$ip' OR ";
|
1404 |
-
}
|
1405 |
-
}
|
1406 |
-
|
1407 |
-
$sql .= ' ) )';
|
1408 |
-
$query->addORCondition( array( $sql => $value[ $count - 1 ] ) );
|
1409 |
-
}
|
1410 |
-
}
|
1411 |
-
}
|
1412 |
-
|
1413 |
-
return $query;
|
1414 |
-
}
|
1415 |
-
|
1416 |
/**
|
1417 |
* Modify post name values to include MySQL wildcards.
|
1418 |
*
|
@@ -1454,130 +1193,6 @@ final class WSAL_AlertManager {
|
|
1454 |
return array_keys( $this->get_sub_categorized_events() );
|
1455 |
}
|
1456 |
|
1457 |
-
/**
|
1458 |
-
* Generate report matching the filter passed.
|
1459 |
-
*
|
1460 |
-
* @param array $filters - Filters.
|
1461 |
-
* @param mixed $report_type - Type of report.
|
1462 |
-
* @return stdClass
|
1463 |
-
*/
|
1464 |
-
public function get_mainwp_extension_report( array $filters, $report_type ) {
|
1465 |
-
// Check report type.
|
1466 |
-
if ( ! $report_type ) {
|
1467 |
-
$report = new stdClass();
|
1468 |
-
$report->data = array();
|
1469 |
-
|
1470 |
-
do {
|
1471 |
-
$response = $this->generate_report( $filters );
|
1472 |
-
|
1473 |
-
if ( isset( $response['data'] ) ) {
|
1474 |
-
$report->data = array_merge( $report->data, $response['data'] );
|
1475 |
-
}
|
1476 |
-
|
1477 |
-
// Set the filters next date.
|
1478 |
-
$filters['nextDate'] = ( isset( $response['lastDate'] ) && $response['lastDate'] ) ? $response['lastDate'] : 0;
|
1479 |
-
} while ( $filters['nextDate'] );
|
1480 |
-
} elseif ( 'statistics_unique_ips' === $report_type ) {
|
1481 |
-
$report = new stdClass();
|
1482 |
-
$report->data = $this->generate_statistics_unique_ips( $filters );
|
1483 |
-
}
|
1484 |
-
|
1485 |
-
return $report;
|
1486 |
-
}
|
1487 |
-
|
1488 |
-
/**
|
1489 |
-
* Generate report for MainWP extension.
|
1490 |
-
*
|
1491 |
-
* @param array $filters - Filters.
|
1492 |
-
* @return array
|
1493 |
-
*/
|
1494 |
-
private function generate_report( $filters ) {
|
1495 |
-
// check the report format
|
1496 |
-
$report_format = empty( $filters['report-format'] ) ? 'html' : 'csv';
|
1497 |
-
if ( ! in_array( $report_format, array( 'csv', 'html' ), true ) ) {
|
1498 |
-
return false;
|
1499 |
-
}
|
1500 |
-
|
1501 |
-
// some alert codes or alert groups are needed to run a report
|
1502 |
-
if ( empty( $filters['alert-codes']['groups'] ) && empty( $filters['alert-codes']['codes'] ) ) {
|
1503 |
-
return false;
|
1504 |
-
}
|
1505 |
-
|
1506 |
-
$args = WSAL_ReportArgs::build_from_alternative_filters( $filters, $this );
|
1507 |
-
|
1508 |
-
$next_date = empty( $filters['nextDate'] ) ? null : $filters['nextDate'];
|
1509 |
-
$limit = empty( $filters['limit'] ) ? 0 : $filters['limit'];
|
1510 |
-
|
1511 |
-
$last_date = null;
|
1512 |
-
|
1513 |
-
if ( isset( $filters['unique-ip'] ) && $filters['unique-ip'] ) {
|
1514 |
-
$results = $this->plugin->getConnector()->getAdapter( 'Occurrence' )->GetReportGrouped( $args );
|
1515 |
-
} else {
|
1516 |
-
$results = $this->plugin->getConnector()->getAdapter( 'Occurrence' )->GetReporting( $args, $next_date, $limit );
|
1517 |
-
}
|
1518 |
-
|
1519 |
-
if ( ! empty( $results['lastDate'] ) ) {
|
1520 |
-
$last_date = $results['lastDate'];
|
1521 |
-
unset( $results['lastDate'] );
|
1522 |
-
}
|
1523 |
-
|
1524 |
-
if ( empty( $results ) ) {
|
1525 |
-
return false;
|
1526 |
-
}
|
1527 |
-
|
1528 |
-
$data = array();
|
1529 |
-
$data_and_filters = array();
|
1530 |
-
|
1531 |
-
if ( ! empty( $filters['unique-ip'] ) ) {
|
1532 |
-
$data = array_values( $results );
|
1533 |
-
} else {
|
1534 |
-
// Get alert details.
|
1535 |
-
foreach ( $results as $entry ) {
|
1536 |
-
$ip = esc_html( $entry->ip );
|
1537 |
-
$ua = esc_html( $entry->ua );
|
1538 |
-
$roles = maybe_unserialize( $entry->roles );
|
1539 |
-
|
1540 |
-
if ( is_array( $roles ) ) {
|
1541 |
-
$roles = implode( ', ', $roles );
|
1542 |
-
} else {
|
1543 |
-
$roles = '';
|
1544 |
-
}
|
1545 |
-
|
1546 |
-
if ( 9999 === (int) $entry->alert_id ) {
|
1547 |
-
continue;
|
1548 |
-
}
|
1549 |
-
|
1550 |
-
$t = $this->get_alert_details( $entry->id, $entry->id, $entry->alert_id, $entry->site_id, $entry->created_on, $entry->user_id, $roles, $ip, $ua, 'report-' . $report_format);
|
1551 |
-
array_push( $data, $t );
|
1552 |
-
}
|
1553 |
-
}
|
1554 |
-
|
1555 |
-
if ( empty( $data ) ) {
|
1556 |
-
return false;
|
1557 |
-
}
|
1558 |
-
|
1559 |
-
$data_and_filters['data'] = $data;
|
1560 |
-
$data_and_filters['filters'] = $filters;
|
1561 |
-
$data_and_filters['lastDate'] = $last_date;
|
1562 |
-
|
1563 |
-
return $data_and_filters;
|
1564 |
-
}
|
1565 |
-
|
1566 |
-
/**
|
1567 |
-
* Create statistics unique IPs report.
|
1568 |
-
*
|
1569 |
-
* @param array $filters - Filters.
|
1570 |
-
*
|
1571 |
-
* @return array
|
1572 |
-
* @throws Freemius_Exception
|
1573 |
-
*/
|
1574 |
-
private function generate_statistics_unique_ips( $filters ) {
|
1575 |
-
$report_args = WSAL_ReportArgs::build_from_alternative_filters( $filters, $this );
|
1576 |
-
$results = $this->plugin->getConnector()->getAdapter( 'Occurrence' )->GetReportGrouped( $report_args );
|
1577 |
-
|
1578 |
-
return array_values( $results );
|
1579 |
-
}
|
1580 |
-
|
1581 |
/**
|
1582 |
* Get user ids for reports.
|
1583 |
*
|
@@ -1695,23 +1310,32 @@ final class WSAL_AlertManager {
|
|
1695 |
/**
|
1696 |
* Get alert details.
|
1697 |
*
|
1698 |
-
* @param
|
1699 |
-
* @param
|
1700 |
-
* @param int $site_id - Site ID.
|
1701 |
-
* @param string $created_on - Alert generation time.
|
1702 |
-
* @param int $user_id - User id.
|
1703 |
-
* @param string|array $roles - User roles.
|
1704 |
-
* @param string $ip - IP address of the user.
|
1705 |
-
* @param string $ua - User agent.
|
1706 |
*
|
1707 |
-
* @return array|false details
|
1708 |
* @throws Exception
|
1709 |
*/
|
1710 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1711 |
// Must be a new instance every time, otherwise the alert message is not retrieved properly.
|
1712 |
$occurrence = new WSAL_Models_Occurrence();
|
1713 |
|
1714 |
-
$user_id = ( ! is_numeric( $user_id ) && null !== $user_id ) ?
|
1715 |
|
1716 |
// Get alert details.
|
1717 |
$code = $this->GetAlert( $alert_id );
|
@@ -1723,33 +1347,22 @@ final class WSAL_AlertManager {
|
|
1723 |
);
|
1724 |
$const = $this->plugin->constants->GetConstantBy( 'value', $code, $const );
|
1725 |
|
1726 |
-
|
1727 |
-
if ( $this->plugin->IsMultisite() ) {
|
1728 |
-
$blog_info = get_blog_details( $site_id, true );
|
1729 |
-
$blog_name = esc_html__( 'Unknown Site', 'wp-security-audit-log' );
|
1730 |
-
$blog_url = '';
|
1731 |
-
|
1732 |
-
if ( $blog_info ) {
|
1733 |
-
$blog_name = esc_html( $blog_info->blogname );
|
1734 |
-
$blog_url = esc_attr( $blog_info->siteurl );
|
1735 |
-
}
|
1736 |
-
} else {
|
1737 |
-
$blog_name = get_bloginfo( 'name' );
|
1738 |
-
$blog_url = '';
|
1739 |
-
|
1740 |
-
if ( empty( $blog_name ) ) {
|
1741 |
-
$blog_name = __( 'Unknown Site', 'wp-security-audit-log' );
|
1742 |
-
} else {
|
1743 |
-
$blog_name = esc_html( $blog_name );
|
1744 |
-
$blog_url = esc_attr( get_bloginfo( 'url' ) );
|
1745 |
-
}
|
1746 |
-
}
|
1747 |
|
1748 |
// Get the alert message - properly.
|
1749 |
-
$occurrence->id
|
1750 |
-
$occurrence->site_id
|
1751 |
-
$occurrence->alert_id
|
1752 |
-
$occurrence->created_on
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1753 |
|
1754 |
$event_metadata = $occurrence->GetMetaArray();
|
1755 |
if ( ! $occurrence->_cachedMessage ) {
|
@@ -1766,18 +1379,74 @@ final class WSAL_AlertManager {
|
|
1766 |
// Meta details.
|
1767 |
return array(
|
1768 |
'site_id' => $site_id,
|
1769 |
-
'blog_name' => $
|
1770 |
-
'blog_url' => $
|
1771 |
'alert_id' => $alert_id,
|
1772 |
-
'timestamp' => $created_on,
|
1773 |
'date' => WSAL_Utilities_DateTimeFormatter::instance()->getFormattedDateTime( $created_on ),
|
|
|
|
|
|
|
1774 |
'code' => $const->name,
|
|
|
1775 |
'message' => $occurrence->GetMessage( $event_metadata, $context ),
|
|
|
1776 |
'user_name' => $username,
|
1777 |
'user_data' => $user_id ? $this->get_event_user_data( $username ) : false,
|
1778 |
'role' => $roles,
|
1779 |
'user_ip' => $ip,
|
|
|
|
|
1780 |
'user_agent' => $ua,
|
1781 |
);
|
1782 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1783 |
}
|
83 |
public $ignored_cpts = array();
|
84 |
|
85 |
/**
|
86 |
+
* Date format.
|
87 |
+
*
|
88 |
* @var string Date format.
|
89 |
*/
|
90 |
private $date_format;
|
91 |
|
92 |
+
/**
|
93 |
+
* Sanitized date format.
|
94 |
+
*
|
95 |
+
* @var string
|
96 |
+
* @since 4.2.1
|
97 |
+
*/
|
98 |
+
private $sanitized_date_format;
|
99 |
|
100 |
/**
|
101 |
* Create new AlertManager instance.
|
104 |
*/
|
105 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
106 |
$this->plugin = $plugin;
|
107 |
+
foreach ( WSAL_Utilities_FileSystemUtils::read_files_in_folder( dirname( __FILE__ ) . '/Loggers', '*.php' ) as $file ) {
|
108 |
$this->AddFromFile( $file );
|
109 |
}
|
110 |
|
237 |
|
238 |
// If user or user role is enable then go ahead.
|
239 |
if ( $this->CheckEnableUserRoles( $username, $roles ) ) {
|
240 |
+
|
241 |
+
$data['Timestamp'] = ( isset( $data['Timestamp'] ) && ! empty( $data['Timestamp'] ) ) ? $data['Timestamp'] : current_time( 'U.u', 'true' );
|
242 |
if ( $delayed ) {
|
243 |
$this->TriggerIf( $type, $data, null );
|
244 |
} else {
|
335 |
/**
|
336 |
* Method: Commit an alert now.
|
337 |
*
|
338 |
+
* @param int $type - Alert type.
|
339 |
+
* @param array $data - Data of the alert.
|
340 |
+
* @param array $cond - Condition for the alert.
|
341 |
+
* @param bool $_retry - Retry.
|
342 |
*
|
343 |
* @return mixed
|
|
|
344 |
* @internal
|
|
|
345 |
*/
|
346 |
protected function _CommitItem( $type, $data, $cond, $_retry = true ) {
|
347 |
// Double NOT operation here is intentional. Same as ! ( bool ) [ $value ]
|
359 |
} else {
|
360 |
// In general this shouldn't happen, but it could, so we handle it here.
|
361 |
/* translators: Event ID */
|
362 |
+
$error_message = sprintf( esc_html__( 'Event with code %d has not be registered.', 'wp-security-audit-log' ), $type );
|
363 |
+
$this->plugin->wsal_log( $error_message );
|
364 |
}
|
365 |
}
|
366 |
}
|
411 |
/**
|
412 |
* Register an alert type.
|
413 |
*
|
414 |
+
* @param string $category Category name.
|
415 |
* @param string $subcategory Subcategory name.
|
416 |
+
* @param array $info Event information from defaults.php.
|
|
|
|
|
417 |
*/
|
418 |
public function Register( $category, $subcategory, $info ) {
|
419 |
|
420 |
+
// Default for optional fields.
|
421 |
+
$metadata = array();
|
422 |
+
$links = array();
|
423 |
$object = '';
|
424 |
$event_type = '';
|
425 |
|
426 |
$definition_items_count = count( $info );
|
427 |
+
if ( 8 === $definition_items_count ) {
|
428 |
+
// Most recent event definition introduced in version 4.2.1.
|
429 |
list( $code, $severity, $desc, $message, $metadata, $links, $object, $event_type ) = $info;
|
430 |
+
} elseif ( 6 === $definition_items_count ) {
|
431 |
+
// Legacy event definition for backwards compatibility (used prior to version 4.2.1).
|
432 |
list( $code, $severity, $desc, $message, $object, $event_type ) = $info;
|
433 |
} else {
|
434 |
+
// Even older legacy event definition for backwards compatibility.
|
435 |
list( $code, $severity, $desc, $message ) = $info;
|
436 |
}
|
437 |
|
438 |
if ( is_string( $links ) ) {
|
439 |
+
$links = array( $links );
|
440 |
}
|
441 |
+
|
442 |
if ( isset( $this->_alerts[ $code ] ) ) {
|
443 |
add_action( 'admin_notices', array( $this, 'duplicate_event_notice' ) );
|
444 |
/* Translators: Event ID */
|
445 |
+
$error_message = sprintf( esc_html__( 'Event %s already registered with WP Activity Log.', 'wp-security-audit-log' ), $code );
|
446 |
+
$this->plugin->wsal_log( $error_message );
|
447 |
+
|
448 |
+
return;
|
449 |
}
|
450 |
|
451 |
/**
|
458 |
* @param integer $code - Event ID.
|
459 |
*
|
460 |
* @since 4.3.2
|
|
|
461 |
*/
|
462 |
$metadata = apply_filters( 'wsal_event_metadata_definition', $metadata, $code );
|
463 |
|
469 |
*
|
470 |
* @param array $groups - An array with group name as the index and an array of group items as the value.
|
471 |
* Item values is an array of [type, code, description, message, object, event type] respectively.
|
|
|
|
|
472 |
*/
|
473 |
public function RegisterGroup( $groups ) {
|
474 |
foreach ( $groups as $name => $group ) {
|
858 |
return $is_disabled;
|
859 |
}
|
860 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
861 |
/**
|
862 |
* Return user data array of the events.
|
863 |
*
|
1152 |
return get_event_type_data( $event_type );
|
1153 |
}
|
1154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1155 |
/**
|
1156 |
* Modify post name values to include MySQL wildcards.
|
1157 |
*
|
1193 |
return array_keys( $this->get_sub_categorized_events() );
|
1194 |
}
|
1195 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1196 |
/**
|
1197 |
* Get user ids for reports.
|
1198 |
*
|
1310 |
/**
|
1311 |
* Get alert details.
|
1312 |
*
|
1313 |
+
* @param stdClass $entry Raw entry from the occurrences table.
|
1314 |
+
* @param string $context Display context.
|
|
|
|
|
|
|
|
|
|
|
|
|
1315 |
*
|
1316 |
+
* @return array|false Alert details.
|
1317 |
* @throws Exception
|
1318 |
*/
|
1319 |
+
public function get_alert_details( $entry, $context = 'default' ) {
|
1320 |
+
$entry_id = $entry->id;
|
1321 |
+
$alert_id = $entry->alert_id;
|
1322 |
+
$site_id = $entry->site_id;
|
1323 |
+
$created_on = $entry->created_on;
|
1324 |
+
$object = $entry->object;
|
1325 |
+
$event_type = $entry->event_type;
|
1326 |
+
$user_id = $entry->user_id;
|
1327 |
+
|
1328 |
+
$ip = esc_html( $entry->ip );
|
1329 |
+
$ua = esc_html( $entry->ua );
|
1330 |
+
$roles = maybe_unserialize( $entry->roles );
|
1331 |
+
if ( is_string( $roles ) ) {
|
1332 |
+
$roles = str_replace( array( '"', '[', ']' ), ' ', $roles );
|
1333 |
+
}
|
1334 |
+
|
1335 |
// Must be a new instance every time, otherwise the alert message is not retrieved properly.
|
1336 |
$occurrence = new WSAL_Models_Occurrence();
|
1337 |
|
1338 |
+
$user_id = ( ! is_numeric( $user_id ) && null !== $user_id ) ? WSAL_Utilities_UsersUtils::swap_login_for_id( $user_id ) : $user_id;
|
1339 |
|
1340 |
// Get alert details.
|
1341 |
$code = $this->GetAlert( $alert_id );
|
1347 |
);
|
1348 |
$const = $this->plugin->constants->GetConstantBy( 'value', $code, $const );
|
1349 |
|
1350 |
+
$blog_info = WSAL_AlertManager::get_blog_info( $this->plugin, $site_id );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1351 |
|
1352 |
// Get the alert message - properly.
|
1353 |
+
$occurrence->id = $entry_id;
|
1354 |
+
$occurrence->site_id = $site_id;
|
1355 |
+
$occurrence->alert_id = $alert_id;
|
1356 |
+
$occurrence->created_on = $created_on;
|
1357 |
+
$occurrence->client_ip = $ip;
|
1358 |
+
$occurrence->object = $object;
|
1359 |
+
$occurrence->event_type = $event_type;
|
1360 |
+
$occurrence->user_id = $user_id;
|
1361 |
+
$occurrence->user_agent = $ua;
|
1362 |
+
$occurrence->post_id = $entry->post_id;
|
1363 |
+
$occurrence->post_type = $entry->post_type;
|
1364 |
+
$occurrence->post_status = $entry->post_status;
|
1365 |
+
$occurrence->SetUserRoles( $roles );
|
1366 |
|
1367 |
$event_metadata = $occurrence->GetMetaArray();
|
1368 |
if ( ! $occurrence->_cachedMessage ) {
|
1379 |
// Meta details.
|
1380 |
return array(
|
1381 |
'site_id' => $site_id,
|
1382 |
+
'blog_name' => $blog_info['name'],
|
1383 |
+
'blog_url' => $blog_info['url'],
|
1384 |
'alert_id' => $alert_id,
|
|
|
1385 |
'date' => WSAL_Utilities_DateTimeFormatter::instance()->getFormattedDateTime( $created_on ),
|
1386 |
+
// We need to keep the timestamp to be able to group entries by dates etc. The "date" field is not suitable
|
1387 |
+
// as it is already translated, thus difficult to parse and process.
|
1388 |
+
'timestamp' => $created_on,
|
1389 |
'code' => $const->name,
|
1390 |
+
// Fill variables in message.
|
1391 |
'message' => $occurrence->GetMessage( $event_metadata, $context ),
|
1392 |
+
'user_id' => $user_id,
|
1393 |
'user_name' => $username,
|
1394 |
'user_data' => $user_id ? $this->get_event_user_data( $username ) : false,
|
1395 |
'role' => $roles,
|
1396 |
'user_ip' => $ip,
|
1397 |
+
'object' => $this->get_event_objects_data( $object ),
|
1398 |
+
'event_type' => $this->get_event_type_data( $event_type ),
|
1399 |
'user_agent' => $ua,
|
1400 |
);
|
1401 |
}
|
1402 |
+
|
1403 |
+
/**
|
1404 |
+
* Retrieves blog info for given site based on current multisite situation. Optimizes for performance using local
|
1405 |
+
* cache.
|
1406 |
+
*
|
1407 |
+
* @param WpSecurityAuditLog $plugin WSAL plugin instance.
|
1408 |
+
* @param int $site_id Site ID.
|
1409 |
+
*
|
1410 |
+
* @return array
|
1411 |
+
* @since 4.4.0
|
1412 |
+
*/
|
1413 |
+
public static function get_blog_info( $plugin, $site_id ) {
|
1414 |
+
// Blog details.
|
1415 |
+
if ( $plugin->IsMultisite() ) {
|
1416 |
+
$blog_info = get_blog_details( $site_id, true );
|
1417 |
+
$blog_name = esc_html__( 'Unknown Site', 'wp-security-audit-log' );
|
1418 |
+
$blog_url = '';
|
1419 |
+
|
1420 |
+
if ( $blog_info ) {
|
1421 |
+
$blog_name = esc_html( $blog_info->blogname );
|
1422 |
+
$blog_url = esc_attr( $blog_info->siteurl );
|
1423 |
+
}
|
1424 |
+
} else {
|
1425 |
+
$blog_name = get_bloginfo( 'name' );
|
1426 |
+
$blog_url = '';
|
1427 |
+
|
1428 |
+
if ( empty( $blog_name ) ) {
|
1429 |
+
$blog_name = __( 'Unknown Site', 'wp-security-audit-log' );
|
1430 |
+
} else {
|
1431 |
+
$blog_name = esc_html( $blog_name );
|
1432 |
+
$blog_url = esc_attr( get_bloginfo( 'url' ) );
|
1433 |
+
}
|
1434 |
+
}
|
1435 |
+
|
1436 |
+
return array(
|
1437 |
+
'name' => $blog_name,
|
1438 |
+
'url' => $blog_url,
|
1439 |
+
);
|
1440 |
+
}
|
1441 |
+
|
1442 |
+
/**
|
1443 |
+
* Retrieves local cache of WP Users.
|
1444 |
+
*
|
1445 |
+
* @return WP_User[] WordPress users.
|
1446 |
+
*
|
1447 |
+
* @since 4.4.0
|
1448 |
+
*/
|
1449 |
+
public function get_wp_users(): array {
|
1450 |
+
return $this->wp_users;
|
1451 |
+
}
|
1452 |
}
|
classes/AuditLogGridView.php
CHANGED
@@ -418,10 +418,8 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
418 |
|
419 |
// Additional user info tooltip.
|
420 |
$tooltip = WSAL_Utilities_UsersUtils::get_tooltip_user_content( $user );
|
421 |
-
|
422 |
$uhtml = '<a class="tooltip" data-tooltip="' . esc_attr( $tooltip ) . '" data-user="' . $user->user_login . '" href="' . $user_edit_link . '" target="_blank">' . esc_html( $display_name ) . '</a>';
|
423 |
|
424 |
-
|
425 |
$roles = WSAL_Utilities_UsersUtils::get_roles_label( $item->GetUserRoles() );
|
426 |
} elseif ( 'Plugin' == $username ) {
|
427 |
$uhtml = '<i>' . __( 'Plugin', 'wp-security-audit-log' ) . '</i>';
|
@@ -784,7 +782,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
784 |
*/
|
785 |
public function query_events( $paged = 0 ) {
|
786 |
|
787 |
-
// TO DO: Get rid of OccurrenceQuery and use the
|
788 |
$query = new WSAL_Models_OccurrenceQuery();
|
789 |
|
790 |
$bid = (int) $this->query_args->site_id;
|
@@ -848,6 +846,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
848 |
|
849 |
$query->setOffset( $offset ); // Set query offset.
|
850 |
$query->setLimit( $per_page ); // Set number of events per page.
|
|
|
851 |
return array(
|
852 |
'total_items' => $total_items,
|
853 |
'per_page' => $per_page,
|
418 |
|
419 |
// Additional user info tooltip.
|
420 |
$tooltip = WSAL_Utilities_UsersUtils::get_tooltip_user_content( $user );
|
|
|
421 |
$uhtml = '<a class="tooltip" data-tooltip="' . esc_attr( $tooltip ) . '" data-user="' . $user->user_login . '" href="' . $user_edit_link . '" target="_blank">' . esc_html( $display_name ) . '</a>';
|
422 |
|
|
|
423 |
$roles = WSAL_Utilities_UsersUtils::get_roles_label( $item->GetUserRoles() );
|
424 |
} elseif ( 'Plugin' == $username ) {
|
425 |
$uhtml = '<i>' . __( 'Plugin', 'wp-security-audit-log' ) . '</i>';
|
782 |
*/
|
783 |
public function query_events( $paged = 0 ) {
|
784 |
|
785 |
+
// TO DO: Get rid of OccurrenceQuery and use the Occurrence Model.
|
786 |
$query = new WSAL_Models_OccurrenceQuery();
|
787 |
|
788 |
$bid = (int) $this->query_args->site_id;
|
846 |
|
847 |
$query->setOffset( $offset ); // Set query offset.
|
848 |
$query->setLimit( $per_page ); // Set number of events per page.
|
849 |
+
|
850 |
return array(
|
851 |
'total_items' => $total_items,
|
852 |
'per_page' => $per_page,
|
classes/AuditLogListView.php
CHANGED
@@ -768,7 +768,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
768 |
|
769 |
// TO DO: Get rid of OccurrenceQuery and use the Occurrence Model.
|
770 |
$query = new WSAL_Models_OccurrenceQuery();
|
771 |
-
$bid
|
772 |
if ( $bid ) {
|
773 |
$query->addCondition( 'site_id = %s ', $bid );
|
774 |
}
|
@@ -808,34 +808,24 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
808 |
|
809 |
// TO DO: Allow order by meta values.
|
810 |
if ( 'scip' === $order_by ) {
|
811 |
-
$query->
|
812 |
-
$query->addCondition( 'meta.name = %s', 'ClientIP' ); // A where condition is added to make sure that we're only requesting the relevant meta data rows from metadata table.
|
813 |
-
$query->addOrderBy( 'CASE WHEN meta.name = "ClientIP" THEN meta.value END', $is_descending );
|
814 |
} elseif ( 'user' === $order_by ) {
|
815 |
-
$query->
|
816 |
-
$query->addCondition( 'meta.name = %s', 'CurrentUserID' ); // A where condition is added to make sure that we're only requesting the relevant meta data rows from metadata table.
|
817 |
-
$query->addOrderBy( 'CASE WHEN meta.name = "CurrentUserID" THEN meta.value END', $is_descending );
|
818 |
} elseif ( 'code' === $order_by ) {
|
819 |
/*
|
820 |
* Handle the 'code' (Severity) column sorting.
|
821 |
*/
|
822 |
-
$query->
|
823 |
-
$query->addCondition( 'meta.name = %s', 'Severity' ); // A where condition is added to make sure that we're only requesting the relevant meta data rows from metadata table.
|
824 |
-
$query->addOrderBy( 'CASE WHEN meta.name = "Severity" THEN meta.value END', $is_descending );
|
825 |
} elseif ( 'object' === $order_by ) {
|
826 |
/*
|
827 |
* Handle the 'object' column sorting.
|
828 |
*/
|
829 |
-
$query->
|
830 |
-
$query->addCondition( 'meta.name = %s', 'Object' ); // A where condition is added to make sure that we're only requesting the relevant meta data rows from metadata table.
|
831 |
-
$query->addOrderBy( 'CASE WHEN meta.name = "Object" THEN meta.value END', $is_descending );
|
832 |
} elseif ( 'event_type' === $order_by ) {
|
833 |
/*
|
834 |
* Handle the 'Event Type' column sorting.
|
835 |
*/
|
836 |
-
$query->
|
837 |
-
$query->addCondition( 'meta.name = %s', 'EventType' ); // A where condition is added to make sure that we're only requesting the relevant meta data rows from metadata table.
|
838 |
-
$query->addOrderBy( 'CASE WHEN meta.name = "EventType" THEN meta.value END', $is_descending );
|
839 |
} else {
|
840 |
$tmp = new WSAL_Models_Occurrence();
|
841 |
// Making sure the field exists to order by.
|
768 |
|
769 |
// TO DO: Get rid of OccurrenceQuery and use the Occurrence Model.
|
770 |
$query = new WSAL_Models_OccurrenceQuery();
|
771 |
+
$bid = (int) $this->query_args->site_id;
|
772 |
if ( $bid ) {
|
773 |
$query->addCondition( 'site_id = %s ', $bid );
|
774 |
}
|
808 |
|
809 |
// TO DO: Allow order by meta values.
|
810 |
if ( 'scip' === $order_by ) {
|
811 |
+
$query->addOrderBy( 'client_ip', $is_descending );
|
|
|
|
|
812 |
} elseif ( 'user' === $order_by ) {
|
813 |
+
$query->addOrderBy( 'user_id', $is_descending );
|
|
|
|
|
814 |
} elseif ( 'code' === $order_by ) {
|
815 |
/*
|
816 |
* Handle the 'code' (Severity) column sorting.
|
817 |
*/
|
818 |
+
$query->addOrderBy( 'severity', $is_descending );
|
|
|
|
|
819 |
} elseif ( 'object' === $order_by ) {
|
820 |
/*
|
821 |
* Handle the 'object' column sorting.
|
822 |
*/
|
823 |
+
$query->addOrderBy( 'object', $is_descending );
|
|
|
|
|
824 |
} elseif ( 'event_type' === $order_by ) {
|
825 |
/*
|
826 |
* Handle the 'Event Type' column sorting.
|
827 |
*/
|
828 |
+
$query->addOrderBy( 'event_type', $is_descending );
|
|
|
|
|
829 |
} else {
|
830 |
$tmp = new WSAL_Models_Occurrence();
|
831 |
// Making sure the field exists to order by.
|
classes/Connector/ConnectorFactory.php
CHANGED
@@ -28,12 +28,14 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
28 |
* @var string
|
29 |
*/
|
30 |
public static $adapter;
|
|
|
31 |
/**
|
32 |
* Connector.
|
33 |
*
|
34 |
* @var array
|
35 |
*/
|
36 |
-
private static $connectors =
|
|
|
37 |
/**
|
38 |
* Occurrence is installed.
|
39 |
*
|
@@ -44,7 +46,16 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
44 |
private static $is_installed;
|
45 |
|
46 |
/**
|
47 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
* also custom options table in the past.
|
49 |
*/
|
50 |
public static function GetDefaultConnector() {
|
@@ -55,7 +66,7 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
55 |
* Returns a connector singleton
|
56 |
*
|
57 |
* @param string|array $config DB configuration array, db alias or empty to use default connection.
|
58 |
-
* @param bool
|
59 |
*
|
60 |
* @return WSAL_Connector_ConnectorInterface
|
61 |
* @throws Freemius_Exception
|
@@ -63,17 +74,24 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
63 |
public static function GetConnector( $config = null, $reset = false ) {
|
64 |
$connection_config = null;
|
65 |
if ( is_null( $config ) || empty( $config ) ) {
|
66 |
-
|
67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
} else {
|
69 |
if ( is_string( $config ) ) {
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
}
|
76 |
-
|
77 |
$connection_config = $config;
|
78 |
}
|
79 |
}
|
@@ -81,23 +99,23 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
81 |
$cache_key = 'default';
|
82 |
if ( is_string( $config ) ) {
|
83 |
$cache_key = $connection_config;
|
84 |
-
}
|
85 |
$cache_key = $connection_config['name'];
|
86 |
}
|
87 |
|
88 |
// TO DO: Load connection config.
|
89 |
-
if ( ! array_key_exists($cache_key,
|
90 |
$connection_type = is_array( $connection_config ) && isset( $connection_config['type'] ) ? strtolower( $connection_config['type'] ) : '';
|
91 |
switch ( $connection_type ) {
|
92 |
// TO DO: Add other connectors.
|
93 |
case 'mysql':
|
94 |
default:
|
95 |
// Use config.
|
96 |
-
self::$connectors[$cache_key] = new WSAL_Connector_MySQLDB( $connection_config );
|
97 |
}
|
98 |
}
|
99 |
|
100 |
-
return self::$connectors[$cache_key];
|
101 |
}
|
102 |
|
103 |
/**
|
@@ -131,11 +149,24 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
131 |
return null;
|
132 |
}
|
133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
/*
|
135 |
* Reused code from the external DB module.
|
136 |
*
|
137 |
* @see WSAL_Ext_Common::get_connection()
|
138 |
*/
|
|
|
139 |
$connection_raw = maybe_unserialize( $plugin->GetGlobalSetting( 'connection-' . $connection_name ) );
|
140 |
$connection = ( $connection_raw instanceof stdClass ) ? json_decode( json_encode( $connection_raw ), true ) : $connection_raw;
|
141 |
if ( ! is_array( $connection ) || empty( $connection ) ) {
|
@@ -153,7 +184,7 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
153 |
* @return boolean true|false
|
154 |
*/
|
155 |
public static function CheckConfig( $config ) {
|
156 |
-
//
|
157 |
if ( array_key_exists( 'type', $config ) && 'mysql' === $config['type'] ) {
|
158 |
try {
|
159 |
$connector = new WSAL_Connector_MySQLDB( $config );
|
@@ -165,4 +196,22 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
165 |
|
166 |
return false;
|
167 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
}
|
28 |
* @var string
|
29 |
*/
|
30 |
public static $adapter;
|
31 |
+
|
32 |
/**
|
33 |
* Connector.
|
34 |
*
|
35 |
* @var array
|
36 |
*/
|
37 |
+
private static $connectors = array();
|
38 |
+
|
39 |
/**
|
40 |
* Occurrence is installed.
|
41 |
*
|
46 |
private static $is_installed;
|
47 |
|
48 |
/**
|
49 |
+
* Enabled archive mode. It forces archive connector by default.
|
50 |
+
*
|
51 |
+
* @var bool
|
52 |
+
*
|
53 |
+
* @since 4.4.0
|
54 |
+
*/
|
55 |
+
private static $archive_mode = false;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Returns the default WPDB connector that must be always used for some data, for example user sessions and
|
59 |
* also custom options table in the past.
|
60 |
*/
|
61 |
public static function GetDefaultConnector() {
|
66 |
* Returns a connector singleton
|
67 |
*
|
68 |
* @param string|array $config DB configuration array, db alias or empty to use default connection.
|
69 |
+
* @param bool $reset - True if reset.
|
70 |
*
|
71 |
* @return WSAL_Connector_ConnectorInterface
|
72 |
* @throws Freemius_Exception
|
74 |
public static function GetConnector( $config = null, $reset = false ) {
|
75 |
$connection_config = null;
|
76 |
if ( is_null( $config ) || empty( $config ) ) {
|
77 |
+
if ( self::$archive_mode ) {
|
78 |
+
// Force archive database if no config provided and archive mode is enabled.
|
79 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
80 |
+
$connection_name = $plugin->GetGlobalSetting( 'archive-connection' );
|
81 |
+
$connection_config = self::load_connection_config( $connection_name );
|
82 |
+
} else {
|
83 |
+
// Default config - local or external, depending on plugin settings and licensing.
|
84 |
+
$connection_config = self::GetConfig( $config );
|
85 |
+
}
|
86 |
} else {
|
87 |
if ( is_string( $config ) ) {
|
88 |
+
// String based config, can be used to retrieve local WP connection.
|
89 |
+
if ( 'local' === $config ) {
|
90 |
+
// This forces the WSAL_Connector_MySQLDB to return connection to local WP database.
|
91 |
+
$connection_config = null;
|
92 |
+
}
|
93 |
+
} elseif ( is_array( $config ) ) {
|
94 |
+
// Array config gets connection to whatever database configuration it holds.
|
95 |
$connection_config = $config;
|
96 |
}
|
97 |
}
|
99 |
$cache_key = 'default';
|
100 |
if ( is_string( $config ) ) {
|
101 |
$cache_key = $connection_config;
|
102 |
+
} elseif ( is_array( $connection_config ) ) {
|
103 |
$cache_key = $connection_config['name'];
|
104 |
}
|
105 |
|
106 |
// TO DO: Load connection config.
|
107 |
+
if ( ! array_key_exists( $cache_key, self::$connectors ) || $reset ) {
|
108 |
$connection_type = is_array( $connection_config ) && isset( $connection_config['type'] ) ? strtolower( $connection_config['type'] ) : '';
|
109 |
switch ( $connection_type ) {
|
110 |
// TO DO: Add other connectors.
|
111 |
case 'mysql':
|
112 |
default:
|
113 |
// Use config.
|
114 |
+
self::$connectors[ $cache_key ] = new WSAL_Connector_MySQLDB( $connection_config );
|
115 |
}
|
116 |
}
|
117 |
|
118 |
+
return self::$connectors[ $cache_key ];
|
119 |
}
|
120 |
|
121 |
/**
|
149 |
return null;
|
150 |
}
|
151 |
|
152 |
+
return self::load_connection_config( $connection_name );
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Loads connection config using its name.
|
157 |
+
*
|
158 |
+
* @param string $connection_name Connection name.
|
159 |
+
*
|
160 |
+
* @return array|null
|
161 |
+
* @since 4.4.0
|
162 |
+
*/
|
163 |
+
private static function load_connection_config( $connection_name ) {
|
164 |
/*
|
165 |
* Reused code from the external DB module.
|
166 |
*
|
167 |
* @see WSAL_Ext_Common::get_connection()
|
168 |
*/
|
169 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
170 |
$connection_raw = maybe_unserialize( $plugin->GetGlobalSetting( 'connection-' . $connection_name ) );
|
171 |
$connection = ( $connection_raw instanceof stdClass ) ? json_decode( json_encode( $connection_raw ), true ) : $connection_raw;
|
172 |
if ( ! is_array( $connection ) || empty( $connection ) ) {
|
184 |
* @return boolean true|false
|
185 |
*/
|
186 |
public static function CheckConfig( $config ) {
|
187 |
+
// Only mysql supported at the moment.
|
188 |
if ( array_key_exists( 'type', $config ) && 'mysql' === $config['type'] ) {
|
189 |
try {
|
190 |
$connector = new WSAL_Connector_MySQLDB( $config );
|
196 |
|
197 |
return false;
|
198 |
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Enables archive mode.
|
202 |
+
*
|
203 |
+
* @since 4.4.0
|
204 |
+
*/
|
205 |
+
public static function enable_archive_mode() {
|
206 |
+
self::$archive_mode = true;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Disables archive mode.
|
211 |
+
*
|
212 |
+
* @since 4.4.0
|
213 |
+
*/
|
214 |
+
public static function disable_archive_mode() {
|
215 |
+
self::$archive_mode = false;
|
216 |
+
}
|
217 |
}
|
classes/Connector/ConnectorInterface.php
CHANGED
@@ -41,7 +41,9 @@ interface WSAL_Connector_ConnectorInterface {
|
|
41 |
public function closeConnection();
|
42 |
|
43 |
/**
|
44 |
-
*
|
|
|
|
|
45 |
*/
|
46 |
public function isInstalled();
|
47 |
|
@@ -66,4 +68,14 @@ interface WSAL_Connector_ConnectorInterface {
|
|
66 |
* Uninstall all.
|
67 |
*/
|
68 |
public function uninstallAll();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
}
|
41 |
public function closeConnection();
|
42 |
|
43 |
/**
|
44 |
+
* Checks if the necessary tables are available
|
45 |
+
*
|
46 |
+
* @return bool true|false
|
47 |
*/
|
48 |
public function isInstalled();
|
49 |
|
68 |
* Uninstall all.
|
69 |
*/
|
70 |
public function uninstallAll();
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Run any query.
|
74 |
+
*
|
75 |
+
* @param string $query
|
76 |
+
*
|
77 |
+
* @return mixed
|
78 |
+
* @since 4.4.0
|
79 |
+
*/
|
80 |
+
public function query( $query );
|
81 |
}
|
classes/Connector/MySQLDB.php
CHANGED
@@ -186,11 +186,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
186 |
}
|
187 |
|
188 |
/**
|
189 |
-
*
|
190 |
-
*
|
191 |
-
* @param string $class_name - Class name.
|
192 |
-
*
|
193 |
-
* @return WSAL_Adapters_ActiveRecordInterface
|
194 |
*/
|
195 |
public function getAdapter( $class_name ) {
|
196 |
$obj_name = $this->getAdapterClassName( $class_name );
|
@@ -210,9 +206,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
210 |
}
|
211 |
|
212 |
/**
|
213 |
-
*
|
214 |
-
*
|
215 |
-
* @return bool true|false
|
216 |
*/
|
217 |
public function isInstalled() {
|
218 |
$wpdb = $this->getConnection();
|
@@ -228,7 +222,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
228 |
* @param bool $is_external_database If true, some tables will not be created.
|
229 |
*/
|
230 |
public function installAll( $is_external_database = false ) {
|
231 |
-
$adapter_list =
|
232 |
$adapter_list = apply_filters( 'wsal_install_adapters_list', $adapter_list );
|
233 |
foreach ( $adapter_list as $file ) {
|
234 |
$file_path = explode( DIRECTORY_SEPARATOR, $file );
|
@@ -269,7 +263,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
269 |
* Uninstall all DB tables.
|
270 |
*/
|
271 |
public function uninstallAll() {
|
272 |
-
foreach (
|
273 |
$file_path = explode( DIRECTORY_SEPARATOR, $file );
|
274 |
$file_name = $file_path[ count( $file_path ) - 1 ];
|
275 |
$class_name = $this->getAdapterClassName( str_replace( 'Adapter.php', '', $file_name ) );
|
@@ -323,7 +317,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
323 |
return 0;
|
324 |
}
|
325 |
|
326 |
-
//
|
327 |
$occurrence_adapter_target = new WSAL_Adapters_MySQL_Occurrence( $target_db );
|
328 |
$occurrence_table_name_target = $occurrence_adapter_target->GetTable();
|
329 |
|
@@ -334,8 +328,19 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
334 |
'site_id' => $entry['site_id'],
|
335 |
'alert_id' => $entry['alert_id'],
|
336 |
'created_on' => $entry['created_on'],
|
337 |
-
'
|
338 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
|
340 |
$old_entry_id = intval( $entry['id'] );
|
341 |
$new_entry_id = $target_db->insert_id;
|
@@ -416,7 +421,6 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
416 |
*/
|
417 |
public function MigrateOccurrenceFromExternalToLocal( $limit ) {
|
418 |
global $wpdb;
|
419 |
-
|
420 |
return $this->MigrateOccurrence( $this->getConnection(), $wpdb, $limit );
|
421 |
}
|
422 |
|
@@ -493,18 +497,32 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
493 |
|
494 |
$occurrence_new = new WSAL_Adapters_MySQL_Occurrence( $archive_db );
|
495 |
|
496 |
-
$sql = 'INSERT INTO ' . $occurrence_new->GetTable() . ' (id, site_id, alert_id, created_on,
|
497 |
foreach ( $occurrences as $entry ) {
|
498 |
-
|
499 |
-
|
|
|
500 |
intval( $entry['id'] ),
|
501 |
intval( $entry['site_id'] ),
|
502 |
intval( $entry['alert_id'] ),
|
503 |
$entry['created_on'],
|
504 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
505 |
);
|
506 |
-
|
|
|
507 |
}
|
|
|
508 |
$sql = rtrim( $sql, ', ' );
|
509 |
$archive_db->query( $sql );
|
510 |
|
@@ -599,4 +617,11 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
599 |
// If both queries are successful, then return true.
|
600 |
return $query_occ && $query_meta;
|
601 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
602 |
}
|
186 |
}
|
187 |
|
188 |
/**
|
189 |
+
* @inheritDoc
|
|
|
|
|
|
|
|
|
190 |
*/
|
191 |
public function getAdapter( $class_name ) {
|
192 |
$obj_name = $this->getAdapterClassName( $class_name );
|
206 |
}
|
207 |
|
208 |
/**
|
209 |
+
* @inheritDoc
|
|
|
|
|
210 |
*/
|
211 |
public function isInstalled() {
|
212 |
$wpdb = $this->getConnection();
|
222 |
* @param bool $is_external_database If true, some tables will not be created.
|
223 |
*/
|
224 |
public function installAll( $is_external_database = false ) {
|
225 |
+
$adapter_list = WSAL_Utilities_FileSystemUtils::read_files_in_folder( $this->getAdaptersDirectory(), '*.php' );
|
226 |
$adapter_list = apply_filters( 'wsal_install_adapters_list', $adapter_list );
|
227 |
foreach ( $adapter_list as $file ) {
|
228 |
$file_path = explode( DIRECTORY_SEPARATOR, $file );
|
263 |
* Uninstall all DB tables.
|
264 |
*/
|
265 |
public function uninstallAll() {
|
266 |
+
foreach ( WSAL_Utilities_FileSystemUtils::read_files_in_folder( $this->getAdaptersDirectory(), '*.php' ) as $file ) {
|
267 |
$file_path = explode( DIRECTORY_SEPARATOR, $file );
|
268 |
$file_name = $file_path[ count( $file_path ) - 1 ];
|
269 |
$class_name = $this->getAdapterClassName( str_replace( 'Adapter.php', '', $file_name ) );
|
317 |
return 0;
|
318 |
}
|
319 |
|
320 |
+
// Insert data to the target database.
|
321 |
$occurrence_adapter_target = new WSAL_Adapters_MySQL_Occurrence( $target_db );
|
322 |
$occurrence_table_name_target = $occurrence_adapter_target->GetTable();
|
323 |
|
328 |
'site_id' => $entry['site_id'],
|
329 |
'alert_id' => $entry['alert_id'],
|
330 |
'created_on' => $entry['created_on'],
|
331 |
+
'client_ip' => $entry['client_ip'],
|
332 |
+
'severity' => $entry['severity'],
|
333 |
+
'object' => $entry['object'],
|
334 |
+
'event_type' => $entry['event_type'],
|
335 |
+
'user_agent' => $entry['user_agent'],
|
336 |
+
'user_roles' => $entry['user_roles'],
|
337 |
+
'username' => $entry['username'],
|
338 |
+
'user_id' => $entry['user_id'],
|
339 |
+
'session_id' => $entry['session_id'],
|
340 |
+
'post_status' => $entry['post_status'],
|
341 |
+
'post_type' => $entry['post_type'],
|
342 |
+
'post_id' => $entry['post_id'],
|
343 |
+
], [ '%d', '%d', '%f','%s', '%d','%s', '%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%d'] );
|
344 |
|
345 |
$old_entry_id = intval( $entry['id'] );
|
346 |
$new_entry_id = $target_db->insert_id;
|
421 |
*/
|
422 |
public function MigrateOccurrenceFromExternalToLocal( $limit ) {
|
423 |
global $wpdb;
|
|
|
424 |
return $this->MigrateOccurrence( $this->getConnection(), $wpdb, $limit );
|
425 |
}
|
426 |
|
497 |
|
498 |
$occurrence_new = new WSAL_Adapters_MySQL_Occurrence( $archive_db );
|
499 |
|
500 |
+
$sql = 'INSERT INTO ' . $occurrence_new->GetTable() . ' ( id, site_id, alert_id, created_on, client_ip, severity, object, event_type, user_agent, user_roles, username, user_id, session_id, post_status, post_type, post_id ) VALUES ';
|
501 |
foreach ( $occurrences as $entry ) {
|
502 |
+
|
503 |
+
$sql .= $archive_db->prepare(
|
504 |
+
'( %d, %d, %d, %f, %s, %d, %s, %s, %s, %s, %s, %d, %s, %s, %s, %d ), ',
|
505 |
intval( $entry['id'] ),
|
506 |
intval( $entry['site_id'] ),
|
507 |
intval( $entry['alert_id'] ),
|
508 |
$entry['created_on'],
|
509 |
+
$entry['client_ip'],
|
510 |
+
$entry['severity'],
|
511 |
+
$entry['object'],
|
512 |
+
$entry['event_type'],
|
513 |
+
$entry['user_agent'],
|
514 |
+
$entry['user_roles'],
|
515 |
+
$entry['username'],
|
516 |
+
intval( $entry['user_id'] ),
|
517 |
+
$entry['session_id'],
|
518 |
+
$entry['post_status'],
|
519 |
+
$entry['post_type'],
|
520 |
+
intval( $entry['post_id'] )
|
521 |
);
|
522 |
+
|
523 |
+
$args['occurrence_ids'][] = intval( $entry['id'] );
|
524 |
}
|
525 |
+
|
526 |
$sql = rtrim( $sql, ', ' );
|
527 |
$archive_db->query( $sql );
|
528 |
|
617 |
// If both queries are successful, then return true.
|
618 |
return $query_occ && $query_meta;
|
619 |
}
|
620 |
+
|
621 |
+
/**
|
622 |
+
* @inheritDoc
|
623 |
+
*/
|
624 |
+
public function query( $query ) {
|
625 |
+
return $this->getConnection()->query( $query );
|
626 |
+
}
|
627 |
}
|
classes/Helpers/Options.php
CHANGED
@@ -94,26 +94,28 @@ class Options {
|
|
94 |
* @param bool $autoload Whether or not to autoload this option.
|
95 |
* @return bool Whether or not the option was updated.
|
96 |
*/
|
97 |
-
public function set_option_value( $option_name = '', $value = null, $autoload =
|
98 |
// bail early if no option name or value was passed.
|
99 |
if ( empty( $option_name ) || null === $value ) {
|
100 |
return;
|
101 |
}
|
102 |
|
103 |
$actual_option_name = $option_name;
|
104 |
-
if (!preg_match( '/\A' .preg_quote($this->prefix) . '/', $option_name)) {
|
105 |
// prepend prefix if not already present
|
106 |
$actual_option_name = $this->prefix . $option_name;
|
107 |
}
|
108 |
|
109 |
-
return self::_set_option_value($actual_option_name, $value, $autoload);
|
110 |
}
|
111 |
|
112 |
/**
|
113 |
* Deletes a plugin option from the WP options table.
|
114 |
*
|
|
|
|
|
115 |
* @since 4.0.2
|
116 |
-
* @param string $option_name Name of the option to delete
|
117 |
* @return bool
|
118 |
*/
|
119 |
public function delete_option( $option_name = '' ) {
|
@@ -202,8 +204,8 @@ class Options {
|
|
202 |
* @param bool $autoload Whether or not to autoload this option.
|
203 |
* @return mixed
|
204 |
*/
|
205 |
-
public static function set_option_value_ignore_prefix( $option_name = '', $value = null, $autoload =
|
206 |
-
return self::_set_option_value( $option_name, $value, $autoload
|
207 |
}
|
208 |
|
209 |
/**
|
@@ -216,19 +218,23 @@ class Options {
|
|
216 |
* @param bool $autoload Whether or not to autoload this option.
|
217 |
* @return bool Whether or not the option was updated.
|
218 |
*/
|
219 |
-
private static function _set_option_value( $option_name = '', $value = null, $autoload =
|
220 |
// bail early if no option name or value was passed.
|
221 |
if ( empty( $option_name ) || null === $value ) {
|
222 |
return;
|
223 |
}
|
224 |
|
225 |
-
if (is_multisite()) {
|
226 |
-
switch_to_blog(get_main_network_id());
|
|
|
|
|
|
|
|
|
227 |
}
|
228 |
|
229 |
$result = \update_option( $option_name, $value, $autoload );
|
230 |
|
231 |
-
if (is_multisite()) {
|
232 |
restore_current_blog();
|
233 |
}
|
234 |
|
@@ -260,23 +266,4 @@ class Options {
|
|
260 |
return true === $bool ? 'yes' : 'no';
|
261 |
}
|
262 |
|
263 |
-
/**
|
264 |
-
* Create neat email/sms string to display in the event.
|
265 |
-
*
|
266 |
-
* @param string $email
|
267 |
-
* @param string $sms
|
268 |
-
* @return string
|
269 |
-
*/
|
270 |
-
public static function create_recipient_string( $email, $sms ) {
|
271 |
-
$recipient = ( isset( $email ) ) ? $email : '';
|
272 |
-
if ( isset( $sms ) && ! empty( $sms ) ) {
|
273 |
-
// Only add seperator if needed.
|
274 |
-
if ( ! empty( $recipient ) ) {
|
275 |
-
$recipient .= ' | ';
|
276 |
-
}
|
277 |
-
$recipient .= $sms;
|
278 |
-
}
|
279 |
-
|
280 |
-
return $recipient;
|
281 |
-
}
|
282 |
}
|
94 |
* @param bool $autoload Whether or not to autoload this option.
|
95 |
* @return bool Whether or not the option was updated.
|
96 |
*/
|
97 |
+
public function set_option_value( $option_name = '', $value = null, $autoload = false ) {
|
98 |
// bail early if no option name or value was passed.
|
99 |
if ( empty( $option_name ) || null === $value ) {
|
100 |
return;
|
101 |
}
|
102 |
|
103 |
$actual_option_name = $option_name;
|
104 |
+
if ( ! preg_match( '/\A' . preg_quote( $this->prefix ) . '/', $option_name ) ) {
|
105 |
// prepend prefix if not already present
|
106 |
$actual_option_name = $this->prefix . $option_name;
|
107 |
}
|
108 |
|
109 |
+
return self::_set_option_value( $actual_option_name, $value, $autoload );
|
110 |
}
|
111 |
|
112 |
/**
|
113 |
* Deletes a plugin option from the WP options table.
|
114 |
*
|
115 |
+
* Hanled option name with and without the prefix for backwards compatibility.
|
116 |
+
*
|
117 |
* @since 4.0.2
|
118 |
+
* @param string $option_name Name of the option to delete.
|
119 |
* @return bool
|
120 |
*/
|
121 |
public function delete_option( $option_name = '' ) {
|
204 |
* @param bool $autoload Whether or not to autoload this option.
|
205 |
* @return mixed
|
206 |
*/
|
207 |
+
public static function set_option_value_ignore_prefix( $option_name = '', $value = null, $autoload = false ) {
|
208 |
+
return self::_set_option_value( $option_name, $value, $autoload );
|
209 |
}
|
210 |
|
211 |
/**
|
218 |
* @param bool $autoload Whether or not to autoload this option.
|
219 |
* @return bool Whether or not the option was updated.
|
220 |
*/
|
221 |
+
private static function _set_option_value( $option_name = '', $value = null, $autoload = false ) {
|
222 |
// bail early if no option name or value was passed.
|
223 |
if ( empty( $option_name ) || null === $value ) {
|
224 |
return;
|
225 |
}
|
226 |
|
227 |
+
if ( is_multisite() ) {
|
228 |
+
switch_to_blog( get_main_network_id() );
|
229 |
+
}
|
230 |
+
|
231 |
+
if ( false === $autoload ) {
|
232 |
+
delete_option( $option_name );
|
233 |
}
|
234 |
|
235 |
$result = \update_option( $option_name, $value, $autoload );
|
236 |
|
237 |
+
if ( is_multisite() ) {
|
238 |
restore_current_blog();
|
239 |
}
|
240 |
|
266 |
return true === $bool ? 'yes' : 'no';
|
267 |
}
|
268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
}
|
classes/Loggers/Database.php
CHANGED
@@ -16,10 +16,10 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
16 |
/**
|
17 |
* Loggers Class.
|
18 |
*
|
19 |
-
* This class
|
20 |
-
* alerts, there is also the function to clean up alerts.
|
21 |
*
|
22 |
* @package wsal
|
|
|
23 |
*/
|
24 |
class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
25 |
|
@@ -154,63 +154,4 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
154 |
// Notify system.
|
155 |
do_action( 'wsal_prune', $deleted_count, vsprintf( $result['sql'], $result['args'] ) );
|
156 |
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Get the promo id, to send each time a different promo,
|
160 |
-
* keeping the last id saved in the DB.
|
161 |
-
*
|
162 |
-
* @return integer $promoToSend - The array index.
|
163 |
-
*/
|
164 |
-
private function GetPromoAlert() {
|
165 |
-
$last_promo_sent_id = $this->plugin->GetGlobalSetting( 'promo-send-id' );
|
166 |
-
$last_promo_sent_id = empty( $last_promo_sent_id ) ? 0 : $last_promo_sent_id;
|
167 |
-
$promo_to_send = null;
|
168 |
-
$promo_alerts = $this->GetActivePromoText();
|
169 |
-
if ( ! empty( $promo_alerts ) ) {
|
170 |
-
$promo_to_send = isset( $promo_alerts[ $last_promo_sent_id ] ) ? $promo_alerts[ $last_promo_sent_id ] : $promo_alerts[0];
|
171 |
-
|
172 |
-
if ( $last_promo_sent_id < count( $promo_alerts ) - 1 ) {
|
173 |
-
$last_promo_sent_id++;
|
174 |
-
} else {
|
175 |
-
$last_promo_sent_id = 0;
|
176 |
-
}
|
177 |
-
$this->plugin->SetGlobalSetting( 'promo-send-id', $last_promo_sent_id );
|
178 |
-
}
|
179 |
-
return $promo_to_send;
|
180 |
-
}
|
181 |
-
|
182 |
-
/**
|
183 |
-
* Array of promo.
|
184 |
-
*
|
185 |
-
* @return array $promo_alerts - The array of promo.
|
186 |
-
*/
|
187 |
-
private function GetActivePromoText() {
|
188 |
-
$promo_alerts = array();
|
189 |
-
$promo_alerts[] = array(
|
190 |
-
'name' => 'Upgrade to Premium',
|
191 |
-
'message' => 'See who is logged in, create user productivity reports, get notified instantly via email of important changes, add search and much more. <strong>%1$s</strong> | <strong>%2$s</strong>',
|
192 |
-
);
|
193 |
-
$promo_alerts[] = array(
|
194 |
-
'name' => 'See Who is Logged In, receive Email Alerts, generate User Productivity Reports and more!',
|
195 |
-
'message' => 'Upgrade to premium and extend the plugin’s features with email alerts, reports tool, free-text based search, user logins and sessions management and more! <strong>%1$s</strong> | <strong>%2$s</strong>',
|
196 |
-
);
|
197 |
-
return $promo_alerts;
|
198 |
-
}
|
199 |
-
|
200 |
-
/**
|
201 |
-
* Check condition to show promo.
|
202 |
-
*
|
203 |
-
* @return integer|null - Counter alert.
|
204 |
-
*/
|
205 |
-
private function CheckPromoToShow() {
|
206 |
-
// If the package is free, show the promo.
|
207 |
-
if ( ! class_exists( 'WSAL_NP_Plugin' )
|
208 |
-
&& ! class_exists( 'WSAL_Ext_Plugin' )
|
209 |
-
&& ! class_exists( 'WSAL_Rep_Plugin' )
|
210 |
-
&& ! class_exists( 'WSAL_SearchExtension' )
|
211 |
-
&& ! class_exists( 'WSAL_UserSessions_Plugin' ) ) {
|
212 |
-
return 150;
|
213 |
-
}
|
214 |
-
return null;
|
215 |
-
}
|
216 |
}
|
16 |
/**
|
17 |
* Loggers Class.
|
18 |
*
|
19 |
+
* This class stores the logs in the database and there is also the function to clean up alerts.
|
|
|
20 |
*
|
21 |
* @package wsal
|
22 |
+
* @subpackage loggers
|
23 |
*/
|
24 |
class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
25 |
|
154 |
// Notify system.
|
155 |
do_action( 'wsal_prune', $deleted_count, vsprintf( $result['sql'], $result['args'] ) );
|
156 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
}
|
classes/MainWpApi.php
ADDED
@@ -0,0 +1,483 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handler for MainWP API endpoints.
|
5 |
+
*
|
6 |
+
* @package wsal
|
7 |
+
* @subpackage main-wp
|
8 |
+
* @since 4.4.0
|
9 |
+
*/
|
10 |
+
class WSAL_MainWpApi {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Instance of WpSecurityAuditLog.
|
14 |
+
*
|
15 |
+
* @var WpSecurityAuditLog
|
16 |
+
*/
|
17 |
+
protected $plugin;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Method: Constructor.
|
21 |
+
*
|
22 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
23 |
+
*/
|
24 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
25 |
+
$this->plugin = $plugin;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* MainWP API Handler.
|
30 |
+
*
|
31 |
+
* @param array $info – Information to return.
|
32 |
+
* @param array $post_data – Post data array from MainWP.
|
33 |
+
*
|
34 |
+
* @return mixed
|
35 |
+
* @since 3.2.5
|
36 |
+
*/
|
37 |
+
public function handle_callback( $info, $post_data ) {
|
38 |
+
if ( isset( $post_data['action'] ) ) {
|
39 |
+
switch ( $post_data['action'] ) {
|
40 |
+
case 'check_wsal':
|
41 |
+
return $this->handle_wsal_info_check();
|
42 |
+
|
43 |
+
case 'get_events':
|
44 |
+
$limit = isset( $post_data['events_count'] ) ? $post_data['events_count'] : false;
|
45 |
+
$offset = isset( $post_data['events_offset'] ) ? $post_data['events_offset'] : false;
|
46 |
+
$query_args = isset( $post_data['query_args'] ) ? $post_data['query_args'] : false;
|
47 |
+
return $this->get_events_data( $limit, $offset, $query_args );
|
48 |
+
|
49 |
+
case 'get_report':
|
50 |
+
$filters = isset( $post_data['filters'] ) ? $post_data['filters'] : array();
|
51 |
+
$report_type = isset( $post_data['report_type'] ) ? $post_data['report_type'] : false;
|
52 |
+
return $this->get_report_data( $filters, $report_type );
|
53 |
+
|
54 |
+
case 'latest_event':
|
55 |
+
// run the query and return it.
|
56 |
+
$event = $this->query_for_latest_event();
|
57 |
+
$event = $event->getAdapter()->Execute( $event );
|
58 |
+
|
59 |
+
// Set the return object.
|
60 |
+
if ( isset( $event[0] ) ) {
|
61 |
+
$info = new stdClass();
|
62 |
+
$info->alert_id = $event[0]->alert_id;
|
63 |
+
$info->created_on = $event[0]->created_on;
|
64 |
+
} else {
|
65 |
+
$info = false;
|
66 |
+
}
|
67 |
+
break;
|
68 |
+
case 'enforce_settings':
|
69 |
+
return $this->handle_settings_enforcement( $post_data );
|
70 |
+
|
71 |
+
case 'get_event_definitions':
|
72 |
+
return $this->get_event_definitions();
|
73 |
+
|
74 |
+
default:
|
75 |
+
break;
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
return $info;
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Handles API call requesting info about WSAL plugin.
|
84 |
+
*
|
85 |
+
* @return stdClass
|
86 |
+
* @since 4.4.0
|
87 |
+
*/
|
88 |
+
protected function handle_wsal_info_check() {
|
89 |
+
$info = new stdClass();
|
90 |
+
$info->wsal_installed = true;
|
91 |
+
$info->is_premium = false;
|
92 |
+
return $info;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Return alerts for MainWP Extension.
|
97 |
+
*
|
98 |
+
* @param integer $limit - Number of alerts to retrieve.
|
99 |
+
* @param int|bool $offset - Events offset, otherwise false.
|
100 |
+
* @param stdClass|bool $query_args - Events query arguments, otherwise false.
|
101 |
+
*
|
102 |
+
* @return stdClass
|
103 |
+
*/
|
104 |
+
public function get_events_data( $limit = 100, $offset = false, $query_args = false ) {
|
105 |
+
$mwp_events = new stdClass();
|
106 |
+
|
107 |
+
// Check if limit is not empty.
|
108 |
+
if ( empty( $limit ) ) {
|
109 |
+
return $mwp_events;
|
110 |
+
}
|
111 |
+
|
112 |
+
// Initiate query occurrence object.
|
113 |
+
$events_query = new WSAL_Models_OccurrenceQuery();
|
114 |
+
$events_query->addCondition( 'site_id = %s ', 1 ); // Set site id.
|
115 |
+
$events_query = $this->filter_query( $events_query, $query_args );
|
116 |
+
|
117 |
+
// Check query arguments.
|
118 |
+
if ( false !== $query_args ) {
|
119 |
+
if ( isset( $query_args['get_count'] ) && $query_args['get_count'] ) {
|
120 |
+
$mwp_events->total_items = $events_query->getAdapter()->Count( $events_query );
|
121 |
+
} else {
|
122 |
+
$mwp_events->total_items = false;
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
// Set order by.
|
127 |
+
$events_query->addOrderBy( 'created_on', true );
|
128 |
+
|
129 |
+
// Set the limit.
|
130 |
+
$events_query->setLimit( $limit );
|
131 |
+
|
132 |
+
// Set the offset.
|
133 |
+
if ( false !== $offset ) {
|
134 |
+
$events_query->setOffset( $offset );
|
135 |
+
}
|
136 |
+
|
137 |
+
// Execute the query.
|
138 |
+
/** @var \WSAL\MainWPExtension\Models\Occurrence[] $events */
|
139 |
+
$events = $events_query->getAdapter()->Execute( $events_query );
|
140 |
+
|
141 |
+
if ( ! empty( $events ) && is_array( $events ) ) {
|
142 |
+
foreach ( $events as $event ) {
|
143 |
+
// Get event meta.
|
144 |
+
$meta_data = $event->GetMetaArray();
|
145 |
+
$meta_data['UserData'] = $this->plugin->alerts->get_event_user_data( WSAL_Utilities_UsersUtils::GetUsername( $meta_data ) );
|
146 |
+
$mwp_events->events[ $event->id ] = new stdClass();
|
147 |
+
$mwp_events->events[ $event->id ]->id = $event->id;
|
148 |
+
$mwp_events->events[ $event->id ]->alert_id = $event->alert_id;
|
149 |
+
$mwp_events->events[ $event->id ]->created_on = $event->created_on;
|
150 |
+
$mwp_events->events[ $event->id ]->meta_data = $meta_data;
|
151 |
+
}
|
152 |
+
|
153 |
+
$mwp_events->users = $this->plugin->alerts->get_wp_users();
|
154 |
+
}
|
155 |
+
|
156 |
+
return $mwp_events;
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Filter query for MWPAL.
|
161 |
+
*
|
162 |
+
* @param WSAL_Models_OccurrenceQuery $query Events query.
|
163 |
+
* @param array $query_args Query args.
|
164 |
+
*
|
165 |
+
* @return WSAL_Models_OccurrenceQuery
|
166 |
+
*/
|
167 |
+
private function filter_query( $query, $query_args ) {
|
168 |
+
if ( isset( $query_args['search_term'] ) && $query_args['search_term'] ) {
|
169 |
+
$query->addSearchCondition( $query_args['search_term'] );
|
170 |
+
}
|
171 |
+
|
172 |
+
if ( ! empty( $query_args['search_filters'] ) ) {
|
173 |
+
// Get DB connection array.
|
174 |
+
$connection = $this->plugin->getConnector()->getAdapter( 'Occurrence' )->get_connection();
|
175 |
+
|
176 |
+
// Tables.
|
177 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $connection );
|
178 |
+
$table_meta = $meta->GetTable(); // Metadata.
|
179 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $connection );
|
180 |
+
$table_occ = $occurrence->GetTable(); // Occurrences.
|
181 |
+
|
182 |
+
foreach ( $query_args['search_filters'] as $prefix => $value ) {
|
183 |
+
if ( 'event' === $prefix ) {
|
184 |
+
$query->addORCondition( array( 'alert_id = %s' => $value ) );
|
185 |
+
} elseif ( in_array( $prefix, array( 'from', 'to', 'on' ), true ) ) {
|
186 |
+
$date = DateTime::createFromFormat( $this->sanitized_date_format, $value[0] );
|
187 |
+
$date->setTime( 0, 0 ); // Reset time to 00:00:00.
|
188 |
+
$date_string = $date->format( 'U' );
|
189 |
+
|
190 |
+
if ( 'from' === $prefix ) {
|
191 |
+
$query->addCondition( 'created_on >= %s', $date_string );
|
192 |
+
} elseif ( 'to' === $prefix ) {
|
193 |
+
$query->addCondition( 'created_on <= %s', strtotime( '+1 day -1 minute', $date_string ) );
|
194 |
+
} elseif ( 'on' === $prefix ) {
|
195 |
+
$query->addCondition( 'created_on >= %s', strtotime( '-1 day +1 day +1 second', $date_string ) );
|
196 |
+
$query->addCondition( 'created_on <= %s', strtotime( '+1 day -1 second', $date_string ) );
|
197 |
+
}
|
198 |
+
} elseif ( in_array( $prefix, array( 'username', 'firstname', 'lastname' ), true ) ) {
|
199 |
+
$users = array();
|
200 |
+
if ( 'username' === $prefix ) {
|
201 |
+
foreach ( $value as $username ) {
|
202 |
+
$user = get_user_by( 'login', $username );
|
203 |
+
if ( ! $user ) {
|
204 |
+
$user = get_user_by( 'slug', $username );
|
205 |
+
}
|
206 |
+
|
207 |
+
if ( $user ) {
|
208 |
+
array_push( $users, $user );
|
209 |
+
}
|
210 |
+
}
|
211 |
+
} elseif ( 'firstname' === $prefix || 'lastname' === $prefix ) {
|
212 |
+
|
213 |
+
$meta_key = 'firstname' === $prefix ? 'first_name' : ( 'lastname' === $prefix ? 'last_name' : false );
|
214 |
+
|
215 |
+
foreach ( $value as $name ) {
|
216 |
+
$users_array = get_users(
|
217 |
+
array(
|
218 |
+
'meta_key' => $meta_key,
|
219 |
+
'meta_value' => $name,
|
220 |
+
'fields' => array( 'ID', 'user_login' ),
|
221 |
+
'meta_compare' => 'LIKE',
|
222 |
+
)
|
223 |
+
);
|
224 |
+
|
225 |
+
foreach ( $users_array as $user ) {
|
226 |
+
array_push( $users, $user );
|
227 |
+
}
|
228 |
+
}
|
229 |
+
}
|
230 |
+
|
231 |
+
if ( ! empty( $users ) ) {
|
232 |
+
global $wpdb;
|
233 |
+
$usernames = wp_list_pluck( $users, 'user_login' );
|
234 |
+
$placeholders_string = implode( ', ', array_fill( 0, count( $usernames ), '%s' ) );
|
235 |
+
|
236 |
+
$sql = $wpdb->prepare( 'username IN ( ' . $placeholders_string . ' ) ', $usernames );
|
237 |
+
|
238 |
+
$user_ids = wp_list_pluck( $users, 'ID' );
|
239 |
+
$placeholders_string = implode( ', ', array_fill( 0, count( $user_ids ), '%d' ) );
|
240 |
+
|
241 |
+
$sql .= ' OR ' . $wpdb->prepare( 'user_id IN ( ' . $placeholders_string . ' ) ', $user_ids );
|
242 |
+
$query->addORCondition( array( $sql => '' ) );
|
243 |
+
}
|
244 |
+
} elseif ( 'userrole' === $prefix ) {
|
245 |
+
// User role search condition.
|
246 |
+
$sql = "$table_occ.user_role replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP %s )";
|
247 |
+
$value = implode( '|', $value );
|
248 |
+
$query->addORCondition( array( $sql => $value ) );
|
249 |
+
} elseif ( 'postname' === $prefix ) {
|
250 |
+
|
251 |
+
$sql = "$table_occ.id IN ( SELECT occurrence_id FROM $table_meta as meta WHERE meta.name='PostTitle' AND ( ";
|
252 |
+
$value = array_map( array( $this, 'add_string_wildcards' ), $value );
|
253 |
+
|
254 |
+
// Get the last value.
|
255 |
+
$last_value = end( $value );
|
256 |
+
|
257 |
+
foreach ( $value as $column_name ) {
|
258 |
+
if ( $last_value === $column_name ) {
|
259 |
+
continue;
|
260 |
+
}
|
261 |
+
$sql .= "( (meta.value LIKE '$column_name') > 0 ) OR ";
|
262 |
+
}
|
263 |
+
|
264 |
+
// Add placeholder for the last value.
|
265 |
+
$sql .= "( (meta.value LIKE '%s') > 0 ) ) )";
|
266 |
+
|
267 |
+
$query->addORCondition( array( $sql => $last_value ) );
|
268 |
+
} elseif ( in_array( $prefix, array( 'posttype', 'poststatus', 'postid' ), true ) ) {
|
269 |
+
$column_name = '';
|
270 |
+
if ( 'posttype' === $prefix ) {
|
271 |
+
$column_name = 'post_type';
|
272 |
+
} elseif ( 'poststatus' === $prefix ) {
|
273 |
+
$column_name = 'post_status';
|
274 |
+
} elseif ( 'postid' === $prefix ) {
|
275 |
+
$column_name = 'post_id';
|
276 |
+
}
|
277 |
+
|
278 |
+
$sql = " {$column_name} = %s ";
|
279 |
+
$query->addORCondition( array( $sql => $value ) );
|
280 |
+
} elseif ( 'ip' === $prefix ) {
|
281 |
+
// IP search condition.
|
282 |
+
$sql = "$table_occ.client_ip = %s ";
|
283 |
+
$query->addORCondition( array( $sql => $value ) );
|
284 |
+
}
|
285 |
+
}
|
286 |
+
}
|
287 |
+
|
288 |
+
return $query;
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Generate report matching the filter passed.
|
293 |
+
*
|
294 |
+
* @param array $filters - Filters.
|
295 |
+
* @param mixed $report_type - Type of report.
|
296 |
+
*
|
297 |
+
* @return stdClass
|
298 |
+
*
|
299 |
+
* @since 4.4.0 Removed support for report type "statistics_unique_ips".
|
300 |
+
*/
|
301 |
+
public function get_report_data( array $filters, $report_type ) {
|
302 |
+
$report = new stdClass();
|
303 |
+
$report->data = array();
|
304 |
+
|
305 |
+
if ( 'statistics_unique_ips' === $report_type ) {
|
306 |
+
// Support for this report was removed in version 4.4.0, but we still returned empty dataset to avoid issues
|
307 |
+
// in the MainWP extension.
|
308 |
+
return $report;
|
309 |
+
}
|
310 |
+
|
311 |
+
do {
|
312 |
+
$response = $this->generate_report( $filters );
|
313 |
+
|
314 |
+
if ( isset( $response['data'] ) ) {
|
315 |
+
$report->data = array_merge( $report->data, $response['data'] );
|
316 |
+
}
|
317 |
+
|
318 |
+
// Set the filters next date.
|
319 |
+
$filters['nextDate'] = ( isset( $response['lastDate'] ) && $response['lastDate'] ) ? $response['lastDate'] : 0;
|
320 |
+
} while ( $filters['nextDate'] );
|
321 |
+
|
322 |
+
return $report;
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Performs a query to retrieve the latest event in the logs.
|
327 |
+
*
|
328 |
+
* @return array
|
329 |
+
* @since 4.0.3
|
330 |
+
*/
|
331 |
+
public function query_for_latest_event() {
|
332 |
+
$event_query = new WSAL_Models_OccurrenceQuery();
|
333 |
+
// order by creation.
|
334 |
+
$event_query->addOrderBy( 'created_on', true );
|
335 |
+
// only request 1 item.
|
336 |
+
$event_query->setLimit( 1 );
|
337 |
+
|
338 |
+
return $event_query;
|
339 |
+
}
|
340 |
+
|
341 |
+
/**
|
342 |
+
* Handles API call enforcing certain WSAL settings.
|
343 |
+
*
|
344 |
+
* @param array $post_data Received request data.
|
345 |
+
*
|
346 |
+
* @return string[]
|
347 |
+
* @since 4.4.0
|
348 |
+
*/
|
349 |
+
private function handle_settings_enforcement( $post_data ) {
|
350 |
+
// Check subaction.
|
351 |
+
if ( ! array_key_exists( 'subaction', $post_data ) || empty( $post_data['subaction'] ) ) {
|
352 |
+
return array(
|
353 |
+
'success' => 'no',
|
354 |
+
'message' => 'Missing subaction parameter.',
|
355 |
+
);
|
356 |
+
}
|
357 |
+
|
358 |
+
$subaction = filter_var( $post_data['subaction'], FILTER_SANITIZE_STRING );
|
359 |
+
if ( ! in_array( $subaction, array( 'update', 'remove' ), true ) ) {
|
360 |
+
return array(
|
361 |
+
'success' => 'no',
|
362 |
+
'message' => 'Unsupported subaction parameter value.',
|
363 |
+
);
|
364 |
+
}
|
365 |
+
|
366 |
+
if ( 'update' === $subaction ) {
|
367 |
+
// Store the enforced settings in local database (used for example to disable related parts
|
368 |
+
// of the settings UI).
|
369 |
+
$settings_to_enforce = $post_data['settings'];
|
370 |
+
$this->plugin->settings()->set_mainwp_enforced_settings( $settings_to_enforce );
|
371 |
+
|
372 |
+
// Change the existing settings.
|
373 |
+
if ( array_key_exists( 'pruning_enabled', $settings_to_enforce ) ) {
|
374 |
+
$this->plugin->settings()->SetPruningDateEnabled( $settings_to_enforce['pruning_enabled'] );
|
375 |
+
if ( array_key_exists( 'pruning_date', $settings_to_enforce ) && array_key_exists( 'pruning_unit', $settings_to_enforce ) ) {
|
376 |
+
$this->plugin->settings()->SetPruningDate( $settings_to_enforce['pruning_date'] . ' ' . $settings_to_enforce['pruning_unit'] );
|
377 |
+
$this->plugin->settings()->set_pruning_unit( $settings_to_enforce['pruning_unit'] );
|
378 |
+
}
|
379 |
+
}
|
380 |
+
|
381 |
+
if ( array_key_exists( 'disabled_events', $settings_to_enforce ) ) {
|
382 |
+
$disabled_event_ids = array_map( 'intval', explode( ',', $settings_to_enforce['disabled_events'] ) );
|
383 |
+
$this->plugin->alerts->SetDisabledAlerts( $disabled_event_ids );
|
384 |
+
}
|
385 |
+
|
386 |
+
if ( array_key_exists( 'incognito_mode_enabled', $settings_to_enforce ) ) {
|
387 |
+
$this->plugin->settings()->SetIncognito( $settings_to_enforce['incognito_mode_enabled'] );
|
388 |
+
}
|
389 |
+
|
390 |
+
if ( array_key_exists( 'login_notification_enabled', $settings_to_enforce ) ) {
|
391 |
+
$login_page_notification_enabled = $settings_to_enforce['login_notification_enabled'];
|
392 |
+
$this->plugin->settings()->set_login_page_notification( $login_page_notification_enabled );
|
393 |
+
if ( 'yes' === $login_page_notification_enabled ) {
|
394 |
+
$this->plugin->settings()->set_login_page_notification_text( $settings_to_enforce['login_notification_text'] );
|
395 |
+
}
|
396 |
+
}
|
397 |
+
} elseif ( 'remove' === $subaction ) {
|
398 |
+
$this->plugin->settings()->delete_mainwp_enforced_settings();
|
399 |
+
}
|
400 |
+
|
401 |
+
$this->plugin->alerts->Trigger( 6043 );
|
402 |
+
|
403 |
+
return array(
|
404 |
+
'success' => 'yes',
|
405 |
+
);
|
406 |
+
}
|
407 |
+
|
408 |
+
/**
|
409 |
+
* Generates report for MainWP extension.
|
410 |
+
*
|
411 |
+
* @param array $filters - Filters.
|
412 |
+
*
|
413 |
+
* @return array
|
414 |
+
*/
|
415 |
+
private function generate_report( $filters ) {
|
416 |
+
// Check the report format.
|
417 |
+
$report_format = empty( $filters['report-format'] ) ? 'html' : $filters['report-format'];
|
418 |
+
if ( ! in_array( $report_format, array( 'csv', 'html' ), true ) ) {
|
419 |
+
$report_format = WSAL_Rep_DataFormat::get_default();
|
420 |
+
}
|
421 |
+
|
422 |
+
// Alert codes filter needs to renamed to work correctly with further report processing.
|
423 |
+
if ( array_key_exists( 'alert-codes', $filters ) ) {
|
424 |
+
$filters['alert_codes'] = $filters['alert-codes'];
|
425 |
+
unset( $filters['alert-codes'] );
|
426 |
+
}
|
427 |
+
|
428 |
+
$args = WSAL_ReportArgs::build_from_alternative_filters( $filters );
|
429 |
+
$next_date = empty( $filters['nextDate'] ) ? null : $filters['nextDate'];
|
430 |
+
$limit = empty( $filters['limit'] ) ? 0 : $filters['limit'];
|
431 |
+
$last_date = null;
|
432 |
+
|
433 |
+
$results = $this->plugin->getConnector()->getAdapter( 'Occurrence' )->get_report_data( $args, $next_date, $limit );
|
434 |
+
|
435 |
+
if ( ! empty( $results['lastDate'] ) ) {
|
436 |
+
$last_date = $results['lastDate'];
|
437 |
+
unset( $results['lastDate'] );
|
438 |
+
}
|
439 |
+
|
440 |
+
if ( empty( $results ) ) {
|
441 |
+
return false;
|
442 |
+
}
|
443 |
+
|
444 |
+
$data = array();
|
445 |
+
|
446 |
+
// Get alert details.
|
447 |
+
foreach ( $results as $entry ) {
|
448 |
+
if ( 9999 === (int) $entry->alert_id ) {
|
449 |
+
continue;
|
450 |
+
}
|
451 |
+
|
452 |
+
array_push( $data, $this->plugin->alerts->get_alert_details( $entry, 'report-' . $report_format ) );
|
453 |
+
}
|
454 |
+
|
455 |
+
if ( empty( $data ) ) {
|
456 |
+
return false;
|
457 |
+
}
|
458 |
+
|
459 |
+
return array(
|
460 |
+
'data' => $data,
|
461 |
+
'filters' => $filters,
|
462 |
+
'lastDate' => $last_date,
|
463 |
+
);
|
464 |
+
}
|
465 |
+
|
466 |
+
/**
|
467 |
+
* Retrieves the events definitions along with some other related pieces of information, such as event object and
|
468 |
+
* event type labels.
|
469 |
+
*
|
470 |
+
* @return array Events definitions data.
|
471 |
+
*
|
472 |
+
* @since 4.4.0
|
473 |
+
*/
|
474 |
+
private function get_event_definitions() {
|
475 |
+
$alert_manager = $this->plugin->alerts;
|
476 |
+
|
477 |
+
return array(
|
478 |
+
'events' => $alert_manager->GetAlerts(),
|
479 |
+
'objects' => $alert_manager->get_event_objects_data(),
|
480 |
+
'types' => $alert_manager->get_event_type_data(),
|
481 |
+
);
|
482 |
+
}
|
483 |
+
}
|
classes/Models/ActiveRecord.php
CHANGED
@@ -41,6 +41,15 @@ abstract class WSAL_Models_ActiveRecord {
|
|
41 |
*/
|
42 |
protected $id = false;
|
43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
/**
|
45 |
* Adapter Name.
|
46 |
*
|
@@ -53,7 +62,7 @@ abstract class WSAL_Models_ActiveRecord {
|
|
53 |
*
|
54 |
* @var boolean
|
55 |
*/
|
56 |
-
protected $
|
57 |
|
58 |
/**
|
59 |
* Record State.
|
@@ -129,7 +138,8 @@ abstract class WSAL_Models_ActiveRecord {
|
|
129 |
if ( ! empty( $this->connector ) ) {
|
130 |
return $this->connector;
|
131 |
}
|
132 |
-
|
|
|
133 |
$this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
|
134 |
} else {
|
135 |
$this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
|
@@ -141,14 +151,29 @@ abstract class WSAL_Models_ActiveRecord {
|
|
141 |
* Gets an adapter for the specified model
|
142 |
* based on the adapter name.
|
143 |
*
|
144 |
-
* @see WSAL_Connector_ConnectorInterface::getAdapter()
|
145 |
-
*
|
146 |
* @return WSAL_Adapters_ActiveRecordInterface
|
147 |
*/
|
148 |
public function getAdapter() {
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
return $this->getConnector()->getAdapter( $this->adapterName );
|
150 |
}
|
151 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
/**
|
153 |
* Load record from DB.
|
154 |
*
|
@@ -166,6 +191,37 @@ abstract class WSAL_Models_ActiveRecord {
|
|
166 |
}
|
167 |
}
|
168 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
/**
|
170 |
* Load object data from variable.
|
171 |
*
|
@@ -177,30 +233,7 @@ abstract class WSAL_Models_ActiveRecord {
|
|
177 |
$copy = new $copy();
|
178 |
foreach ( (array) $data as $key => $val ) {
|
179 |
if ( isset( $copy->$key ) ) {
|
180 |
-
|
181 |
-
case $this->is_ip_address( $val ):
|
182 |
-
$this->$key = (string) $val;
|
183 |
-
break;
|
184 |
-
case is_array( $copy->$key ):
|
185 |
-
case is_object( $copy->$key ):
|
186 |
-
$json_decoded_val = WSAL_Helpers_DataHelper::JsonDecode( $val );
|
187 |
-
$this->$key = ( null == $json_decoded_val ) ? $val : $json_decoded_val;
|
188 |
-
break;
|
189 |
-
case is_int( $copy->$key ):
|
190 |
-
$this->$key = (int) $val;
|
191 |
-
break;
|
192 |
-
case is_float( $copy->$key ):
|
193 |
-
$this->$key = (float) $val;
|
194 |
-
break;
|
195 |
-
case is_bool( $copy->$key ):
|
196 |
-
$this->$key = (bool) $val;
|
197 |
-
break;
|
198 |
-
case is_string( $copy->$key ):
|
199 |
-
$this->$key = (string) $val;
|
200 |
-
break;
|
201 |
-
default:
|
202 |
-
throw new Exception( 'Unsupported type "' . gettype( $copy->$key ) . '"' );
|
203 |
-
}
|
204 |
}
|
205 |
}
|
206 |
return $this;
|
@@ -357,27 +390,4 @@ abstract class WSAL_Models_ActiveRecord {
|
|
357 |
protected static function CacheClear() {
|
358 |
self::$_cache = array();
|
359 |
}
|
360 |
-
|
361 |
-
/**
|
362 |
-
* Function used in WSAL reporting extension.
|
363 |
-
*
|
364 |
-
* @param WSAL_ReportArgs $report_args
|
365 |
-
*
|
366 |
-
* @return array Report results.
|
367 |
-
* @see WSAL_Adapters_MySQL_ActiveRecord::GetReporting()
|
368 |
-
*/
|
369 |
-
public function GetReporting( $report_args ) {
|
370 |
-
return $this->getAdapter()->GetReporting( $report_args );
|
371 |
-
}
|
372 |
-
|
373 |
-
/**
|
374 |
-
* Check if the float is IPv4 instead.
|
375 |
-
*
|
376 |
-
* @see WSAL_Models_ActiveRecord::LoadData()
|
377 |
-
* @param float $ip_address - Number to check.
|
378 |
-
* @return bool result validation
|
379 |
-
*/
|
380 |
-
private function is_ip_address( $ip_address ) {
|
381 |
-
return filter_var( $ip_address, FILTER_VALIDATE_IP ) !== false;
|
382 |
-
}
|
383 |
}
|
41 |
*/
|
42 |
protected $id = false;
|
43 |
|
44 |
+
/**
|
45 |
+
* This property is used in conjunction with its setter method to force an adapter used by this record. It completely
|
46 |
+
* bypasses the default way of creating the adapter using its name and a connector returned by function getConnector.
|
47 |
+
*
|
48 |
+
* @var WSAL_Adapters_ActiveRecordInterface
|
49 |
+
* @since 4.4.0
|
50 |
+
*/
|
51 |
+
protected $adapter = null;
|
52 |
+
|
53 |
/**
|
54 |
* Adapter Name.
|
55 |
*
|
62 |
*
|
63 |
* @var boolean
|
64 |
*/
|
65 |
+
protected $use_default_adapter = false;
|
66 |
|
67 |
/**
|
68 |
* Record State.
|
138 |
if ( ! empty( $this->connector ) ) {
|
139 |
return $this->connector;
|
140 |
}
|
141 |
+
|
142 |
+
if ( $this->use_default_adapter ) {
|
143 |
$this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
|
144 |
} else {
|
145 |
$this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
|
151 |
* Gets an adapter for the specified model
|
152 |
* based on the adapter name.
|
153 |
*
|
|
|
|
|
154 |
* @return WSAL_Adapters_ActiveRecordInterface
|
155 |
*/
|
156 |
public function getAdapter() {
|
157 |
+
// use forcefully set adapter if set
|
158 |
+
if ( ! empty( $this->adapter ) ) {
|
159 |
+
return $this->adapter;
|
160 |
+
}
|
161 |
+
|
162 |
+
// create adapter using the connector returned from getConnector method
|
163 |
return $this->getConnector()->getAdapter( $this->adapterName );
|
164 |
}
|
165 |
|
166 |
+
/**
|
167 |
+
* Allows the database adapter to be set from the outside. This is useful during data migrations.
|
168 |
+
*
|
169 |
+
* @param WSAL_Adapters_ActiveRecordInterface $adapter
|
170 |
+
*
|
171 |
+
* @since 4.4.0
|
172 |
+
*/
|
173 |
+
public function setAdapter( $adapter ) {
|
174 |
+
$this->adapter = $adapter;
|
175 |
+
}
|
176 |
+
|
177 |
/**
|
178 |
* Load record from DB.
|
179 |
*
|
191 |
}
|
192 |
}
|
193 |
|
194 |
+
/**
|
195 |
+
* Casts given value to a correct type based on the type of property (identified by the $key) in the $copy object.
|
196 |
+
* This is to allow automatic type casting instead of handling each database column individually.
|
197 |
+
*
|
198 |
+
* @param object $copy
|
199 |
+
* @param string $key
|
200 |
+
* @param mixed $val
|
201 |
+
*
|
202 |
+
* @return mixed
|
203 |
+
* @throws Exception
|
204 |
+
*/
|
205 |
+
protected function cast_to_correct_type( $copy, $key, $val ){
|
206 |
+
switch ( true ) {
|
207 |
+
case is_string( $copy->$key ):
|
208 |
+
case WSAL_Utilities_RequestUtils::is_ip_address( $val ):
|
209 |
+
return (string) $val;
|
210 |
+
case is_array( $copy->$key ):
|
211 |
+
case is_object( $copy->$key ):
|
212 |
+
$json_decoded_val = WSAL_Helpers_DataHelper::JsonDecode( $val );
|
213 |
+
return is_null( $json_decoded_val ) ? $val : $json_decoded_val;
|
214 |
+
case is_int( $copy->$key ):
|
215 |
+
return (int) $val;
|
216 |
+
case is_float( $copy->$key ):
|
217 |
+
return (float) $val;
|
218 |
+
case is_bool( $copy->$key ):
|
219 |
+
return (bool) $val;
|
220 |
+
default:
|
221 |
+
throw new Exception( 'Unsupported type "' . gettype( $copy->$key ) . '"' );
|
222 |
+
}
|
223 |
+
}
|
224 |
+
|
225 |
/**
|
226 |
* Load object data from variable.
|
227 |
*
|
233 |
$copy = new $copy();
|
234 |
foreach ( (array) $data as $key => $val ) {
|
235 |
if ( isset( $copy->$key ) ) {
|
236 |
+
$this->$key = $this->cast_to_correct_type($copy, $key, $val);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
}
|
238 |
}
|
239 |
return $this;
|
390 |
protected static function CacheClear() {
|
391 |
self::$_cache = array();
|
392 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
393 |
}
|
classes/Models/Meta.php
CHANGED
@@ -80,9 +80,9 @@ class WSAL_Models_Meta extends WSAL_Models_ActiveRecord {
|
|
80 |
* @param mixed $value - Meta value.
|
81 |
* @param integer $occurrence_id - Occurrence_id.
|
82 |
*
|
83 |
-
|
84 |
*/
|
85 |
-
public function
|
86 |
$meta = $this->getAdapter()->LoadByNameAndOccurrenceId( $name, $occurrence_id );
|
87 |
if ( ! empty( $meta ) ) {
|
88 |
$this->id = $meta['id'];
|
80 |
* @param mixed $value - Meta value.
|
81 |
* @param integer $occurrence_id - Occurrence_id.
|
82 |
*
|
83 |
+
* @see WSAL_Adapters_MySQL_Meta::LoadByNameAndOccurrenceId()
|
84 |
*/
|
85 |
+
public function UpdateByNameAndOccurrenceId( $name, $value, $occurrence_id ) {
|
86 |
$meta = $this->getAdapter()->LoadByNameAndOccurrenceId( $name, $occurrence_id );
|
87 |
if ( ! empty( $meta ) ) {
|
88 |
$this->id = $meta['id'];
|
classes/Models/Occurrence.php
CHANGED
@@ -21,6 +21,21 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
21 |
*/
|
22 |
class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
/**
|
25 |
* Occurrence ID.
|
26 |
*
|
@@ -50,20 +65,100 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
50 |
public $created_on = 0.0;
|
51 |
|
52 |
/**
|
53 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
*
|
55 |
-
* @var
|
56 |
-
* @
|
57 |
*/
|
58 |
-
public $
|
59 |
|
60 |
/**
|
61 |
-
*
|
62 |
*
|
63 |
-
* @var
|
64 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
*/
|
66 |
-
public $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
|
68 |
/**
|
69 |
* Model Name.
|
@@ -103,50 +198,84 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
103 |
* @see WSAL_Adapters_MySQL_Occurrence::GetNamedMeta()
|
104 |
*/
|
105 |
public function GetMetaValue( $name, $default = array() ) {
|
106 |
-
|
107 |
-
|
108 |
-
if
|
109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
}
|
111 |
|
112 |
-
return
|
113 |
}
|
114 |
|
115 |
/**
|
116 |
* Sets the value of a meta item (creates or updates meta item).
|
117 |
*
|
118 |
* @param string $name - Meta name.
|
119 |
-
* @param mixed
|
120 |
*/
|
121 |
public function SetMetaValue( $name, $value ) {
|
122 |
// check explicitly for `0` string values.
|
123 |
if ( '0' === $value || ! empty( $value ) ) {
|
124 |
-
//
|
125 |
-
$
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
}
|
131 |
}
|
132 |
|
133 |
/**
|
134 |
* Update Metadata of this occurrence by name.
|
135 |
*
|
136 |
-
* @see WSAL_Models_Meta::UpdateByNameAndOccurenceId()
|
137 |
* @param string $name - Meta name.
|
138 |
-
* @param mixed
|
|
|
|
|
139 |
*/
|
140 |
public function UpdateMetaValue( $name, $value ) {
|
141 |
$model = new WSAL_Models_Meta();
|
142 |
-
$model->
|
143 |
}
|
144 |
|
145 |
/**
|
146 |
-
* Returns a key-value pair of
|
147 |
*
|
148 |
-
* @see WSAL_Adapters_MySQL_Occurrence::GetMultiMeta()
|
149 |
* @return array
|
|
|
150 |
*/
|
151 |
public function GetMetaArray() {
|
152 |
$result = array();
|
@@ -154,11 +283,16 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
154 |
foreach ( $metas as $meta ) {
|
155 |
$result[ $meta->name ] = maybe_unserialize( $meta->value );
|
156 |
}
|
|
|
|
|
|
|
|
|
|
|
157 |
return $result;
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
-
* Creates or updates all
|
162 |
*
|
163 |
* @param array $data - New meta data.
|
164 |
*/
|
@@ -166,6 +300,9 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
166 |
foreach ( (array) $data as $key => $val ) {
|
167 |
$this->SetMetaValue( $key, $val );
|
168 |
}
|
|
|
|
|
|
|
169 |
}
|
170 |
|
171 |
/**
|
@@ -190,24 +327,6 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
190 |
if ( null !== $alert_object && method_exists( $alert_object, 'GetMessage' ) ) {
|
191 |
$this->_cachedMessage = $alert_object->GetMessage( $meta_array, $this->_cachedMessage, $this->getId(), $context );
|
192 |
} else {
|
193 |
-
/**
|
194 |
-
* Reaching this point means we have an event we don't know
|
195 |
-
* about. It could be a custom event or possibly a removed
|
196 |
-
* event.
|
197 |
-
*
|
198 |
-
* We currently have 2 sets of custom events that we can flag
|
199 |
-
* specific messages about. WPForms and BBPress. Both are
|
200 |
-
* available as plugin add-ons.
|
201 |
-
*
|
202 |
-
* @since 4.0.2
|
203 |
-
*/
|
204 |
-
$addon_event_codes = array(
|
205 |
-
'wfcm' => array(
|
206 |
-
'name' => __( 'WFCM', 'wp-security-audit-log' ),
|
207 |
-
'event_ids' => array( 6028, 6029, 6030, 6031, 6032, 6033 ),
|
208 |
-
),
|
209 |
-
);
|
210 |
-
|
211 |
// Filter to allow items to be added elsewhere.
|
212 |
$addon_event_codes = apply_filters( 'wsal_addon_event_codes', $addon_event_codes );
|
213 |
|
@@ -244,7 +363,9 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
244 |
* @return boolean True on success, false on failure.
|
245 |
*/
|
246 |
public function Delete() {
|
247 |
-
|
|
|
|
|
248 |
$meta->Delete();
|
249 |
}
|
250 |
return parent::Delete();
|
@@ -264,14 +385,10 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
264 |
/**
|
265 |
* Gets the Client IP.
|
266 |
*
|
267 |
-
* @param array $meta - Occurrence meta array.
|
268 |
* @return string IP address of request.
|
269 |
*/
|
270 |
-
public function GetSourceIP(
|
271 |
-
|
272 |
-
return $this->GetMetaValue( 'ClientIP', '' );
|
273 |
-
}
|
274 |
-
return isset( $meta['ClientIP'] ) ? $meta['ClientIP'] : '';
|
275 |
}
|
276 |
|
277 |
/**
|
@@ -293,14 +410,14 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
293 |
/**
|
294 |
* Gets user roles.
|
295 |
*
|
296 |
-
* @param array $meta - Occurrence meta array.
|
297 |
* @return array Array of user roles.
|
298 |
*/
|
299 |
-
public function GetUserRoles(
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
|
|
304 |
}
|
305 |
|
306 |
/**
|
@@ -338,8 +455,8 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
338 |
* @param array $args - Query args.
|
339 |
* @return WSAL_Models_Occurrence[]
|
340 |
*/
|
341 |
-
public function
|
342 |
-
return $this->getAdapter()->
|
343 |
}
|
344 |
|
345 |
/**
|
@@ -362,4 +479,34 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
362 |
public function GetByPostID( $post_id ) {
|
363 |
return $this->getAdapter()->GetByPostID( $post_id );
|
364 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
365 |
}
|
21 |
*/
|
22 |
class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
23 |
|
24 |
+
public static $migrated_meta = array(
|
25 |
+
'ClientIP' => 'client_ip',
|
26 |
+
'Severity' => 'severity',
|
27 |
+
'Object' => 'object',
|
28 |
+
'EventType' => 'event_type',
|
29 |
+
'UserAgent' => 'user_agent',
|
30 |
+
'CurrentUserRoles' => 'user_roles',
|
31 |
+
'Username' => 'username',
|
32 |
+
'CurrentUserID' => 'user_id',
|
33 |
+
'SessionID' => 'session_id',
|
34 |
+
'PostStatus' => 'post_status',
|
35 |
+
'PostType' => 'post_type',
|
36 |
+
'PostID' => 'post_id'
|
37 |
+
);
|
38 |
+
|
39 |
/**
|
40 |
* Occurrence ID.
|
41 |
*
|
65 |
public $created_on = 0.0;
|
66 |
|
67 |
/**
|
68 |
+
* Client IP address.
|
69 |
+
*
|
70 |
+
* @var string
|
71 |
+
* @since 4.4.0
|
72 |
+
*/
|
73 |
+
public $client_ip = '';
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Severity.
|
77 |
*
|
78 |
+
* @var int
|
79 |
+
* @since 4.4.0
|
80 |
*/
|
81 |
+
public $severity = '';
|
82 |
|
83 |
/**
|
84 |
+
* Event object.
|
85 |
*
|
86 |
+
* @var string
|
87 |
+
* @since 4.4.0
|
88 |
+
*/
|
89 |
+
public $object = '';
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Event type.
|
93 |
+
*
|
94 |
+
* @var string
|
95 |
+
* @since 4.4.0
|
96 |
*/
|
97 |
+
public $event_type = '';
|
98 |
+
|
99 |
+
/**
|
100 |
+
* User agent string.
|
101 |
+
*
|
102 |
+
* @var string
|
103 |
+
* @since 4.4.0
|
104 |
+
*/
|
105 |
+
public $user_agent = '';
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Comma separated user roles of the user belonging to the event.
|
109 |
+
*
|
110 |
+
* @var string
|
111 |
+
* @since 4.4.0
|
112 |
+
*/
|
113 |
+
public $user_roles = '';
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Username of the user belonging to the event.
|
117 |
+
*
|
118 |
+
* @var string
|
119 |
+
* @since 4.4.0
|
120 |
+
*/
|
121 |
+
public $username = null;
|
122 |
+
|
123 |
+
/**
|
124 |
+
* User ID of the user belonging to the event.
|
125 |
+
*
|
126 |
+
* @var int
|
127 |
+
* @since 4.4.0
|
128 |
+
*/
|
129 |
+
public $user_id = null;
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Session ID.
|
133 |
+
*
|
134 |
+
* @var string
|
135 |
+
* @since 4.4.0
|
136 |
+
*/
|
137 |
+
public $session_id = '';
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Post status.
|
141 |
+
*
|
142 |
+
* @var string
|
143 |
+
* @since 4.4.0
|
144 |
+
*/
|
145 |
+
public $post_status = '';
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Post status.
|
149 |
+
*
|
150 |
+
* @var string
|
151 |
+
* @since 4.4.0
|
152 |
+
*/
|
153 |
+
public $post_type = '';
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Post ID.
|
157 |
+
*
|
158 |
+
* @var int
|
159 |
+
* @since 4.4.0
|
160 |
+
*/
|
161 |
+
public $post_id = 0;
|
162 |
|
163 |
/**
|
164 |
* Model Name.
|
198 |
* @see WSAL_Adapters_MySQL_Occurrence::GetNamedMeta()
|
199 |
*/
|
200 |
public function GetMetaValue( $name, $default = array() ) {
|
201 |
+
$result = $default;
|
202 |
+
|
203 |
+
// check if the meta is part of the occurrences table
|
204 |
+
if ( in_array( $name, array_keys( self::$migrated_meta ) ) ) {
|
205 |
+
$property_name = self::$migrated_meta[ $name ];
|
206 |
+
if ( property_exists( $this, $property_name ) ) {
|
207 |
+
$result = $this->$property_name;
|
208 |
+
}
|
209 |
+
} else {
|
210 |
+
// Get meta adapter.
|
211 |
+
$meta = $this->getAdapter()->GetNamedMeta( $this, $name );
|
212 |
+
if ( is_null( $meta ) || ! array_key_exists( 'value', $meta ) ) {
|
213 |
+
return $default;
|
214 |
+
}
|
215 |
+
|
216 |
+
$result = $meta['value'];
|
217 |
+
}
|
218 |
+
|
219 |
+
$result = maybe_unserialize( $result );
|
220 |
+
if ( 'CurrentUserRoles' === $name && is_string( $result ) ) {
|
221 |
+
$result = preg_replace( '/[\[\]"]/', '', $result );
|
222 |
+
$result = explode( ',', $result );
|
223 |
}
|
224 |
|
225 |
+
return $result;
|
226 |
}
|
227 |
|
228 |
/**
|
229 |
* Sets the value of a meta item (creates or updates meta item).
|
230 |
*
|
231 |
* @param string $name - Meta name.
|
232 |
+
* @param mixed $value - Meta value.
|
233 |
*/
|
234 |
public function SetMetaValue( $name, $value ) {
|
235 |
// check explicitly for `0` string values.
|
236 |
if ( '0' === $value || ! empty( $value ) ) {
|
237 |
+
// check if the meta is part of the occurrences table
|
238 |
+
if ( in_array( $name, array_keys( self::$migrated_meta ) ) ) {
|
239 |
+
$property_name = self::$migrated_meta[ $name ];
|
240 |
+
if ( property_exists( $this, $property_name ) ) {
|
241 |
+
if ( 'CurrentUserRoles' === $name ) {
|
242 |
+
$value = maybe_unserialize( $value );
|
243 |
+
if ( is_array( $value ) && ! empty( $value ) ) {
|
244 |
+
$this->$property_name = implode( ',', $value );
|
245 |
+
}
|
246 |
+
} else {
|
247 |
+
$this->$property_name = $value;
|
248 |
+
}
|
249 |
+
}
|
250 |
+
} else {
|
251 |
+
// Get meta adapter.
|
252 |
+
$model = new WSAL_Models_Meta();
|
253 |
+
$model->occurrence_id = $this->getId();
|
254 |
+
$model->name = $name;
|
255 |
+
$model->value = maybe_serialize( $value );
|
256 |
+
$model->SaveMeta();
|
257 |
+
}
|
258 |
}
|
259 |
}
|
260 |
|
261 |
/**
|
262 |
* Update Metadata of this occurrence by name.
|
263 |
*
|
|
|
264 |
* @param string $name - Meta name.
|
265 |
+
* @param mixed $value - Meta value.
|
266 |
+
*
|
267 |
+
*@see WSAL_Models_Meta::UpdateByNameAndOccurrenceId()
|
268 |
*/
|
269 |
public function UpdateMetaValue( $name, $value ) {
|
270 |
$model = new WSAL_Models_Meta();
|
271 |
+
$model->UpdateByNameAndOccurrenceId( $name, $value, $this->getId() );
|
272 |
}
|
273 |
|
274 |
/**
|
275 |
+
* Returns a key-value pair of metadata.
|
276 |
*
|
|
|
277 |
* @return array
|
278 |
+
* @see WSAL_Adapters_MySQL_Occurrence::GetMultiMeta()
|
279 |
*/
|
280 |
public function GetMetaArray() {
|
281 |
$result = array();
|
283 |
foreach ( $metas as $meta ) {
|
284 |
$result[ $meta->name ] = maybe_unserialize( $meta->value );
|
285 |
}
|
286 |
+
|
287 |
+
foreach ( self::$migrated_meta as $meta_key => $column_name ) {
|
288 |
+
$result[ $meta_key ] = $this->$column_name;
|
289 |
+
}
|
290 |
+
|
291 |
return $result;
|
292 |
}
|
293 |
|
294 |
/**
|
295 |
+
* Creates or updates all metadata passed as an array of meta-key/meta-value pairs.
|
296 |
*
|
297 |
* @param array $data - New meta data.
|
298 |
*/
|
300 |
foreach ( (array) $data as $key => $val ) {
|
301 |
$this->SetMetaValue( $key, $val );
|
302 |
}
|
303 |
+
|
304 |
+
// the occurrence object itself needs to be saved again as some metadata is stored as its properties
|
305 |
+
$this->Save();
|
306 |
}
|
307 |
|
308 |
/**
|
327 |
if ( null !== $alert_object && method_exists( $alert_object, 'GetMessage' ) ) {
|
328 |
$this->_cachedMessage = $alert_object->GetMessage( $meta_array, $this->_cachedMessage, $this->getId(), $context );
|
329 |
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
// Filter to allow items to be added elsewhere.
|
331 |
$addon_event_codes = apply_filters( 'wsal_addon_event_codes', $addon_event_codes );
|
332 |
|
363 |
* @return boolean True on success, false on failure.
|
364 |
*/
|
365 |
public function Delete() {
|
366 |
+
/** @var WSAL_Adapters_MySQL_Occurrence $adapter */
|
367 |
+
$adapter= $this->getAdapter();
|
368 |
+
foreach ( $adapter->GetMultiMeta() as $meta ) {
|
369 |
$meta->Delete();
|
370 |
}
|
371 |
return parent::Delete();
|
385 |
/**
|
386 |
* Gets the Client IP.
|
387 |
*
|
|
|
388 |
* @return string IP address of request.
|
389 |
*/
|
390 |
+
public function GetSourceIP() {
|
391 |
+
return $this->GetMetaValue( 'ClientIP', array() );
|
|
|
|
|
|
|
392 |
}
|
393 |
|
394 |
/**
|
410 |
/**
|
411 |
* Gets user roles.
|
412 |
*
|
|
|
413 |
* @return array Array of user roles.
|
414 |
*/
|
415 |
+
public function GetUserRoles() {
|
416 |
+
return $this->GetMetaValue( 'CurrentUserRoles', array() );
|
417 |
+
}
|
418 |
+
|
419 |
+
public function SetUserRoles( $roles ) {
|
420 |
+
$this->user_roles = is_array($roles) ? implode( ',', $roles ) : $roles;
|
421 |
}
|
422 |
|
423 |
/**
|
455 |
* @param array $args - Query args.
|
456 |
* @return WSAL_Models_Occurrence[]
|
457 |
*/
|
458 |
+
public function CheckUnknownUsers( $args = array() ) {
|
459 |
+
return $this->getAdapter()->CheckUnknownUsers( $args );
|
460 |
}
|
461 |
|
462 |
/**
|
479 |
public function GetByPostID( $post_id ) {
|
480 |
return $this->getAdapter()->GetByPostID( $post_id );
|
481 |
}
|
482 |
+
|
483 |
+
/**
|
484 |
+
* @inheritDoc
|
485 |
+
*
|
486 |
+
* Extends the default mechanism for loading data to handle the migrated meta fields in version 4.4.0.
|
487 |
+
*
|
488 |
+
* @since 4.4.0
|
489 |
+
*/
|
490 |
+
public function LoadData( $data ) {
|
491 |
+
$copy = get_class( $this );
|
492 |
+
$copy = new $copy();
|
493 |
+
foreach ( (array) $data as $key => $val ) {
|
494 |
+
if ( ! is_null( $val ) && in_array($key, ['user_id', 'username'])) {
|
495 |
+
// username and user_id cannot have the default value set because some database queries rely on having
|
496 |
+
// null values in the database
|
497 |
+
if ( 'user_id' === $key ) {
|
498 |
+
$this->user_id = intval( $val );
|
499 |
+
} else if ( 'username' === $key ) {
|
500 |
+
$this->username = (string) $val;
|
501 |
+
}
|
502 |
+
} else if ( 'roles' === $key ) {
|
503 |
+
$this->SetUserRoles($val);
|
504 |
+
} else if ( isset( $copy->$key ) ) {
|
505 |
+
// default type casting is applied to the rest of the fields
|
506 |
+
$this->$key = $this->cast_to_correct_type( $copy, $key, $val );
|
507 |
+
}
|
508 |
+
}
|
509 |
+
|
510 |
+
return $this;
|
511 |
+
}
|
512 |
}
|
classes/Models/Query.php
CHANGED
@@ -82,7 +82,7 @@ class WSAL_Models_Query {
|
|
82 |
*
|
83 |
* @var bool
|
84 |
*/
|
85 |
-
protected $
|
86 |
|
87 |
/**
|
88 |
* Method: Constructor.
|
@@ -101,7 +101,8 @@ class WSAL_Models_Query {
|
|
101 |
if ( ! empty( $this->connector ) ) {
|
102 |
return $this->connector;
|
103 |
}
|
104 |
-
|
|
|
105 |
$this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
|
106 |
} else {
|
107 |
$this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
|
@@ -112,7 +113,7 @@ class WSAL_Models_Query {
|
|
112 |
/**
|
113 |
* Gets the adapter.
|
114 |
*
|
115 |
-
* @return
|
116 |
*/
|
117 |
public function getAdapter() {
|
118 |
return $this->getConnector()->getAdapter( 'Query' );
|
82 |
*
|
83 |
* @var bool
|
84 |
*/
|
85 |
+
protected $use_default_adapter = false;
|
86 |
|
87 |
/**
|
88 |
* Method: Constructor.
|
101 |
if ( ! empty( $this->connector ) ) {
|
102 |
return $this->connector;
|
103 |
}
|
104 |
+
|
105 |
+
if ( $this->use_default_adapter ) {
|
106 |
$this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
|
107 |
} else {
|
108 |
$this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
|
113 |
/**
|
114 |
* Gets the adapter.
|
115 |
*
|
116 |
+
* @return WSAL_Adapters_QueryInterface
|
117 |
*/
|
118 |
public function getAdapter() {
|
119 |
return $this->getConnector()->getAdapter( 'Query' );
|
classes/Multisite/NetworkWide/AbstractTracker.php
CHANGED
@@ -32,7 +32,7 @@ abstract class AbstractTracker implements TrackerInterface {
|
|
32 |
/**
|
33 |
* The key used to store data under.
|
34 |
*
|
35 |
-
* You should always
|
36 |
*
|
37 |
* @since 3.5.2
|
38 |
* @var string
|
32 |
/**
|
33 |
* The key used to store data under.
|
34 |
*
|
35 |
+
* You should always redefine this in extended classes.
|
36 |
*
|
37 |
* @since 3.5.2
|
38 |
* @var string
|
classes/Multisite/NetworkWide/TrackerInterface.php
CHANGED
@@ -64,8 +64,8 @@ interface TrackerInterface {
|
|
64 |
public static function get_network_data_list( $site_id = 0 );
|
65 |
|
66 |
/**
|
67 |
-
* Should setup the $data property to hold
|
68 |
-
* single
|
69 |
*
|
70 |
* @method generate_data
|
71 |
* @since 3.5.2
|
64 |
public static function get_network_data_list( $site_id = 0 );
|
65 |
|
66 |
/**
|
67 |
+
* Should setup the $data property to hold its data. In format of a
|
68 |
+
* single dimensional array.
|
69 |
*
|
70 |
* @method generate_data
|
71 |
* @since 3.5.2
|
classes/ReportArgs.php
CHANGED
@@ -125,6 +125,27 @@ class WSAL_ReportArgs {
|
|
125 |
*/
|
126 |
public $code__in;
|
127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
/**
|
129 |
* An array of post types to include in report.
|
130 |
*
|
@@ -132,6 +153,13 @@ class WSAL_ReportArgs {
|
|
132 |
*/
|
133 |
public $post_type__in;
|
134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
/**
|
136 |
* An array of post statuses to include in report.
|
137 |
*
|
@@ -139,149 +167,229 @@ class WSAL_ReportArgs {
|
|
139 |
*/
|
140 |
public $post_status__in;
|
141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
/**
|
143 |
* @param array $filters
|
144 |
-
* @param WSAL_AlertManager $alert_manager
|
145 |
*
|
146 |
-
* @return
|
147 |
*/
|
148 |
-
public static function build_from_alternative_filters( $filters
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
|
150 |
-
|
|
|
151 |
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
|
|
|
|
|
|
156 |
|
157 |
-
|
158 |
-
$result->user__in = $alert_manager->get_user_ids( $filters['users'] );
|
159 |
-
}
|
160 |
|
161 |
-
if (
|
162 |
-
$result->
|
163 |
}
|
164 |
|
165 |
-
if (
|
166 |
-
$result->
|
167 |
}
|
168 |
|
169 |
-
if (
|
170 |
-
$result->
|
171 |
}
|
172 |
-
|
173 |
-
$ip_addresses = empty( $filters['ip-addresses'] ) ? null : $filters['ip-addresses'];
|
174 |
-
$alert_groups = $filters['alert-codes']['groups'];
|
175 |
-
$alert_codes = $filters['alert-codes']['alerts'];
|
176 |
-
$date_start = empty( $filters['date-range']['start'] ) ? null : $filters['date-range']['start'];
|
177 |
-
$date_end = empty( $filters['date-range']['end'] ) ? null : $filters['date-range']['end'];
|
178 |
-
|
179 |
-
// extract full list of alert codes
|
180 |
-
$codes = $alert_manager->get_codes_by_groups( $alert_groups, $alert_codes );
|
181 |
-
|
182 |
|
183 |
-
|
184 |
-
|
185 |
-
if ( is_array( $ip_addresses ) && ! empty( $ip_addresses ) ) {
|
186 |
-
$result->ip__in = $ip_addresses;
|
187 |
}
|
188 |
|
189 |
-
if (
|
190 |
-
$result->
|
191 |
}
|
192 |
|
193 |
-
if ( $
|
194 |
-
$result->
|
195 |
}
|
196 |
|
197 |
-
if ( $
|
198 |
-
$result->
|
199 |
}
|
200 |
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
/**
|
205 |
-
* @param array $filters An array of filters as defined in the Reports extension form.
|
206 |
-
* @param WSAL_Rep_Common $report_utils
|
207 |
-
*
|
208 |
-
* @return WSAL_ReportArgs
|
209 |
-
*/
|
210 |
-
public static function build_from_extension_filters( $filters, $report_utils ) {
|
211 |
-
|
212 |
-
$result = new WSAL_ReportArgs();
|
213 |
|
214 |
-
if (
|
215 |
-
$result->
|
216 |
}
|
217 |
|
218 |
-
if (
|
219 |
-
$result->
|
220 |
}
|
221 |
|
222 |
-
if (
|
223 |
-
$result->
|
224 |
}
|
225 |
|
226 |
-
if (
|
227 |
-
$result->
|
228 |
}
|
229 |
|
230 |
-
if (
|
231 |
-
$result->
|
232 |
}
|
233 |
|
234 |
-
if (
|
235 |
-
$result->
|
236 |
}
|
237 |
|
238 |
-
if (
|
239 |
-
$result->
|
240 |
}
|
241 |
|
242 |
-
if (
|
243 |
-
$result->
|
244 |
}
|
245 |
|
246 |
-
if (
|
247 |
$result->object__in = $filters['objects'];
|
248 |
}
|
249 |
|
250 |
-
if (
|
251 |
$result->object__not_in = $filters['objects-exclude'];
|
252 |
}
|
253 |
|
254 |
-
if (
|
255 |
$result->type__in = $filters['event-types'];
|
256 |
}
|
257 |
|
258 |
-
if (
|
259 |
$result->type__not_in = $filters['event-types-exclude'];
|
260 |
}
|
261 |
|
262 |
-
if (
|
263 |
$result->ip__in = $filters['ip-addresses'];
|
264 |
}
|
265 |
|
266 |
-
if (
|
267 |
$result->ip__not_in = $filters['ip-addresses-exclude'];
|
268 |
}
|
269 |
|
270 |
-
|
271 |
-
$_codes = $report_utils->GetCodesByGroups( $filters['alert_codes_groups'], $filters['alert_codes_alerts'] );
|
272 |
-
|
273 |
if ( is_array( $_codes ) && ! empty( $_codes ) ) {
|
274 |
$result->code__in = $_codes;
|
275 |
}
|
276 |
|
277 |
-
|
|
|
|
|
|
|
|
|
|
|
278 |
$result->start_date = $filters['date_range_start'];
|
279 |
}
|
280 |
|
281 |
-
if ( $filters['date_range_end'] ) {
|
282 |
$result->end_date = $filters['date_range_end'];
|
283 |
}
|
284 |
|
285 |
return $result;
|
286 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
}
|
125 |
*/
|
126 |
public $code__in;
|
127 |
|
128 |
+
/**
|
129 |
+
* An array of event IDs to exclude from report.
|
130 |
+
*
|
131 |
+
* @var int[]
|
132 |
+
*/
|
133 |
+
public $code__not_in;
|
134 |
+
|
135 |
+
/**
|
136 |
+
* An array of post IDs to include in report.
|
137 |
+
*
|
138 |
+
* @var string[]
|
139 |
+
*/
|
140 |
+
public $post__in;
|
141 |
+
|
142 |
+
/**
|
143 |
+
* An array of post IDs to exclude from report.
|
144 |
+
*
|
145 |
+
* @var string[]
|
146 |
+
*/
|
147 |
+
public $post__not_in;
|
148 |
+
|
149 |
/**
|
150 |
* An array of post types to include in report.
|
151 |
*
|
153 |
*/
|
154 |
public $post_type__in;
|
155 |
|
156 |
+
/**
|
157 |
+
* An array of post types to exclude from report.
|
158 |
+
*
|
159 |
+
* @var string[]
|
160 |
+
*/
|
161 |
+
public $post_type__not_in;
|
162 |
+
|
163 |
/**
|
164 |
* An array of post statuses to include in report.
|
165 |
*
|
167 |
*/
|
168 |
public $post_status__in;
|
169 |
|
170 |
+
/**
|
171 |
+
* An array of post statuses to exclude from report.
|
172 |
+
*
|
173 |
+
* @var string[]
|
174 |
+
*/
|
175 |
+
public $post_status__not_in;
|
176 |
+
|
177 |
/**
|
178 |
* @param array $filters
|
|
|
179 |
*
|
180 |
+
* @return WSAL_ReportArgs
|
181 |
*/
|
182 |
+
public static function build_from_alternative_filters( $filters ) {
|
183 |
+
$_filters = array();
|
184 |
+
foreach ( $filters as $key => $value ) {
|
185 |
+
if ( is_array( $value ) && ! is_int( array_key_first( $value ) ) ) {
|
186 |
+
foreach ( $value as $sub_key => $sub_value ) {
|
187 |
+
$_filters[ $key . '_' . $sub_key ] = $sub_value;
|
188 |
+
}
|
189 |
+
} else {
|
190 |
+
$_filters[ $key ] = $value;
|
191 |
+
}
|
192 |
+
}
|
193 |
|
194 |
+
return self::build_from_extension_filters( $_filters, WpSecurityAuditLog::GetInstance()->reports_util );
|
195 |
+
}
|
196 |
|
197 |
+
/**
|
198 |
+
* @param array $filters An array of filters as defined in the Reports extension form.
|
199 |
+
* @param WSAL_Rep_Common $report_utils Reporting utils.
|
200 |
+
*
|
201 |
+
* @return WSAL_ReportArgs
|
202 |
+
*/
|
203 |
+
public static function build_from_extension_filters( $filters, $report_utils ) {
|
204 |
|
205 |
+
$result = new WSAL_ReportArgs();
|
|
|
|
|
206 |
|
207 |
+
if ( self::is_field_present_and_non_empty_array( 'sites', $filters ) ) {
|
208 |
+
$result->site__in = $filters['sites'];
|
209 |
}
|
210 |
|
211 |
+
if ( self::is_field_present_and_non_empty_array( 'sites-exclude', $filters ) ) {
|
212 |
+
$result->site__not_in = $filters['sites-exclude'];
|
213 |
}
|
214 |
|
215 |
+
if ( self::is_field_present_and_non_empty_array( 'users', $filters ) ) {
|
216 |
+
$result->user__in = self::extract_user_ids( $filters['users'] );
|
217 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
|
219 |
+
if ( self::is_field_present_and_non_empty_array( 'users-exclude', $filters ) ) {
|
220 |
+
$result->user__not_in = self::extract_user_ids( $filters['users-exclude'] );
|
|
|
|
|
221 |
}
|
222 |
|
223 |
+
if ( self::is_field_present_and_non_empty_array( 'roles', $filters ) ) {
|
224 |
+
$result->role__in = $filters['roles'];
|
225 |
}
|
226 |
|
227 |
+
if ( self::is_field_present_and_non_empty_array( 'roles-exclude', $filters ) ) {
|
228 |
+
$result->role__not_in = $filters['roles-exclude'];
|
229 |
}
|
230 |
|
231 |
+
if ( self::is_field_present_and_non_empty_array( 'post_ids', $filters ) ) {
|
232 |
+
$result->post__in = $filters['post_ids'];
|
233 |
}
|
234 |
|
235 |
+
if ( self::is_field_present_and_non_empty_array( 'post_ids-exclude', $filters ) ) {
|
236 |
+
$result->post__not_in = $filters['post_ids-exclude'];
|
237 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
238 |
|
239 |
+
if ( self::is_field_present_and_non_empty_array( 'alert_codes_post_types', $filters ) ) {
|
240 |
+
$result->post_type__in = $filters['alert_codes_post_types'];
|
241 |
}
|
242 |
|
243 |
+
if ( self::is_field_present_and_non_empty_array( 'post_types', $filters ) ) {
|
244 |
+
$result->post_type__in = $filters['post_types'];
|
245 |
}
|
246 |
|
247 |
+
if ( self::is_field_present_and_non_empty_array( 'alert_codes_post_types-exclude', $filters ) ) {
|
248 |
+
$result->post_type__not_in = $filters['alert_codes_post_types-exclude'];
|
249 |
}
|
250 |
|
251 |
+
if ( self::is_field_present_and_non_empty_array( 'post_types-exclude', $filters ) ) {
|
252 |
+
$result->post_type__not_in = $filters['post_types-exclude'];
|
253 |
}
|
254 |
|
255 |
+
if ( self::is_field_present_and_non_empty_array( 'alert_codes_post_statuses', $filters ) ) {
|
256 |
+
$result->post_status__in = $filters['alert_codes_post_statuses'];
|
257 |
}
|
258 |
|
259 |
+
if ( self::is_field_present_and_non_empty_array( 'post_statuses', $filters ) ) {
|
260 |
+
$result->post_status__in = $filters['post_statuses'];
|
261 |
}
|
262 |
|
263 |
+
if ( self::is_field_present_and_non_empty_array( 'alert_codes_post_statuses-exclude', $filters ) ) {
|
264 |
+
$result->post_status__not_in = $filters['alert_codes_post_statuses-exclude'];
|
265 |
}
|
266 |
|
267 |
+
if ( self::is_field_present_and_non_empty_array( 'post_statuses-exclude', $filters ) ) {
|
268 |
+
$result->post_status__not_in = $filters['post_statuses-exclude'];
|
269 |
}
|
270 |
|
271 |
+
if ( self::is_field_present_and_non_empty_array( 'objects', $filters ) ) {
|
272 |
$result->object__in = $filters['objects'];
|
273 |
}
|
274 |
|
275 |
+
if ( self::is_field_present_and_non_empty_array( 'objects-exclude', $filters ) ) {
|
276 |
$result->object__not_in = $filters['objects-exclude'];
|
277 |
}
|
278 |
|
279 |
+
if ( self::is_field_present_and_non_empty_array( 'event-types', $filters ) ) {
|
280 |
$result->type__in = $filters['event-types'];
|
281 |
}
|
282 |
|
283 |
+
if ( self::is_field_present_and_non_empty_array( 'event-types-exclude', $filters ) ) {
|
284 |
$result->type__not_in = $filters['event-types-exclude'];
|
285 |
}
|
286 |
|
287 |
+
if ( self::is_field_present_and_non_empty_array( 'ip-addresses', $filters ) ) {
|
288 |
$result->ip__in = $filters['ip-addresses'];
|
289 |
}
|
290 |
|
291 |
+
if ( self::is_field_present_and_non_empty_array( 'ip-addresses-exclude', $filters ) ) {
|
292 |
$result->ip__not_in = $filters['ip-addresses-exclude'];
|
293 |
}
|
294 |
|
295 |
+
$_codes = self::get_codes( $filters, 'alert_codes_groups', 'alert_codes_alerts', $report_utils );
|
|
|
|
|
296 |
if ( is_array( $_codes ) && ! empty( $_codes ) ) {
|
297 |
$result->code__in = $_codes;
|
298 |
}
|
299 |
|
300 |
+
$_excluded_codes = self::get_codes( $filters, 'alert_codes_groups-exclude', 'alert_codes_alerts-exclude', $report_utils );
|
301 |
+
if ( is_array( $_excluded_codes ) && ! empty( $_excluded_codes ) ) {
|
302 |
+
$result->code__not_in = $_excluded_codes;
|
303 |
+
}
|
304 |
+
|
305 |
+
if ( array_key_exists( 'date_range_start', $filters ) && $filters['date_range_start'] ) {
|
306 |
$result->start_date = $filters['date_range_start'];
|
307 |
}
|
308 |
|
309 |
+
if ( array_key_exists( 'date_range_end', $filters ) && $filters['date_range_end'] ) {
|
310 |
$result->end_date = $filters['date_range_end'];
|
311 |
}
|
312 |
|
313 |
return $result;
|
314 |
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Checks if the key is present in the array and the value is non-empty array.
|
318 |
+
*
|
319 |
+
* @param string $key Key to look for.
|
320 |
+
* @param array $array Report filtering data.
|
321 |
+
*
|
322 |
+
* @return bool True if the key is present in the array and the value is non-empty array.
|
323 |
+
*
|
324 |
+
* @since 4.4.0
|
325 |
+
*/
|
326 |
+
private static function is_field_present_and_non_empty_array( $key, $array ) {
|
327 |
+
return array_key_exists( $key, $array ) && is_array( $array[ $key ] ) && ! empty( $array[ $key ] );
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Determines all alert IDs/codes for given array of data. The groups and keys are located using the provided keys.
|
332 |
+
*
|
333 |
+
* @param array $array Filter data.
|
334 |
+
* @param string $groups_key Key of the event groups array.
|
335 |
+
* @param string $codes_key Key of the event codes array.
|
336 |
+
* @param WSAL_Rep_Common $report_utils Report utilities.
|
337 |
+
*
|
338 |
+
* @return int[]
|
339 |
+
*
|
340 |
+
* @since 4.4.0
|
341 |
+
*/
|
342 |
+
private static function get_codes( $array, $groups_key, $codes_key, $report_utils ) {
|
343 |
+
$groups = self::is_field_present_and_non_empty_array( $groups_key, $array ) ? $array[ $groups_key ] : array();
|
344 |
+
$alerts = self::is_field_present_and_non_empty_array( $codes_key, $array ) ? $array[ $codes_key ] : array();
|
345 |
+
|
346 |
+
$result = $report_utils->GetCodesByGroups( $groups, $alerts, false );
|
347 |
+
if ( false === $result ) {
|
348 |
+
return array();
|
349 |
+
}
|
350 |
+
|
351 |
+
return $result;
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Determines user ID based on given value.
|
356 |
+
*
|
357 |
+
* @param int|string $value User ID or login username.
|
358 |
+
*
|
359 |
+
* @return int User ID.
|
360 |
+
* @since 4.4.0
|
361 |
+
*/
|
362 |
+
public static function grab_uid( $value ) {
|
363 |
+
if ( is_numeric( $value ) ) {
|
364 |
+
return intval( $value );
|
365 |
+
}
|
366 |
+
|
367 |
+
// Load user by id.
|
368 |
+
$user = get_user_by( 'login', $value );
|
369 |
+
if ( $user instanceof WP_User ) {
|
370 |
+
return $user->ID;
|
371 |
+
}
|
372 |
+
|
373 |
+
return 0;
|
374 |
+
}
|
375 |
+
|
376 |
+
/**
|
377 |
+
* Extracts user IDs.
|
378 |
+
*
|
379 |
+
* @param array $values User IDs or login usernames (or both).
|
380 |
+
*
|
381 |
+
* @return int[] User IDs.
|
382 |
+
* @since 4.4.0
|
383 |
+
*/
|
384 |
+
public static function extract_user_ids( $values ) {
|
385 |
+
return array_filter(
|
386 |
+
array_map(
|
387 |
+
array( __CLASS__, 'grab_uid' ),
|
388 |
+
$values
|
389 |
+
),
|
390 |
+
function ( $item ) {
|
391 |
+
return $item > 0;
|
392 |
+
}
|
393 |
+
);
|
394 |
+
}
|
395 |
}
|
classes/SensorManager.php
CHANGED
@@ -30,16 +30,14 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
30 |
protected $sensors = array();
|
31 |
|
32 |
/**
|
33 |
-
*
|
34 |
-
*
|
35 |
-
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
36 |
*/
|
37 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
38 |
parent::__construct( $plugin );
|
39 |
|
40 |
// Check sensors before loading for optimization.
|
41 |
add_filter( 'wsal_before_sensor_load', array( $this, 'check_sensor_before_load' ), 10, 2 );
|
42 |
-
foreach (
|
43 |
$this->AddFromFile( $file );
|
44 |
}
|
45 |
|
@@ -55,7 +53,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
55 |
foreach ( $paths as $inc_path ) {
|
56 |
// Check directory.
|
57 |
if ( is_dir( $inc_path ) && is_readable( $inc_path ) ) {
|
58 |
-
foreach (
|
59 |
// Include custom sensor file.
|
60 |
require_once $file;
|
61 |
$file = substr( $file, 0, -4 );
|
@@ -81,7 +79,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
-
*
|
85 |
*/
|
86 |
public function HookEvents() {
|
87 |
foreach ( $this->sensors as $sensor ) {
|
@@ -105,7 +103,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
105 |
/**
|
106 |
* Filter: `wsal_before_sensor_load`
|
107 |
*
|
108 |
-
* Check to see if sensor is to be
|
109 |
*
|
110 |
* @param bool $load_sensor – Set to true if sensor is to be loaded.
|
111 |
* @param string $file – File path.
|
@@ -189,15 +187,20 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
189 |
|
190 |
$frontend_events = WSAL_Settings::get_frontend_events();
|
191 |
|
192 |
-
//
|
193 |
if ( WpSecurityAuditLog::is_login_screen() ) {
|
194 |
-
if (
|
195 |
-
|| 'LogInOut' === $filename ) {
|
196 |
return true;
|
197 |
}
|
198 |
return false; // Any other sensor should not load here.
|
199 |
}
|
200 |
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
/**
|
202 |
* WSAL Filter: `wsal_load_public_sensor`
|
203 |
*
|
@@ -209,7 +212,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
209 |
*
|
210 |
* @param array $public_sensors - List of sensors to be loaded for visitors.
|
211 |
*/
|
212 |
-
$public_sensors = apply_filters( 'wsal_load_public_sensors',
|
213 |
if ( WpSecurityAuditLog::is_frontend() && ! is_user_logged_in() && ! in_array( $filename, $public_sensors, true ) ) {
|
214 |
return false;
|
215 |
}
|
@@ -276,7 +279,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
276 |
}
|
277 |
break;
|
278 |
|
279 |
-
case '
|
280 |
if ( is_user_logged_in() || empty( $frontend_events['register'] ) ) {
|
281 |
$load_sensor = false;
|
282 |
}
|
30 |
protected $sensors = array();
|
31 |
|
32 |
/**
|
33 |
+
* {@inheritDoc}
|
|
|
|
|
34 |
*/
|
35 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
36 |
parent::__construct( $plugin );
|
37 |
|
38 |
// Check sensors before loading for optimization.
|
39 |
add_filter( 'wsal_before_sensor_load', array( $this, 'check_sensor_before_load' ), 10, 2 );
|
40 |
+
foreach ( WSAL_Utilities_FileSystemUtils::read_files_in_folder( dirname( __FILE__ ) . '/Sensors', '*.php' ) as $file ) {
|
41 |
$this->AddFromFile( $file );
|
42 |
}
|
43 |
|
53 |
foreach ( $paths as $inc_path ) {
|
54 |
// Check directory.
|
55 |
if ( is_dir( $inc_path ) && is_readable( $inc_path ) ) {
|
56 |
+
foreach ( WSAL_Utilities_FileSystemUtils::read_files_in_folder( $inc_path, '*.php' ) as $file ) {
|
57 |
// Include custom sensor file.
|
58 |
require_once $file;
|
59 |
$file = substr( $file, 0, -4 );
|
79 |
}
|
80 |
|
81 |
/**
|
82 |
+
* {@inheritDoc}
|
83 |
*/
|
84 |
public function HookEvents() {
|
85 |
foreach ( $this->sensors as $sensor ) {
|
103 |
/**
|
104 |
* Filter: `wsal_before_sensor_load`
|
105 |
*
|
106 |
+
* Check to see if sensor is to be initiated or not.
|
107 |
*
|
108 |
* @param bool $load_sensor – Set to true if sensor is to be loaded.
|
109 |
* @param string $file – File path.
|
187 |
|
188 |
$frontend_events = WSAL_Settings::get_frontend_events();
|
189 |
|
190 |
+
// Only LogInOut and Register sensors should load on login page.
|
191 |
if ( WpSecurityAuditLog::is_login_screen() ) {
|
192 |
+
if ( in_array( $filename, array( 'Register', 'LogInOut' ) ) ) {
|
|
|
193 |
return true;
|
194 |
}
|
195 |
return false; // Any other sensor should not load here.
|
196 |
}
|
197 |
|
198 |
+
$default_public_sensors = array( 'Register', 'LogInOut' );
|
199 |
+
if ( $this->plugin->IsMultisite() ) {
|
200 |
+
// Multisite sign-up is happening on front-end.
|
201 |
+
array_push( $default_public_sensors, 'MultisiteSignUp' );
|
202 |
+
}
|
203 |
+
|
204 |
/**
|
205 |
* WSAL Filter: `wsal_load_public_sensor`
|
206 |
*
|
212 |
*
|
213 |
* @param array $public_sensors - List of sensors to be loaded for visitors.
|
214 |
*/
|
215 |
+
$public_sensors = apply_filters( 'wsal_load_public_sensors', $default_public_sensors );
|
216 |
if ( WpSecurityAuditLog::is_frontend() && ! is_user_logged_in() && ! in_array( $filename, $public_sensors, true ) ) {
|
217 |
return false;
|
218 |
}
|
279 |
}
|
280 |
break;
|
281 |
|
282 |
+
case 'Register':
|
283 |
if ( is_user_logged_in() || empty( $frontend_events['register'] ) ) {
|
284 |
$load_sensor = false;
|
285 |
}
|
classes/Sensors/Content.php
CHANGED
@@ -100,10 +100,9 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
100 |
add_action( 'create_post_tag', array( $this, 'event_tag_creation' ), 10, 1 );
|
101 |
add_action( 'pre_delete_term', array( $this, 'check_taxonomy_term_deletion' ), 10, 2 );
|
102 |
add_filter( 'wp_update_term_data', array( $this, 'event_update_term_data' ), 10, 4 );
|
103 |
-
add_filter( 'add_post_metadata', array( $this, '
|
104 |
-
add_filter( 'updated_post_meta', array( $this, 'check_changed_meta' ), 10, 4 );
|
105 |
add_filter( 'delete_post_metadata', array( $this, 'check_deleted_meta' ), 10, 5 );
|
106 |
-
|
107 |
|
108 |
// Check if MainWP Child Plugin exists.
|
109 |
if ( WpSecurityAuditLog::is_mainwp_active() ) {
|
@@ -124,14 +123,14 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
124 |
|
125 |
// If post exists.
|
126 |
if ( ! empty( $post ) && $post instanceof WP_Post ) {
|
127 |
-
$this->_old_post
|
128 |
-
$this->_old_link
|
129 |
-
$this->_old_tmpl
|
130 |
-
$this->_old_cats
|
131 |
-
$this->_old_tags
|
132 |
-
$this->_old_stky
|
133 |
-
$this->old_status
|
134 |
-
$this->old_meta
|
135 |
}
|
136 |
}
|
137 |
|
@@ -291,10 +290,10 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
291 |
|
292 |
$event_data = $this->get_post_event_data( $post ); // Get event data.
|
293 |
|
294 |
-
//
|
295 |
-
$request_params
|
296 |
if ( empty( $request_params['action'] ) && isset( $request_params['page'] ) ) {
|
297 |
-
$event
|
298 |
$event_data = array(
|
299 |
'PostID' => $post->ID,
|
300 |
'PostType' => $post->post_type,
|
@@ -456,9 +455,9 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
456 |
|
457 |
// Update post URL based on current actual path.
|
458 |
if ( $this->plugin->IsMultisite() && ! is_subdomain_install() ) {
|
459 |
-
//
|
460 |
-
$subdir_path
|
461 |
-
$escaped
|
462 |
$current_path = preg_replace( '/' . $escaped . '/', '', $current_path );
|
463 |
}
|
464 |
|
@@ -603,10 +602,10 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
603 |
$this->plugin->alerts->Trigger(
|
604 |
2125,
|
605 |
array(
|
606 |
-
'tag'
|
607 |
-
'TagLink'
|
608 |
-
'old_desc'
|
609 |
-
'new_desc'
|
610 |
)
|
611 |
);
|
612 |
}
|
@@ -667,18 +666,20 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
667 |
}
|
668 |
|
669 |
/**
|
670 |
-
*
|
671 |
*
|
672 |
-
* @param int $
|
673 |
-
* @param
|
674 |
-
* @param
|
675 |
-
* @param mixed $
|
676 |
-
*
|
677 |
-
* @return
|
|
|
|
|
678 |
*/
|
679 |
-
|
680 |
if ( ! $post_id ) {
|
681 |
-
return $
|
682 |
}
|
683 |
|
684 |
switch ( $meta_key ) {
|
@@ -689,75 +690,93 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
689 |
$this->check_featured_image_change( $post_id, $meta_value );
|
690 |
break;
|
691 |
default:
|
692 |
-
return $
|
693 |
}
|
694 |
|
695 |
-
return $
|
696 |
}
|
697 |
|
698 |
/**
|
699 |
-
* Check Page Template Update
|
700 |
-
*
|
701 |
-
* @param
|
702 |
-
* @param int
|
703 |
-
* @param
|
704 |
-
* @param
|
705 |
-
*
|
706 |
-
*
|
707 |
-
* @return bool|null $delete Whether to allow metadata deletion of the given type.
|
708 |
*/
|
709 |
-
public function
|
710 |
-
|
711 |
-
|
712 |
-
}
|
713 |
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
725 |
}
|
726 |
|
727 |
/**
|
728 |
* Check Page Template Update.
|
729 |
*
|
730 |
-
* @param int
|
731 |
-
* @param mixed
|
732 |
*/
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
}
|
755 |
|
756 |
/**
|
757 |
* Check Post Featured Image Update.
|
758 |
*
|
759 |
-
* @param int
|
760 |
-
* @param mixed
|
761 |
*/
|
762 |
public function check_featured_image_change( $post_id, $meta_value ) {
|
763 |
$previous_featured_image = ( isset( $this->old_meta['_thumbnail_id'][0] ) ) ? wp_get_attachment_metadata( $this->old_meta['_thumbnail_id'][0] ) : false;
|
@@ -771,14 +790,14 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
771 |
|
772 |
if ( empty( $previous_featured_image['file'] ) && ! empty( $new_featured_image['file'] ) ) {
|
773 |
$event_type = 'added';
|
774 |
-
} elseif ( ! empty( $previous_featured_image['file'] ) &&
|
775 |
$event_type = 'removed';
|
776 |
}
|
777 |
|
778 |
$previous_image = is_array( $previous_featured_image ) && array_key_exists( 'file', $previous_featured_image ) ? $previous_featured_image['file'] : __( 'No previous image', 'wp-security-audit-log' );
|
779 |
$new_image = is_array( $new_featured_image ) && array_key_exists( 'file', $new_featured_image ) ? $new_featured_image['file'] : __( 'No image', 'wp-security-audit-log' );
|
780 |
|
781 |
-
$post
|
782 |
$editor_link = $this->get_editor_link( $post );
|
783 |
$this->plugin->alerts->Trigger(
|
784 |
2130,
|
@@ -915,14 +934,14 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
915 |
$this->plugin->alerts->Trigger( $event, $event_data );
|
916 |
} else {
|
917 |
|
918 |
-
//
|
919 |
-
//
|
920 |
$request_params = WSAL_Utilities_RequestUtils::get_filtered_request_data();
|
921 |
-
if ( array_key_exists( 'plugin', $request_params ) && !empty( $request_params['plugin'] ) ) {
|
922 |
-
//
|
923 |
$plugin_name = $request_params['plugin'];
|
924 |
$plugin_data = get_plugin_data( trailingslashit( WP_PLUGIN_DIR ) . $plugin_name );
|
925 |
-
$event_data
|
926 |
'PluginName' => ( $plugin_data && isset( $plugin_data['Name'] ) ) ? $plugin_data['Name'] : false,
|
927 |
'PostID' => $new_post->ID,
|
928 |
'PostType' => $new_post->post_type,
|
100 |
add_action( 'create_post_tag', array( $this, 'event_tag_creation' ), 10, 1 );
|
101 |
add_action( 'pre_delete_term', array( $this, 'check_taxonomy_term_deletion' ), 10, 2 );
|
102 |
add_filter( 'wp_update_term_data', array( $this, 'event_update_term_data' ), 10, 4 );
|
103 |
+
add_filter( 'add_post_metadata', array( $this, 'check_added_meta' ), 10, 5 );
|
|
|
104 |
add_filter( 'delete_post_metadata', array( $this, 'check_deleted_meta' ), 10, 5 );
|
105 |
+
add_action( 'updated_post_meta', array( $this, 'check_changed_meta' ), 10, 4 );
|
106 |
|
107 |
// Check if MainWP Child Plugin exists.
|
108 |
if ( WpSecurityAuditLog::is_mainwp_active() ) {
|
123 |
|
124 |
// If post exists.
|
125 |
if ( ! empty( $post ) && $post instanceof WP_Post ) {
|
126 |
+
$this->_old_post = $post;
|
127 |
+
$this->_old_link = get_permalink( $post_id );
|
128 |
+
$this->_old_tmpl = $this->get_post_template( $this->_old_post );
|
129 |
+
$this->_old_cats = $this->get_post_categories( $this->_old_post );
|
130 |
+
$this->_old_tags = $this->get_post_tags( $this->_old_post );
|
131 |
+
$this->_old_stky = in_array( $post_id, get_option( 'sticky_posts' ), true );
|
132 |
+
$this->old_status = $post->post_status;
|
133 |
+
$this->old_meta = get_post_meta( $post_id );
|
134 |
}
|
135 |
}
|
136 |
|
290 |
|
291 |
$event_data = $this->get_post_event_data( $post ); // Get event data.
|
292 |
|
293 |
+
// Check if this was initiated by a plugin.
|
294 |
+
$request_params = WSAL_Utilities_RequestUtils::get_filtered_request_data();
|
295 |
if ( empty( $request_params['action'] ) && isset( $request_params['page'] ) ) {
|
296 |
+
$event = 5025;
|
297 |
$event_data = array(
|
298 |
'PostID' => $post->ID,
|
299 |
'PostType' => $post->post_type,
|
455 |
|
456 |
// Update post URL based on current actual path.
|
457 |
if ( $this->plugin->IsMultisite() && ! is_subdomain_install() ) {
|
458 |
+
// For multisite using subfolders, remove the subfolder.
|
459 |
+
$subdir_path = parse_url( home_url(), PHP_URL_PATH );
|
460 |
+
$escaped = str_replace( '/', '\/', preg_quote( $subdir_path ) );
|
461 |
$current_path = preg_replace( '/' . $escaped . '/', '', $current_path );
|
462 |
}
|
463 |
|
602 |
$this->plugin->alerts->Trigger(
|
603 |
2125,
|
604 |
array(
|
605 |
+
'tag' => $new_name,
|
606 |
+
'TagLink' => $term_link,
|
607 |
+
'old_desc' => $old_desc,
|
608 |
+
'new_desc' => $new_desc,
|
609 |
)
|
610 |
);
|
611 |
}
|
666 |
}
|
667 |
|
668 |
/**
|
669 |
+
* Checks if selected metadata items have changed. Function is called from different contexts.
|
670 |
*
|
671 |
+
* @param int $post_id Post ID.
|
672 |
+
* @param string $meta_key Meta key.
|
673 |
+
* @param mixed $meta_value Meta value.
|
674 |
+
* @param mixed $default_result Default result.
|
675 |
+
*
|
676 |
+
* @return mixed
|
677 |
+
*
|
678 |
+
* @since 4.4.0
|
679 |
*/
|
680 |
+
private function check_selected_meta_change( $post_id, $meta_key, $meta_value, $default_result ) {
|
681 |
if ( ! $post_id ) {
|
682 |
+
return $default_result;
|
683 |
}
|
684 |
|
685 |
switch ( $meta_key ) {
|
690 |
$this->check_featured_image_change( $post_id, $meta_value );
|
691 |
break;
|
692 |
default:
|
693 |
+
return $default_result;
|
694 |
}
|
695 |
|
696 |
+
return $default_result;
|
697 |
}
|
698 |
|
699 |
/**
|
700 |
+
* Check Page Template Update.
|
701 |
+
*
|
702 |
+
* @param int $meta_id ID of updated metadata entry.
|
703 |
+
* @param int $post_id Post ID.
|
704 |
+
* @param string $meta_key Meta key.
|
705 |
+
* @param mixed $meta_value Meta value.
|
706 |
+
*
|
707 |
+
* @return int ID of updated metadata entry.
|
|
|
708 |
*/
|
709 |
+
public function check_changed_meta( $meta_id, $post_id, $meta_key, $meta_value ) {
|
710 |
+
return $this->check_selected_meta_change( $post_id, $meta_key, $meta_value, $meta_id );
|
711 |
+
}
|
|
|
712 |
|
713 |
+
/**
|
714 |
+
* Check Page Template Update for deletions.
|
715 |
+
*
|
716 |
+
* @param null|bool $delete Whether to allow metadata deletion of the given type.
|
717 |
+
* @param int $object_id ID of the object metadata is for.
|
718 |
+
* @param string $meta_key Metadata key.
|
719 |
+
* @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
|
720 |
+
* @param bool $delete_all Whether to delete the matching metadata entries
|
721 |
+
* for all objects, ignoring the specified $object_id.
|
722 |
+
* Default false.
|
723 |
+
*
|
724 |
+
* @return bool|null Whether to allow metadata deletion of the given type.
|
725 |
+
*/
|
726 |
+
public function check_deleted_meta( $delete, $object_id, $meta_key, $meta_value, $delete_all ) {
|
727 |
+
return $this->check_selected_meta_change( $object_id, $meta_key, $meta_value, $delete );
|
728 |
+
}
|
729 |
+
|
730 |
+
/**
|
731 |
+
* Check Page Template Update for additions.
|
732 |
+
*
|
733 |
+
* @param null|bool $check Whether to allow adding metadata for the given type.
|
734 |
+
* @param int $object_id ID of the object metadata is for.
|
735 |
+
* @param string $meta_key Metadata key.
|
736 |
+
* @param mixed $meta_value Metadata value. Must be serializable if non-scalar.
|
737 |
+
* @param bool $unique Whether the specified meta key should be unique for the object.
|
738 |
+
*
|
739 |
+
* @return bool|null Whether to allow metadata addition of the given type.
|
740 |
+
*
|
741 |
+
* @since 4.4.0
|
742 |
+
*/
|
743 |
+
public function check_added_meta( $check, $object_id, $meta_key, $meta_value, $unique ) {
|
744 |
+
return $this->check_selected_meta_change( $object_id, $meta_key, $meta_value, $check );
|
745 |
}
|
746 |
|
747 |
/**
|
748 |
* Check Page Template Update.
|
749 |
*
|
750 |
+
* @param int $post_id Post ID.
|
751 |
+
* @param mixed $meta_value Meta value.
|
752 |
*/
|
753 |
+
public function check_template_change( $post_id, $meta_value ) {
|
754 |
+
$post = get_post( $post_id );
|
755 |
+
$old_tmpl = ( $this->_old_tmpl && 'page' !== basename( $this->_old_tmpl, '.php' ) ) ? ucwords( str_replace( array( '-', '_' ), ' ', basename( $this->_old_tmpl, '.php' ) ) ) : __( 'Default template', 'wp-security-audit-log' );
|
756 |
+
$new_tmpl = ( $meta_value ) ? ucwords( str_replace( array( '-', '_' ), ' ', basename( $meta_value ) ) ) : __( 'Default', 'wp-security-audit-log' );
|
757 |
+
if ( $old_tmpl !== $new_tmpl ) {
|
758 |
+
$editor_link = $this->get_editor_link( $post );
|
759 |
+
$this->plugin->alerts->Trigger(
|
760 |
+
2048,
|
761 |
+
array(
|
762 |
+
'PostID' => $post->ID,
|
763 |
+
'PostType' => $post->post_type,
|
764 |
+
'PostTitle' => $post->post_title,
|
765 |
+
'PostStatus' => $post->post_status,
|
766 |
+
'PostDate' => $post->post_date,
|
767 |
+
'OldTemplate' => $old_tmpl,
|
768 |
+
'NewTemplate' => $new_tmpl,
|
769 |
+
$editor_link['name'] => $editor_link['value'],
|
770 |
+
)
|
771 |
+
);
|
772 |
+
}
|
773 |
+
}
|
|
|
774 |
|
775 |
/**
|
776 |
* Check Post Featured Image Update.
|
777 |
*
|
778 |
+
* @param int $post_id Post ID.
|
779 |
+
* @param mixed $meta_value Meta value.
|
780 |
*/
|
781 |
public function check_featured_image_change( $post_id, $meta_value ) {
|
782 |
$previous_featured_image = ( isset( $this->old_meta['_thumbnail_id'][0] ) ) ? wp_get_attachment_metadata( $this->old_meta['_thumbnail_id'][0] ) : false;
|
790 |
|
791 |
if ( empty( $previous_featured_image['file'] ) && ! empty( $new_featured_image['file'] ) ) {
|
792 |
$event_type = 'added';
|
793 |
+
} elseif ( ! empty( $previous_featured_image['file'] ) && empty( $new_featured_image['file'] ) ) {
|
794 |
$event_type = 'removed';
|
795 |
}
|
796 |
|
797 |
$previous_image = is_array( $previous_featured_image ) && array_key_exists( 'file', $previous_featured_image ) ? $previous_featured_image['file'] : __( 'No previous image', 'wp-security-audit-log' );
|
798 |
$new_image = is_array( $new_featured_image ) && array_key_exists( 'file', $new_featured_image ) ? $new_featured_image['file'] : __( 'No image', 'wp-security-audit-log' );
|
799 |
|
800 |
+
$post = get_post( $post_id );
|
801 |
$editor_link = $this->get_editor_link( $post );
|
802 |
$this->plugin->alerts->Trigger(
|
803 |
2130,
|
934 |
$this->plugin->alerts->Trigger( $event, $event_data );
|
935 |
} else {
|
936 |
|
937 |
+
// So far we assume that the action is initiated by a user, let's check if it was actually initiated
|
938 |
+
// by a plugin.
|
939 |
$request_params = WSAL_Utilities_RequestUtils::get_filtered_request_data();
|
940 |
+
if ( array_key_exists( 'plugin', $request_params ) && ! empty( $request_params['plugin'] ) ) {
|
941 |
+
// Event initiated by a plugin.
|
942 |
$plugin_name = $request_params['plugin'];
|
943 |
$plugin_data = get_plugin_data( trailingslashit( WP_PLUGIN_DIR ) . $plugin_name );
|
944 |
+
$event_data = array(
|
945 |
'PluginName' => ( $plugin_data && isset( $plugin_data['Name'] ) ) ? $plugin_data['Name'] : false,
|
946 |
'PostID' => $new_post->ID,
|
947 |
'PostType' => $new_post->post_type,
|
classes/Sensors/FrontendRegister.php
DELETED
@@ -1,62 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Frontend user registration sensor.
|
4 |
-
*
|
5 |
-
* @package wsal
|
6 |
-
*/
|
7 |
-
|
8 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
9 |
-
exit; // Exit if accessed directly.
|
10 |
-
}
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Frontend user registration sensor.
|
14 |
-
*/
|
15 |
-
class WSAL_Sensors_FrontendRegister extends WSAL_AbstractSensor {
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Listening to events using WP hooks.
|
19 |
-
*/
|
20 |
-
public function HookEvents() {
|
21 |
-
/*
|
22 |
-
* We hook into action 'user_register' because it is part of the function 'wp_insert_user'. Default WordPress
|
23 |
-
* registration utilizes action 'register_new_user', but we cannot rely a front-end registration implemented
|
24 |
-
* by a third party to use it.
|
25 |
-
*/
|
26 |
-
add_action( 'user_register', array( $this, 'event_user_register' ), 10, 1 );
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Triggered when a user is registered.
|
31 |
-
*
|
32 |
-
* This function is identical to function WSAL_Sensors_Public::event_user_register. We will keep the duplication
|
33 |
-
* until some autoloading improvements are made.
|
34 |
-
*
|
35 |
-
* @param int $user_id - User ID of the registered user.
|
36 |
-
*/
|
37 |
-
public function event_user_register( $user_id ) {
|
38 |
-
$plugin = WpSecurityAuditLog::GetInstance();
|
39 |
-
$user = get_userdata( $user_id );
|
40 |
-
$event = $plugin->IsMultisite() ? 4012 : ( is_user_logged_in() ? 4001 : 4000 );
|
41 |
-
$current_user = wp_get_current_user();
|
42 |
-
|
43 |
-
$new_user_data = array(
|
44 |
-
'Username' => $user->user_login,
|
45 |
-
'Email' => $user->user_email,
|
46 |
-
'Roles' => is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles,
|
47 |
-
);
|
48 |
-
|
49 |
-
if ( 4000 != $event ) {
|
50 |
-
$new_user_data['FirstName'] = ! empty( $user->user_firstname ) ? $user->user_firstname : '';
|
51 |
-
$new_user_data['LastName'] = ! empty( $user->user_lastname ) ? $user->user_lastname : '';
|
52 |
-
}
|
53 |
-
|
54 |
-
$event_data = array(
|
55 |
-
'NewUserID' => $user_id,
|
56 |
-
'UserChanger' => ! empty( $current_user ) ? $current_user->user_login : '',
|
57 |
-
'NewUserData' => (object) $new_user_data,
|
58 |
-
);
|
59 |
-
|
60 |
-
$plugin->alerts->Trigger( $event, $event_data, true );
|
61 |
-
}
|
62 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/Sensors/LogInOut.php
CHANGED
@@ -393,15 +393,13 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
393 |
$new = $occ->GetMetaValue( 'Attempts', 0 ) + 1;
|
394 |
|
395 |
$login_failure_log_limit = $this->GetLoginFailureLogLimit();
|
396 |
-
if ( - 1 !==
|
397 |
-
&& $new > $
|
398 |
-
$new = $
|
399 |
}
|
400 |
|
401 |
$occ->UpdateMetaValue( 'Attempts', $new );
|
402 |
-
$occ->
|
403 |
-
|
404 |
-
// $occ->SetMetaValue('CurrentUserRoles', $user_roles);
|
405 |
$occ->created_on = null;
|
406 |
$occ->Save();
|
407 |
} else {
|
@@ -419,14 +417,14 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
419 |
*
|
420 |
* @return bool
|
421 |
*/
|
422 |
-
function ($manager) {
|
423 |
// skip if 1004 (session block) is already in place
|
424 |
return !$manager->WillOrHasTriggered(1004);
|
425 |
}
|
426 |
);
|
427 |
}
|
428 |
} else {
|
429 |
-
$occ_unknown = $obj_occurrence->
|
430 |
array(
|
431 |
$ip,
|
432 |
1003,
|
@@ -445,9 +443,9 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
445 |
$new = $occ_unknown->GetMetaValue( 'Attempts', 0 ) + 1;
|
446 |
|
447 |
// If login attempts pass allowed number of attempts then stop increasing the attempts.
|
448 |
-
|
449 |
-
|
450 |
-
$new = $
|
451 |
}
|
452 |
|
453 |
// Update the number of login attempts.
|
@@ -462,8 +460,7 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
462 |
$occ_unknown->UpdateMetaValue( 'Users', $users );
|
463 |
} else {
|
464 |
// In this case the value doesn't exist so set the value to array.
|
465 |
-
$users = array();
|
466 |
-
$users[] = $username;
|
467 |
}
|
468 |
|
469 |
$occ_unknown->created_on = null;
|
393 |
$new = $occ->GetMetaValue( 'Attempts', 0 ) + 1;
|
394 |
|
395 |
$login_failure_log_limit = $this->GetLoginFailureLogLimit();
|
396 |
+
if ( - 1 !== $login_failure_log_limit
|
397 |
+
&& $new > $login_failure_log_limit ) {
|
398 |
+
$new = $login_failure_log_limit . '+';
|
399 |
}
|
400 |
|
401 |
$occ->UpdateMetaValue( 'Attempts', $new );
|
402 |
+
$occ->username = $username;
|
|
|
|
|
403 |
$occ->created_on = null;
|
404 |
$occ->Save();
|
405 |
} else {
|
417 |
*
|
418 |
* @return bool
|
419 |
*/
|
420 |
+
function ( $manager ) {
|
421 |
// skip if 1004 (session block) is already in place
|
422 |
return !$manager->WillOrHasTriggered(1004);
|
423 |
}
|
424 |
);
|
425 |
}
|
426 |
} else {
|
427 |
+
$occ_unknown = $obj_occurrence->CheckUnknownUsers(
|
428 |
array(
|
429 |
$ip,
|
430 |
1003,
|
443 |
$new = $occ_unknown->GetMetaValue( 'Attempts', 0 ) + 1;
|
444 |
|
445 |
// If login attempts pass allowed number of attempts then stop increasing the attempts.
|
446 |
+
$failure_limit = $this->GetVisitorLoginFailureLogLimit();
|
447 |
+
if ( -1 !== $failure_limit && $new > $failure_limit ) {
|
448 |
+
$new = $failure_limit . '+';
|
449 |
}
|
450 |
|
451 |
// Update the number of login attempts.
|
460 |
$occ_unknown->UpdateMetaValue( 'Users', $users );
|
461 |
} else {
|
462 |
// In this case the value doesn't exist so set the value to array.
|
463 |
+
$users = array( $username );
|
|
|
464 |
}
|
465 |
|
466 |
$occ_unknown->created_on = null;
|
classes/Sensors/Multisite.php
CHANGED
@@ -5,7 +5,9 @@
|
|
5 |
* Multisite sensor file.
|
6 |
*
|
7 |
* @since 1.0.0
|
|
|
8 |
* @package wsal
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -14,11 +16,10 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
14 |
}
|
15 |
|
16 |
/**
|
17 |
-
* Multisite
|
18 |
*
|
19 |
* 4010 Existing user added to a site
|
20 |
* 4011 User removed from site
|
21 |
-
* 4012 New network user created
|
22 |
* 5008 Activated theme on network
|
23 |
* 5009 Deactivated theme from network
|
24 |
* 7000 New site added on the network
|
@@ -58,7 +59,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
58 |
add_action( 'add_user_to_blog', array( $this, 'EventUserAddedToBlog' ), 10, 3 );
|
59 |
add_action( 'remove_user_from_blog', array( $this, 'EventUserRemovedFromBlog' ), 10, 2 );
|
60 |
|
61 |
-
add_action( 'update_site_option', array( $this, 'on_network_option_change'), 10, 4 );
|
62 |
}
|
63 |
|
64 |
/**
|
@@ -207,11 +208,13 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
207 |
public function EventNewBlog( $new_blog ) {
|
208 |
$blog_id = $new_blog->blog_id;
|
209 |
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
|
|
|
|
215 |
$network = get_network( $new_blog->network_id );
|
216 |
if ( ! $network ) {
|
217 |
$network = get_network();
|
@@ -232,7 +235,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
232 |
array(
|
233 |
'BlogID' => $blog_id,
|
234 |
'SiteName' => $blog_title,
|
235 |
-
'BlogURL' => $blog_url
|
236 |
)
|
237 |
);
|
238 |
}
|
@@ -371,6 +374,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
371 |
* New network user created.
|
372 |
*
|
373 |
* @param WSAL_AlertManager $mgr - Instance of Alert Manager.
|
|
|
374 |
*/
|
375 |
public function MustNotContainCreateUser( WSAL_AlertManager $mgr ) {
|
376 |
return ! $mgr->WillTrigger( 4012 );
|
5 |
* Multisite sensor file.
|
6 |
*
|
7 |
* @since 1.0.0
|
8 |
+
*
|
9 |
* @package wsal
|
10 |
+
* @subpackage sensors
|
11 |
*/
|
12 |
|
13 |
// Exit if accessed directly.
|
16 |
}
|
17 |
|
18 |
/**
|
19 |
+
* Multisite sensor.
|
20 |
*
|
21 |
* 4010 Existing user added to a site
|
22 |
* 4011 User removed from site
|
|
|
23 |
* 5008 Activated theme on network
|
24 |
* 5009 Deactivated theme from network
|
25 |
* 7000 New site added on the network
|
59 |
add_action( 'add_user_to_blog', array( $this, 'EventUserAddedToBlog' ), 10, 3 );
|
60 |
add_action( 'remove_user_from_blog', array( $this, 'EventUserRemovedFromBlog' ), 10, 2 );
|
61 |
|
62 |
+
add_action( 'update_site_option', array( $this, 'on_network_option_change' ), 10, 4 );
|
63 |
}
|
64 |
|
65 |
/**
|
208 |
public function EventNewBlog( $new_blog ) {
|
209 |
$blog_id = $new_blog->blog_id;
|
210 |
|
211 |
+
/*
|
212 |
+
* Site meta data nor options are not setup at this points so get_blog_option and get_home_url are not
|
213 |
+
* returning anything for the new blog.
|
214 |
+
*
|
215 |
+
* The following code to work out the correct URL for the new site was taken from ms-site.php (WP 5.7).
|
216 |
+
* @see https://github.com/WordPress/WordPress/blob/5.7/wp-includes/ms-site.php#L673
|
217 |
+
*/
|
218 |
$network = get_network( $new_blog->network_id );
|
219 |
if ( ! $network ) {
|
220 |
$network = get_network();
|
235 |
array(
|
236 |
'BlogID' => $blog_id,
|
237 |
'SiteName' => $blog_title,
|
238 |
+
'BlogURL' => $blog_url,
|
239 |
)
|
240 |
);
|
241 |
}
|
374 |
* New network user created.
|
375 |
*
|
376 |
* @param WSAL_AlertManager $mgr - Instance of Alert Manager.
|
377 |
+
* @return bool
|
378 |
*/
|
379 |
public function MustNotContainCreateUser( WSAL_AlertManager $mgr ) {
|
380 |
return ! $mgr->WillTrigger( 4012 );
|
classes/Sensors/MultisiteSignUp.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Sensor: Multisite sign-up
|
4 |
+
*
|
5 |
+
* Multisite sign-up sensor file.
|
6 |
+
*
|
7 |
+
* @since 4.4.0
|
8 |
+
*
|
9 |
+
* @package wsal
|
10 |
+
* @subpackage sensors
|
11 |
+
*/
|
12 |
+
|
13 |
+
// Exit if accessed directly.
|
14 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
15 |
+
exit;
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Multisite sign-up sensor.
|
20 |
+
*
|
21 |
+
* 4013 User has been activated
|
22 |
+
* 4024 User has signed up to the network
|
23 |
+
*
|
24 |
+
* @package wsal
|
25 |
+
* @subpackage sensors
|
26 |
+
*/
|
27 |
+
class WSAL_Sensors_MultisiteSignUp extends WSAL_AbstractSensor {
|
28 |
+
/**
|
29 |
+
* {@inheritDoc}
|
30 |
+
*/
|
31 |
+
public function HookEvents() {
|
32 |
+
add_action( 'after_signup_user', array( $this, 'handle_multisite_user_signup' ), 10, 4 );
|
33 |
+
add_action( 'wpmu_activate_user', array( $this, 'handle_multisite_user_activation' ), 10, 3 );
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Function handles new multisite user activation.
|
38 |
+
*
|
39 |
+
* @param int $user_id User ID.
|
40 |
+
* @param string $password User password.
|
41 |
+
* @param array $meta Signup meta data.
|
42 |
+
*/
|
43 |
+
public function handle_multisite_user_activation( $user_id, $password, $meta ) {
|
44 |
+
$user = get_userdata( $user_id );
|
45 |
+
if ( ! $user instanceof WP_User ) {
|
46 |
+
// Bail if the user is not valid for some reason.
|
47 |
+
return;
|
48 |
+
}
|
49 |
+
|
50 |
+
$new_user_data = array(
|
51 |
+
'Roles' => is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles,
|
52 |
+
'Username' => $user->user_login,
|
53 |
+
'FirstName' => ! empty( $user->user_firstname ) ? $user->user_firstname : '',
|
54 |
+
'LastName' => ! empty( $user->user_lastname ) ? $user->user_lastname : '',
|
55 |
+
);
|
56 |
+
|
57 |
+
$event_data = array(
|
58 |
+
'NewUserID' => $user_id,
|
59 |
+
'NewUserData' => (object) $new_user_data,
|
60 |
+
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
61 |
+
);
|
62 |
+
|
63 |
+
$this->plugin->alerts->TriggerIf( 4013, $event_data, array( $this, 'must_not_contain_create_user' ) );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Function handles multisite user sign-ups.
|
68 |
+
*
|
69 |
+
* Caution: there is no entry in the users table at this point.
|
70 |
+
*
|
71 |
+
* @param string $user The user's requested login name.
|
72 |
+
* @param string $user_email The user's email address.
|
73 |
+
* @param string $key The user's activation key.
|
74 |
+
* @param array $meta Signup meta data. Default empty array.
|
75 |
+
*/
|
76 |
+
public function handle_multisite_user_signup( $user, $user_email, $key, $meta ) {
|
77 |
+
$this->plugin->alerts->TriggerIf(
|
78 |
+
4024,
|
79 |
+
array(
|
80 |
+
'username' => $user,
|
81 |
+
'email_address' => $user_email,
|
82 |
+
),
|
83 |
+
array( $this, 'must_not_contain_create_user' )
|
84 |
+
);
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Callback that checks if event 4012 is already in the pipeline.
|
89 |
+
*
|
90 |
+
* @param WSAL_AlertManager $manager - Instance of WSAL_AlertManager.
|
91 |
+
*/
|
92 |
+
public function must_not_contain_create_user( WSAL_AlertManager $manager ) {
|
93 |
+
return ! $manager->WillTrigger( 4012 );
|
94 |
+
}
|
95 |
+
}
|
classes/Sensors/Public.php
DELETED
@@ -1,64 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Sensor: Public Activity
|
4 |
-
*
|
5 |
-
* Public/Visitor activity sensor class file.
|
6 |
-
*
|
7 |
-
* @since 3.3
|
8 |
-
* @package wsal
|
9 |
-
*/
|
10 |
-
|
11 |
-
// Exit if accessed directly.
|
12 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
-
exit;
|
14 |
-
}
|
15 |
-
|
16 |
-
/**
|
17 |
-
* System Activity sensor.
|
18 |
-
*
|
19 |
-
* @package wsal
|
20 |
-
*/
|
21 |
-
class WSAL_Sensors_Public extends WSAL_AbstractSensor {
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Listening to events using WP hooks.
|
25 |
-
*/
|
26 |
-
public function HookEvents() {
|
27 |
-
add_action( 'user_register', array( $this, 'event_user_register' ) );
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Triggered when a user is registered.
|
32 |
-
*
|
33 |
-
* This function is identical to function WSAL_Sensors_FrontendRegister::event_user_register. We will keep the
|
34 |
-
* duplication until some autoloading improvements are made.
|
35 |
-
*
|
36 |
-
* @param int $user_id - User ID of the registered user.
|
37 |
-
*/
|
38 |
-
public function event_user_register( $user_id ) {
|
39 |
-
$plugin = WpSecurityAuditLog::GetInstance();
|
40 |
-
$user = get_userdata( $user_id );
|
41 |
-
$event = $plugin->IsMultisite() ? 4012 : ( is_user_logged_in() ? 4001 : 4000 );
|
42 |
-
$current_user = wp_get_current_user();
|
43 |
-
|
44 |
-
$new_user_data = array(
|
45 |
-
'Username' => $user->user_login,
|
46 |
-
'Email' => $user->user_email,
|
47 |
-
'Roles' => is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles,
|
48 |
-
);
|
49 |
-
|
50 |
-
if ( 4000 != $event ) {
|
51 |
-
$new_user_data['FirstName'] = ! empty( $user->user_firstname ) ? $user->user_firstname : '';
|
52 |
-
$new_user_data['LastName'] = ! empty( $user->user_lastname ) ? $user->user_lastname : '';
|
53 |
-
}
|
54 |
-
|
55 |
-
$event_data = array(
|
56 |
-
'NewUserID' => $user_id,
|
57 |
-
'UserChanger' => ! empty( $current_user ) ? $current_user->user_login : '',
|
58 |
-
'NewUserData' => (object) $new_user_data,
|
59 |
-
'EditUserLink' => add_query_arg( 'user_id', $user->ID, admin_url( 'user-edit.php' ) ),
|
60 |
-
);
|
61 |
-
|
62 |
-
$plugin->alerts->Trigger( $event, $event_data, true );
|
63 |
-
}
|
64 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/Sensors/Register.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* User registration sensor file.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage sensors
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit; // Exit if accessed directly.
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* User registration sensor.
|
15 |
+
*
|
16 |
+
* 4000 New user was created on WordPress
|
17 |
+
*
|
18 |
+
* @package wsal
|
19 |
+
* @subpackage sensors
|
20 |
+
*/
|
21 |
+
class WSAL_Sensors_Register extends WSAL_AbstractSensor {
|
22 |
+
/**
|
23 |
+
* {@inheritDoc}
|
24 |
+
*/
|
25 |
+
public function HookEvents() {
|
26 |
+
/*
|
27 |
+
* Default WordPress registration utilizes action 'register_new_user', but we cannot rely on it to detect
|
28 |
+
* a front-end registration implemented by a third party. We hook into the action 'user_register' because it is
|
29 |
+
* part of the function 'wp_insert_user' that definitely runs.
|
30 |
+
*/
|
31 |
+
add_action( 'user_register', array( $this, 'event_user_register' ), 10, 1 );
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* When a user registers, action 'user_register' is fired because it is part of the function 'wp_insert_user'. We
|
36 |
+
* can assume event 4000 if the current session is not logged in.
|
37 |
+
*
|
38 |
+
* @param int $user_id - User ID of the registered user.
|
39 |
+
*/
|
40 |
+
public function event_user_register( $user_id ) {
|
41 |
+
if ( is_user_logged_in() ) {
|
42 |
+
// We bail if the user is logged in. That is no longer user registration, but user creation.
|
43 |
+
return;
|
44 |
+
}
|
45 |
+
|
46 |
+
$user = get_userdata( $user_id );
|
47 |
+
if ( ! $user instanceof WP_User ) {
|
48 |
+
// Bail if the user is not valid for some reason.
|
49 |
+
return;
|
50 |
+
}
|
51 |
+
|
52 |
+
$new_user_data = array(
|
53 |
+
'Username' => $user->user_login,
|
54 |
+
'Roles' => is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles,
|
55 |
+
);
|
56 |
+
|
57 |
+
$event_data = array(
|
58 |
+
'NewUserID' => $user_id,
|
59 |
+
'NewUserData' => (object) $new_user_data,
|
60 |
+
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
61 |
+
);
|
62 |
+
|
63 |
+
if ( $this->IsMultisite() ) {
|
64 |
+
// Registration should not be logged on multisite if event 4024 is fired.
|
65 |
+
$this->plugin->alerts->TriggerIf(
|
66 |
+
4000,
|
67 |
+
$event_data,
|
68 |
+
/**
|
69 |
+
* Don't log if event 4024 is fired.
|
70 |
+
*
|
71 |
+
* @param WSAL_AlertManager $mgr - Instance of WSAL_AlertManager.
|
72 |
+
*/
|
73 |
+
function ( WSAL_AlertManager $mgr ) {
|
74 |
+
return ! $mgr->WillTrigger( 4013 );
|
75 |
+
}
|
76 |
+
);
|
77 |
+
} else {
|
78 |
+
$this->plugin->alerts->Trigger( 4000, $event_data, true );
|
79 |
+
}
|
80 |
+
|
81 |
+
}
|
82 |
+
}
|
classes/Sensors/System.php
CHANGED
@@ -413,6 +413,24 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
413 |
);
|
414 |
}
|
415 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
416 |
}
|
417 |
|
418 |
/**
|
413 |
);
|
414 |
}
|
415 |
}
|
416 |
+
|
417 |
+
// Site title.
|
418 |
+
if ( $is_option_page
|
419 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'general-options' )
|
420 |
+
&& isset( $post_array['blogname'] ) ) {
|
421 |
+
$previous_value = get_option( 'blogname' );
|
422 |
+
$new_value = ( ! empty( $post_array['blogname'] ) ) ? $post_array['blogname'] : '';
|
423 |
+
|
424 |
+
if ( $previous_value !== $new_value ) {
|
425 |
+
$this->plugin->alerts->Trigger(
|
426 |
+
6059,
|
427 |
+
array(
|
428 |
+
'previous_value' => $previous_value,
|
429 |
+
'new_value' => $new_value,
|
430 |
+
)
|
431 |
+
);
|
432 |
+
}
|
433 |
+
}
|
434 |
}
|
435 |
|
436 |
/**
|
classes/Sensors/UserProfile.php
CHANGED
@@ -4,8 +4,10 @@
|
|
4 |
*
|
5 |
* User profile sensor file.
|
6 |
*
|
7 |
-
* @since 1.0.0
|
8 |
* @package wsal
|
|
|
|
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -16,7 +18,6 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
16 |
/**
|
17 |
* User Profiles sensor.
|
18 |
*
|
19 |
-
* 4000 New user was created on WordPress
|
20 |
* 4001 User created another WordPress user
|
21 |
* 4002 The role of a user was changed by another WordPress user
|
22 |
* 4003 User has changed his or her password
|
@@ -41,7 +42,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
41 |
protected $old_superadmins;
|
42 |
|
43 |
/**
|
44 |
-
*
|
45 |
*/
|
46 |
public function HookEvents() {
|
47 |
add_action( 'profile_update', array( $this, 'event_user_updated' ), 10, 2 );
|
@@ -56,15 +57,22 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
56 |
add_action( 'update_user_meta', array( $this, 'event_application_password_added' ), 10, 4 );
|
57 |
add_action( 'retrieve_password', array( $this, 'event_password_reset_link_sent' ), 10, 1 );
|
58 |
|
|
|
|
|
59 |
}
|
60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
public function event_application_password_added( $meta_id, $user_id, $meta_key, $_meta_value ) {
|
62 |
|
63 |
// Filter global arrays for security.
|
64 |
-
$post_array = filter_input_array( INPUT_POST );
|
65 |
-
$get_array = filter_input_array( INPUT_GET );
|
66 |
$server_array = filter_input_array( INPUT_SERVER );
|
67 |
-
|
68 |
if ( ! isset( $server_array['HTTP_REFERER'] ) || ! isset( $server_array['REQUEST_URI'] ) ) {
|
69 |
return;
|
70 |
}
|
@@ -72,7 +80,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
72 |
// Check the page which is performing this change.
|
73 |
$referer_check = pathinfo( $server_array['HTTP_REFERER'] );
|
74 |
$referer_check = $referer_check['filename'];
|
75 |
-
$referer_check = ( strpos( $referer_check, '.' ) !== false ) ? strstr( $referer_check
|
76 |
|
77 |
$is_correct_referer_and_action = false;
|
78 |
|
@@ -80,14 +88,17 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
80 |
$is_correct_referer_and_action = true;
|
81 |
}
|
82 |
|
83 |
-
// Ensure we are
|
84 |
-
if ( $is_correct_referer_and_action && strpos( $server_array['REQUEST_URI'], '/wp/v2/users/'. $user_id .'/application-passwords' ) !== false ) {
|
85 |
|
86 |
$old_value = get_user_meta( $user_id, '_application_passwords', true );
|
87 |
|
88 |
$current_user = get_user_by( 'id', $user_id );
|
89 |
$current_userdata = get_userdata( $user_id );
|
90 |
-
$current_user_roles = implode( ', ', array_map( array(
|
|
|
|
|
|
|
91 |
$event_id = ( 'user-edit' === $referer_check ) ? 4026 : 4025;
|
92 |
|
93 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
@@ -100,19 +111,17 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
100 |
'firstname' => ( empty( $current_user->user_firstname ) ) ? ' ' : $current_user->user_firstname,
|
101 |
'lastname' => ( empty( $current_user->user_lastname ) ) ? ' ' : $current_user->user_lastname,
|
102 |
'CurrentUserID' => $current_user->ID,
|
103 |
-
'friendly_name' => sanitize_text_field( $_POST['name'] ),
|
104 |
'EventType' => 'added',
|
105 |
)
|
106 |
);
|
107 |
-
}
|
108 |
-
|
109 |
-
|
110 |
-
elseif ( ! empty( $old_value ) && count( $old_value ) > 1 && empty( $_meta_value ) ) {
|
111 |
-
$event_id = ( 'user-edit' === $referer_check ) ? 4028 : 4027;
|
112 |
|
113 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
114 |
$this->plugin->alerts->Trigger(
|
115 |
-
$event_id
|
116 |
array(
|
117 |
'roles' => $current_user_roles,
|
118 |
'login' => $current_user->user_login,
|
@@ -122,10 +131,8 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
122 |
'EventType' => 'revoked',
|
123 |
)
|
124 |
);
|
125 |
-
}
|
126 |
-
|
127 |
-
// Check the item that was removed.
|
128 |
-
elseif ( count( $_meta_value ) < count( $old_value ) ) {
|
129 |
$revoked_pw = array_diff( array_map( 'serialize', $old_value ), array_map( 'serialize', $_meta_value ) );
|
130 |
$revoked_pw = array_values( array_map( 'unserialize', $revoked_pw ) );
|
131 |
$revoked_pw_name = $revoked_pw[0]['name'];
|
@@ -133,7 +140,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
133 |
|
134 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
135 |
$this->plugin->alerts->Trigger(
|
136 |
-
$event_id
|
137 |
array(
|
138 |
'roles' => $current_user_roles,
|
139 |
'login' => $current_user->user_login,
|
@@ -146,14 +153,13 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
146 |
);
|
147 |
}
|
148 |
}
|
149 |
-
|
150 |
}
|
151 |
|
152 |
/**
|
153 |
* Method: Support for Ultimate Member email change
|
154 |
* alert.
|
155 |
*
|
156 |
-
* @param int $user_id
|
157 |
* @param WP_User $old_userdata - Old WP_User object.
|
158 |
*/
|
159 |
public function event_user_updated( $user_id, $old_userdata ) {
|
@@ -215,6 +221,23 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
215 |
);
|
216 |
}
|
217 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
// Alert if role has changed via Members plugin.
|
219 |
if ( isset( $_POST['members_user_roles'] ) && ! empty( $_POST['members_user_roles'] ) ) {
|
220 |
if ( $old_userdata->roles !== $_POST['members_user_roles'] ) {
|
@@ -226,9 +249,10 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
226 |
/**
|
227 |
* Triggered when a user role is changed.
|
228 |
*
|
229 |
-
* @param int
|
230 |
-
* @param string
|
231 |
-
* @param array
|
|
|
232 |
*/
|
233 |
public function event_user_role_changed( $user_id, $new_role, $old_roles, $use_posted_data = false ) {
|
234 |
// Get WP_User object.
|
@@ -331,9 +355,9 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
331 |
*
|
332 |
* Triggers when a user is granted super admin access.
|
333 |
*
|
334 |
-
* @since 3.4
|
335 |
-
*
|
336 |
* @param int $user_id - ID of the user that was granted Super Admin privileges.
|
|
|
|
|
337 |
*/
|
338 |
public function event_super_access_granted( $user_id ) {
|
339 |
$user = get_userdata( $user_id );
|
@@ -357,9 +381,9 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
357 |
*
|
358 |
* Triggers when a user is revoked super admin access.
|
359 |
*
|
360 |
-
* @since 3.4
|
361 |
-
*
|
362 |
* @param int $user_id - ID of the user that was revoked Super Admin privileges.
|
|
|
|
|
363 |
*/
|
364 |
public function event_super_access_revoked( $user_id ) {
|
365 |
$user = get_userdata( $user_id );
|
@@ -384,10 +408,13 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
384 |
* @param string $user_login User's login name.
|
385 |
*/
|
386 |
public function event_password_reset_link_sent( $user_login ) {
|
387 |
-
$current_user
|
388 |
|
389 |
$current_userdata = get_userdata( $current_user->ID );
|
390 |
-
$current_user_roles = implode( ', ', array_map( array(
|
|
|
|
|
|
|
391 |
|
392 |
$this->plugin->alerts->Trigger(
|
393 |
4029,
|
@@ -405,13 +432,14 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
405 |
/**
|
406 |
* Remove BBPress Prefix from User Role.
|
407 |
*
|
408 |
-
* @since 3.4
|
409 |
-
*
|
410 |
* @param string $user_role - User role.
|
|
|
411 |
* @return string
|
|
|
412 |
*/
|
413 |
public function filter_role_names( $user_role ) {
|
414 |
global $wp_roles;
|
|
|
415 |
return isset( $wp_roles->role_names[ $user_role ] ) ? $wp_roles->role_names[ $user_role ] : false;
|
416 |
}
|
417 |
|
@@ -438,4 +466,48 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
438 |
|| $mgr->WillOrHasTriggered( 4001 )
|
439 |
);
|
440 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
441 |
}
|
4 |
*
|
5 |
* User profile sensor file.
|
6 |
*
|
|
|
7 |
* @package wsal
|
8 |
+
* @subpackage sensors
|
9 |
+
*
|
10 |
+
* @since 1.0.0
|
11 |
*/
|
12 |
|
13 |
// Exit if accessed directly.
|
18 |
/**
|
19 |
* User Profiles sensor.
|
20 |
*
|
|
|
21 |
* 4001 User created another WordPress user
|
22 |
* 4002 The role of a user was changed by another WordPress user
|
23 |
* 4003 User has changed his or her password
|
42 |
protected $old_superadmins;
|
43 |
|
44 |
/**
|
45 |
+
* {@inheritDoc}
|
46 |
*/
|
47 |
public function HookEvents() {
|
48 |
add_action( 'profile_update', array( $this, 'event_user_updated' ), 10, 2 );
|
57 |
add_action( 'update_user_meta', array( $this, 'event_application_password_added' ), 10, 4 );
|
58 |
add_action( 'retrieve_password', array( $this, 'event_password_reset_link_sent' ), 10, 1 );
|
59 |
|
60 |
+
// We hook into action 'user_register' because it is part of the function 'wp_insert_user'.
|
61 |
+
add_action( 'user_register', array( $this, 'on_user_register' ), 10, 1 );
|
62 |
}
|
63 |
|
64 |
+
/**
|
65 |
+
* Captures addition of application passwords.
|
66 |
+
*
|
67 |
+
* @param int $meta_id ID of the metadata entry to update.
|
68 |
+
* @param int $user_id ID of the user metadata is for.
|
69 |
+
* @param string $meta_key Metadata key.
|
70 |
+
* @param mixed $_meta_value Metadata value. Serialized if non-scalar.
|
71 |
+
*/
|
72 |
public function event_application_password_added( $meta_id, $user_id, $meta_key, $_meta_value ) {
|
73 |
|
74 |
// Filter global arrays for security.
|
|
|
|
|
75 |
$server_array = filter_input_array( INPUT_SERVER );
|
|
|
76 |
if ( ! isset( $server_array['HTTP_REFERER'] ) || ! isset( $server_array['REQUEST_URI'] ) ) {
|
77 |
return;
|
78 |
}
|
80 |
// Check the page which is performing this change.
|
81 |
$referer_check = pathinfo( $server_array['HTTP_REFERER'] );
|
82 |
$referer_check = $referer_check['filename'];
|
83 |
+
$referer_check = ( strpos( $referer_check, '.' ) !== false ) ? strstr( $referer_check, '.', true ) : $referer_check;
|
84 |
|
85 |
$is_correct_referer_and_action = false;
|
86 |
|
88 |
$is_correct_referer_and_action = true;
|
89 |
}
|
90 |
|
91 |
+
// Ensure we are dealing with the correct request.
|
92 |
+
if ( $is_correct_referer_and_action && strpos( $server_array['REQUEST_URI'], '/wp/v2/users/' . $user_id . '/application-passwords' ) !== false ) {
|
93 |
|
94 |
$old_value = get_user_meta( $user_id, '_application_passwords', true );
|
95 |
|
96 |
$current_user = get_user_by( 'id', $user_id );
|
97 |
$current_userdata = get_userdata( $user_id );
|
98 |
+
$current_user_roles = implode( ', ', array_map( array(
|
99 |
+
$this,
|
100 |
+
'filter_role_names'
|
101 |
+
), $current_userdata->roles ) );
|
102 |
$event_id = ( 'user-edit' === $referer_check ) ? 4026 : 4025;
|
103 |
|
104 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
111 |
'firstname' => ( empty( $current_user->user_firstname ) ) ? ' ' : $current_user->user_firstname,
|
112 |
'lastname' => ( empty( $current_user->user_lastname ) ) ? ' ' : $current_user->user_lastname,
|
113 |
'CurrentUserID' => $current_user->ID,
|
114 |
+
'friendly_name' => sanitize_text_field( wp_unslash( $_POST['name'] ) ),
|
115 |
'EventType' => 'added',
|
116 |
)
|
117 |
);
|
118 |
+
} elseif ( ! empty( $old_value ) && count( $old_value ) > 1 && empty( $_meta_value ) ) {
|
119 |
+
// Check if all have been removed.
|
120 |
+
$event_id = ( 'user-edit' === $referer_check ) ? 4028 : 4027;
|
|
|
|
|
121 |
|
122 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
123 |
$this->plugin->alerts->Trigger(
|
124 |
+
$event_id,
|
125 |
array(
|
126 |
'roles' => $current_user_roles,
|
127 |
'login' => $current_user->user_login,
|
131 |
'EventType' => 'revoked',
|
132 |
)
|
133 |
);
|
134 |
+
} elseif ( count( $_meta_value ) < count( $old_value ) ) {
|
135 |
+
// Check the item that was removed.
|
|
|
|
|
136 |
$revoked_pw = array_diff( array_map( 'serialize', $old_value ), array_map( 'serialize', $_meta_value ) );
|
137 |
$revoked_pw = array_values( array_map( 'unserialize', $revoked_pw ) );
|
138 |
$revoked_pw_name = $revoked_pw[0]['name'];
|
140 |
|
141 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
142 |
$this->plugin->alerts->Trigger(
|
143 |
+
$event_id,
|
144 |
array(
|
145 |
'roles' => $current_user_roles,
|
146 |
'login' => $current_user->user_login,
|
153 |
);
|
154 |
}
|
155 |
}
|
|
|
156 |
}
|
157 |
|
158 |
/**
|
159 |
* Method: Support for Ultimate Member email change
|
160 |
* alert.
|
161 |
*
|
162 |
+
* @param int $user_id - User ID.
|
163 |
* @param WP_User $old_userdata - Old WP_User object.
|
164 |
*/
|
165 |
public function event_user_updated( $user_id, $old_userdata ) {
|
221 |
);
|
222 |
}
|
223 |
|
224 |
+
// Alert if website URL is changed.
|
225 |
+
if ( $old_userdata->user_url !== $new_userdata->user_url ) {
|
226 |
+
$user_roles = implode( ', ', array_map( array( $this, 'filter_role_names' ), $new_userdata->roles ) );
|
227 |
+
$this->plugin->alerts->Trigger(
|
228 |
+
4021,
|
229 |
+
array(
|
230 |
+
'TargetUsername' => $new_userdata->user_login,
|
231 |
+
'old_url' => $old_userdata->user_url,
|
232 |
+
'new_url' => $new_userdata->user_url,
|
233 |
+
'Roles' => $user_roles,
|
234 |
+
'FirstName' => $new_userdata->user_firstname,
|
235 |
+
'LastName' => $new_userdata->user_lastname,
|
236 |
+
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
237 |
+
)
|
238 |
+
);
|
239 |
+
}
|
240 |
+
|
241 |
// Alert if role has changed via Members plugin.
|
242 |
if ( isset( $_POST['members_user_roles'] ) && ! empty( $_POST['members_user_roles'] ) ) {
|
243 |
if ( $old_userdata->roles !== $_POST['members_user_roles'] ) {
|
249 |
/**
|
250 |
* Triggered when a user role is changed.
|
251 |
*
|
252 |
+
* @param int $user_id User ID of the user.
|
253 |
+
* @param string $new_role New role.
|
254 |
+
* @param array $old_roles Array of old roles.
|
255 |
+
* @param boolean $use_posted_data If true, posted user data is used.
|
256 |
*/
|
257 |
public function event_user_role_changed( $user_id, $new_role, $old_roles, $use_posted_data = false ) {
|
258 |
// Get WP_User object.
|
355 |
*
|
356 |
* Triggers when a user is granted super admin access.
|
357 |
*
|
|
|
|
|
358 |
* @param int $user_id - ID of the user that was granted Super Admin privileges.
|
359 |
+
*
|
360 |
+
* @since 3.4
|
361 |
*/
|
362 |
public function event_super_access_granted( $user_id ) {
|
363 |
$user = get_userdata( $user_id );
|
381 |
*
|
382 |
* Triggers when a user is revoked super admin access.
|
383 |
*
|
|
|
|
|
384 |
* @param int $user_id - ID of the user that was revoked Super Admin privileges.
|
385 |
+
*
|
386 |
+
* @since 3.4
|
387 |
*/
|
388 |
public function event_super_access_revoked( $user_id ) {
|
389 |
$user = get_userdata( $user_id );
|
408 |
* @param string $user_login User's login name.
|
409 |
*/
|
410 |
public function event_password_reset_link_sent( $user_login ) {
|
411 |
+
$current_user = get_user_by( 'login', $user_login );
|
412 |
|
413 |
$current_userdata = get_userdata( $current_user->ID );
|
414 |
+
$current_user_roles = implode( ', ', array_map( array(
|
415 |
+
$this,
|
416 |
+
'filter_role_names'
|
417 |
+
), $current_userdata->roles ) );
|
418 |
|
419 |
$this->plugin->alerts->Trigger(
|
420 |
4029,
|
432 |
/**
|
433 |
* Remove BBPress Prefix from User Role.
|
434 |
*
|
|
|
|
|
435 |
* @param string $user_role - User role.
|
436 |
+
*
|
437 |
* @return string
|
438 |
+
* @since 3.4
|
439 |
*/
|
440 |
public function filter_role_names( $user_role ) {
|
441 |
global $wp_roles;
|
442 |
+
|
443 |
return isset( $wp_roles->role_names[ $user_role ] ) ? $wp_roles->role_names[ $user_role ] : false;
|
444 |
}
|
445 |
|
466 |
|| $mgr->WillOrHasTriggered( 4001 )
|
467 |
);
|
468 |
}
|
469 |
+
|
470 |
+
/**
|
471 |
+
* When a user is created (by any means other than direct database insert), action 'user_register' is fired because
|
472 |
+
* it is part of the function 'wp_insert_user'. We can assume one of the following events if the current session is
|
473 |
+
* logged in end event 4000 is not triggerred from elsewhere (it is also hooked into action 'user_register').
|
474 |
+
*
|
475 |
+
* - 4001 User created another WordPress user
|
476 |
+
* - 4012 New network user created
|
477 |
+
*
|
478 |
+
* @param int $user_id - User ID of the registered user.
|
479 |
+
*/
|
480 |
+
public function on_user_register( $user_id ) {
|
481 |
+
if ( ! is_user_logged_in() ) {
|
482 |
+
// We bail if the user is not logged in. That is no longer user creation, but a user registration.
|
483 |
+
return;
|
484 |
+
}
|
485 |
+
|
486 |
+
$user = get_userdata( $user_id );
|
487 |
+
if ( ! $user instanceof WP_User ) {
|
488 |
+
// Bail if the user is not valid for some reason.
|
489 |
+
return;
|
490 |
+
}
|
491 |
+
|
492 |
+
$new_user_data = array(
|
493 |
+
'Username' => $user->user_login,
|
494 |
+
'FirstName' => ! empty( $user->user_firstname ) ? $user->user_firstname : '',
|
495 |
+
'LastName' => ! empty( $user->user_lastname ) ? $user->user_lastname : '',
|
496 |
+
);
|
497 |
+
|
498 |
+
$event_code = $this->plugin->IsMultisite() ? 4012 : 4001;
|
499 |
+
if ( 4001 === $event_code ) {
|
500 |
+
$new_user_data['Roles'] = is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles;
|
501 |
+
} else if ( 4012 === $event_code ) {
|
502 |
+
$new_user_data['Email'] = $user->user_email;
|
503 |
+
}
|
504 |
+
|
505 |
+
$event_data = array(
|
506 |
+
'NewUserID' => $user_id,
|
507 |
+
'NewUserData' => (object) $new_user_data,
|
508 |
+
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
509 |
+
);
|
510 |
+
|
511 |
+
$this->plugin->alerts->Trigger( $event_code, $event_data, $this->plugin->IsMultisite() );
|
512 |
+
}
|
513 |
}
|
classes/Settings.php
CHANGED
@@ -202,7 +202,7 @@ class WSAL_Settings {
|
|
202 |
* @param boolean $newvalue - True if enabled.
|
203 |
*/
|
204 |
public function set_admin_bar_notif( $newvalue ) {
|
205 |
-
$this->_plugin->SetGlobalBooleanSetting( 'disable-admin-bar-notif', ! $newvalue );
|
206 |
}
|
207 |
|
208 |
/**
|
@@ -224,7 +224,7 @@ class WSAL_Settings {
|
|
224 |
* @param string $newvalue - New option value.
|
225 |
*/
|
226 |
public function set_admin_bar_notif_updates( $newvalue ) {
|
227 |
-
$this->_plugin->SetGlobalSetting( 'admin-bar-notif-updates', $newvalue );
|
228 |
}
|
229 |
|
230 |
/**
|
@@ -484,6 +484,11 @@ class WSAL_Settings {
|
|
484 |
return $this->_plugin->GetGlobalBooleanSetting( 'delete-data' );
|
485 |
}
|
486 |
|
|
|
|
|
|
|
|
|
|
|
487 |
public function SetDeleteData( $enabled ) {
|
488 |
$this->_plugin->SetGlobalBooleanSetting( 'delete-data', $enabled );
|
489 |
}
|
@@ -528,7 +533,7 @@ class WSAL_Settings {
|
|
528 |
|
529 |
|
530 |
$this->_viewers = $users_or_roles;
|
531 |
-
$this->_plugin->SetGlobalSetting( 'plugin-viewers', implode( ',', $this->_viewers ) );
|
532 |
}
|
533 |
|
534 |
/**
|
@@ -558,7 +563,7 @@ class WSAL_Settings {
|
|
558 |
$this->_plugin->alerts->Trigger( 6049, $alert_data );
|
559 |
}
|
560 |
|
561 |
-
$this->_plugin->SetGlobalSetting( 'restrict-plugin-settings', $setting );
|
562 |
}
|
563 |
|
564 |
/**
|
@@ -586,7 +591,7 @@ class WSAL_Settings {
|
|
586 |
* @since 4.1.3
|
587 |
*/
|
588 |
public function set_restrict_log_viewer( $setting ) {
|
589 |
-
$this->_plugin->SetGlobalSetting( 'restrict-log-viewer', $setting );
|
590 |
}
|
591 |
|
592 |
public function SetViewPerPage( $newvalue ) {
|
@@ -1471,10 +1476,11 @@ class WSAL_Settings {
|
|
1471 |
/**
|
1472 |
* Get the log limit for failed login attempts.
|
1473 |
*
|
|
|
1474 |
* @since 2.6.3
|
1475 |
*/
|
1476 |
public function get_failed_login_limit() {
|
1477 |
-
return $this->_plugin->GetGlobalSetting( 'log-failed-login-limit', 10 );
|
1478 |
}
|
1479 |
|
1480 |
/**
|
@@ -1494,10 +1500,11 @@ class WSAL_Settings {
|
|
1494 |
/**
|
1495 |
* Get the log limit for failed login attempts for visitor.
|
1496 |
*
|
|
|
1497 |
* @since 2.6.3
|
1498 |
*/
|
1499 |
public function get_visitor_failed_login_limit() {
|
1500 |
-
return $this->_plugin->GetGlobalSetting( 'log-visitor-failed-login-limit', 10 );
|
1501 |
}
|
1502 |
|
1503 |
|
@@ -1592,8 +1599,8 @@ class WSAL_Settings {
|
|
1592 |
) {
|
1593 |
// Check if freemius state is anonymous.
|
1594 |
if ( ! wsal_freemius()->is_premium() && 'anonymous' === $this->_plugin->GetGlobalSetting( 'freemius_state', 'anonymous' ) ) {
|
1595 |
-
// Update
|
1596 |
-
$this->_plugin->SetGlobalSetting( 'wsal_freemius_state', 'skipped' );
|
1597 |
|
1598 |
if ( ! $this->_plugin->IsMultisite() ) {
|
1599 |
wsal_freemius()->skip_connection(); // Opt out.
|
@@ -1613,7 +1620,7 @@ class WSAL_Settings {
|
|
1613 |
$this->SetIncognito( true ); // Incognito mode to hide WSAL on plugins page.
|
1614 |
$this->set_restrict_log_viewer( 'only_me' );
|
1615 |
$this->set_restrict_plugin_setting( 'only_me' );
|
1616 |
-
//
|
1617 |
$only_me_user_id = is_user_logged_in() ? get_current_user_id() : 1;
|
1618 |
$this->set_only_me_user_id( $only_me_user_id );
|
1619 |
$this->_plugin->SetGlobalBooleanSetting( 'mwp-child-stealth-mode', true ); // Save stealth mode option.
|
@@ -1759,7 +1766,7 @@ class WSAL_Settings {
|
|
1759 |
* @return boolean
|
1760 |
*/
|
1761 |
public function is_infinite_scroll() {
|
1762 |
-
return 'infinite-scroll' === $this->get_events_type_nav()
|
1763 |
}
|
1764 |
|
1765 |
/**
|
@@ -1783,7 +1790,6 @@ class WSAL_Settings {
|
|
1783 |
* @since 3.3.1.1
|
1784 |
*
|
1785 |
* @param string $nav_type - Navigation type.
|
1786 |
-
* @return string
|
1787 |
*/
|
1788 |
public function set_events_type_nav( $nav_type ) {
|
1789 |
$this->_plugin->SetGlobalSetting( 'events-nav-type', $nav_type );
|
@@ -1796,8 +1802,7 @@ class WSAL_Settings {
|
|
1796 |
*/
|
1797 |
public function get_plugin_settings() {
|
1798 |
global $wpdb;
|
1799 |
-
|
1800 |
-
return $plugin_options;
|
1801 |
}
|
1802 |
|
1803 |
/**
|
@@ -1996,9 +2001,7 @@ class WSAL_Settings {
|
|
1996 |
);
|
1997 |
|
1998 |
// Get the option.
|
1999 |
-
|
2000 |
-
|
2001 |
-
return $value;
|
2002 |
}
|
2003 |
|
2004 |
/**
|
@@ -2008,17 +2011,17 @@ class WSAL_Settings {
|
|
2008 |
* @return bool
|
2009 |
*/
|
2010 |
public static function set_frontend_events( $value = array() ) {
|
2011 |
-
return \WSAL\Helpers\Options::set_option_value_ignore_prefix( self::FRONT_END_EVENTS_OPTION_NAME, $value );
|
2012 |
}
|
2013 |
|
2014 |
/**
|
2015 |
* Stores the ID of user who restricted the plugin settings access to "only me".
|
2016 |
*
|
2017 |
-
* @param int $user_id
|
2018 |
* @since 4.1.3
|
2019 |
*/
|
2020 |
public function set_only_me_user_id( $user_id ) {
|
2021 |
-
$this->_plugin->SetGlobalSetting( 'only-me-user-id', $user_id );
|
2022 |
}
|
2023 |
|
2024 |
/**
|
@@ -2066,18 +2069,18 @@ class WSAL_Settings {
|
|
2066 |
}
|
2067 |
|
2068 |
public function determine_added_and_removed_items( $old_value, $value ) {
|
2069 |
-
$old_value
|
2070 |
-
$value
|
2071 |
-
$return
|
2072 |
-
$return[
|
2073 |
-
$return[
|
2074 |
|
2075 |
return $return;
|
2076 |
}
|
2077 |
|
2078 |
public function tidy_blank_values( $value ) {
|
2079 |
return ( empty( $value ) ) ? __( 'None provided', 'wp-security-audit-log' ) : $value;
|
2080 |
-
|
2081 |
|
2082 |
/**
|
2083 |
* Retrieves current database version.
|
@@ -2096,6 +2099,7 @@ class WSAL_Settings {
|
|
2096 |
* @since 4.3.2
|
2097 |
*/
|
2098 |
public function set_database_version( $version ) {
|
2099 |
-
$this->_plugin->SetGlobalSetting( 'db_version', $version );
|
2100 |
}
|
|
|
2101 |
}
|
202 |
* @param boolean $newvalue - True if enabled.
|
203 |
*/
|
204 |
public function set_admin_bar_notif( $newvalue ) {
|
205 |
+
$this->_plugin->SetGlobalBooleanSetting( 'disable-admin-bar-notif', ! $newvalue, true );
|
206 |
}
|
207 |
|
208 |
/**
|
224 |
* @param string $newvalue - New option value.
|
225 |
*/
|
226 |
public function set_admin_bar_notif_updates( $newvalue ) {
|
227 |
+
$this->_plugin->SetGlobalSetting( 'admin-bar-notif-updates', $newvalue, true );
|
228 |
}
|
229 |
|
230 |
/**
|
484 |
return $this->_plugin->GetGlobalBooleanSetting( 'delete-data' );
|
485 |
}
|
486 |
|
487 |
+
/**
|
488 |
+
* Sets the plugin setting that allows data deletion on plugin uninstall.
|
489 |
+
*
|
490 |
+
* @param mixed $enabled
|
491 |
+
*/
|
492 |
public function SetDeleteData( $enabled ) {
|
493 |
$this->_plugin->SetGlobalBooleanSetting( 'delete-data', $enabled );
|
494 |
}
|
533 |
|
534 |
|
535 |
$this->_viewers = $users_or_roles;
|
536 |
+
$this->_plugin->SetGlobalSetting( 'plugin-viewers', implode( ',', $this->_viewers ), true );
|
537 |
}
|
538 |
|
539 |
/**
|
563 |
$this->_plugin->alerts->Trigger( 6049, $alert_data );
|
564 |
}
|
565 |
|
566 |
+
$this->_plugin->SetGlobalSetting( 'restrict-plugin-settings', $setting, true );
|
567 |
}
|
568 |
|
569 |
/**
|
591 |
* @since 4.1.3
|
592 |
*/
|
593 |
public function set_restrict_log_viewer( $setting ) {
|
594 |
+
$this->_plugin->SetGlobalSetting( 'restrict-log-viewer', $setting, true );
|
595 |
}
|
596 |
|
597 |
public function SetViewPerPage( $newvalue ) {
|
1476 |
/**
|
1477 |
* Get the log limit for failed login attempts.
|
1478 |
*
|
1479 |
+
* @return int
|
1480 |
* @since 2.6.3
|
1481 |
*/
|
1482 |
public function get_failed_login_limit() {
|
1483 |
+
return intval($this->_plugin->GetGlobalSetting( 'log-failed-login-limit', 10 ));
|
1484 |
}
|
1485 |
|
1486 |
/**
|
1500 |
/**
|
1501 |
* Get the log limit for failed login attempts for visitor.
|
1502 |
*
|
1503 |
+
* @return int
|
1504 |
* @since 2.6.3
|
1505 |
*/
|
1506 |
public function get_visitor_failed_login_limit() {
|
1507 |
+
return intval( $this->_plugin->GetGlobalSetting( 'log-visitor-failed-login-limit', 10 ) );
|
1508 |
}
|
1509 |
|
1510 |
|
1599 |
) {
|
1600 |
// Check if freemius state is anonymous.
|
1601 |
if ( ! wsal_freemius()->is_premium() && 'anonymous' === $this->_plugin->GetGlobalSetting( 'freemius_state', 'anonymous' ) ) {
|
1602 |
+
// Update Freemius state to skipped.
|
1603 |
+
$this->_plugin->SetGlobalSetting( 'wsal_freemius_state', 'skipped', true );
|
1604 |
|
1605 |
if ( ! $this->_plugin->IsMultisite() ) {
|
1606 |
wsal_freemius()->skip_connection(); // Opt out.
|
1620 |
$this->SetIncognito( true ); // Incognito mode to hide WSAL on plugins page.
|
1621 |
$this->set_restrict_log_viewer( 'only_me' );
|
1622 |
$this->set_restrict_plugin_setting( 'only_me' );
|
1623 |
+
// Current user with fallback to default admin (in case this is triggered using WP CLI or something similar).
|
1624 |
$only_me_user_id = is_user_logged_in() ? get_current_user_id() : 1;
|
1625 |
$this->set_only_me_user_id( $only_me_user_id );
|
1626 |
$this->_plugin->SetGlobalBooleanSetting( 'mwp-child-stealth-mode', true ); // Save stealth mode option.
|
1766 |
* @return boolean
|
1767 |
*/
|
1768 |
public function is_infinite_scroll() {
|
1769 |
+
return 'infinite-scroll' === $this->get_events_type_nav();
|
1770 |
}
|
1771 |
|
1772 |
/**
|
1790 |
* @since 3.3.1.1
|
1791 |
*
|
1792 |
* @param string $nav_type - Navigation type.
|
|
|
1793 |
*/
|
1794 |
public function set_events_type_nav( $nav_type ) {
|
1795 |
$this->_plugin->SetGlobalSetting( 'events-nav-type', $nav_type );
|
1802 |
*/
|
1803 |
public function get_plugin_settings() {
|
1804 |
global $wpdb;
|
1805 |
+
return $wpdb->get_results( "SELECT * FROM $wpdb->options WHERE option_name LIKE 'wsal_%'" );
|
|
|
1806 |
}
|
1807 |
|
1808 |
/**
|
2001 |
);
|
2002 |
|
2003 |
// Get the option.
|
2004 |
+
return \WSAL\Helpers\Options::get_option_value_ignore_prefix( self::FRONT_END_EVENTS_OPTION_NAME, $default );
|
|
|
|
|
2005 |
}
|
2006 |
|
2007 |
/**
|
2011 |
* @return bool
|
2012 |
*/
|
2013 |
public static function set_frontend_events( $value = array() ) {
|
2014 |
+
return \WSAL\Helpers\Options::set_option_value_ignore_prefix( self::FRONT_END_EVENTS_OPTION_NAME, $value, true );
|
2015 |
}
|
2016 |
|
2017 |
/**
|
2018 |
* Stores the ID of user who restricted the plugin settings access to "only me".
|
2019 |
*
|
2020 |
+
* @param int $user_id User ID.
|
2021 |
* @since 4.1.3
|
2022 |
*/
|
2023 |
public function set_only_me_user_id( $user_id ) {
|
2024 |
+
$this->_plugin->SetGlobalSetting( 'only-me-user-id', $user_id, true );
|
2025 |
}
|
2026 |
|
2027 |
/**
|
2069 |
}
|
2070 |
|
2071 |
public function determine_added_and_removed_items( $old_value, $value ) {
|
2072 |
+
$old_value = ( ! is_array( $old_value ) ) ? explode( ',', $old_value ) : $old_value;
|
2073 |
+
$value = ( ! is_array( $value ) ) ? explode( ',', $value ) : $value;
|
2074 |
+
$return = array();
|
2075 |
+
$return['removed'] = array_filter( array_diff( $old_value, $value ) );
|
2076 |
+
$return['added'] = array_filter( array_diff( $value, $old_value ) );
|
2077 |
|
2078 |
return $return;
|
2079 |
}
|
2080 |
|
2081 |
public function tidy_blank_values( $value ) {
|
2082 |
return ( empty( $value ) ) ? __( 'None provided', 'wp-security-audit-log' ) : $value;
|
2083 |
+
}
|
2084 |
|
2085 |
/**
|
2086 |
* Retrieves current database version.
|
2099 |
* @since 4.3.2
|
2100 |
*/
|
2101 |
public function set_database_version( $version ) {
|
2102 |
+
$this->_plugin->SetGlobalSetting( 'db_version', $version, true );
|
2103 |
}
|
2104 |
+
|
2105 |
}
|
classes/ThirdPartyExtensions/AbstractExtension.php
CHANGED
@@ -104,5 +104,13 @@ if ( ! class_exists( 'WSAL_AbstractExtension' ) ) {
|
|
104 |
|
105 |
abstract public function get_color();
|
106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
}
|
108 |
}
|
104 |
|
105 |
abstract public function get_color();
|
106 |
|
107 |
+
/**
|
108 |
+
* Gets the filename of the plugin this extension is targetting.
|
109 |
+
*
|
110 |
+
* @return string Filename.
|
111 |
+
*
|
112 |
+
* @since 4.4.0
|
113 |
+
*/
|
114 |
+
abstract public function get_plugin_filename();
|
115 |
}
|
116 |
}
|
classes/ThirdPartyExtensions/BBPressExtension.php
CHANGED
@@ -10,12 +10,12 @@ if ( ! class_exists( 'WSAL_BBPressExtension' ) ) {
|
|
10 |
'addon_for' => 'bbpress',
|
11 |
'title' => $this->get_plugin_name(),
|
12 |
'image_filename' => 'bbpress.png',
|
13 |
-
'plugin_slug' =>
|
14 |
'plugin_basename' => 'wsal-bbpress.php',
|
15 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/wp-security-audit-log-add-on-for-bbpress.latest-stable.zip',
|
16 |
-
'event_tab_id' => '#
|
17 |
'plugin_description' => 'Keep a log of your sites bbPress activity, from forum and topic creation, user profile changes and more.',
|
18 |
-
)
|
19 |
);
|
20 |
|
21 |
// combine the two arrays.
|
@@ -35,7 +35,7 @@ if ( ! class_exists( 'WSAL_BBPressExtension' ) ) {
|
|
35 |
}
|
36 |
|
37 |
public function get_custom_post_types() {
|
38 |
-
return
|
39 |
}
|
40 |
|
41 |
public function get_plugin_name() {
|
@@ -49,5 +49,9 @@ if ( ! class_exists( 'WSAL_BBPressExtension' ) ) {
|
|
49 |
public function get_color() {
|
50 |
return '#8dc770';
|
51 |
}
|
|
|
|
|
|
|
|
|
52 |
}
|
53 |
}
|
10 |
'addon_for' => 'bbpress',
|
11 |
'title' => $this->get_plugin_name(),
|
12 |
'image_filename' => 'bbpress.png',
|
13 |
+
'plugin_slug' => $this->get_plugin_filename(),
|
14 |
'plugin_basename' => 'wsal-bbpress.php',
|
15 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/wp-security-audit-log-add-on-for-bbpress.latest-stable.zip',
|
16 |
+
'event_tab_id' => '#cat-bbpress-forums',
|
17 |
'plugin_description' => 'Keep a log of your sites bbPress activity, from forum and topic creation, user profile changes and more.',
|
18 |
+
),
|
19 |
);
|
20 |
|
21 |
// combine the two arrays.
|
35 |
}
|
36 |
|
37 |
public function get_custom_post_types() {
|
38 |
+
return array( 'forum', 'topic', 'reply' );
|
39 |
}
|
40 |
|
41 |
public function get_plugin_name() {
|
49 |
public function get_color() {
|
50 |
return '#8dc770';
|
51 |
}
|
52 |
+
|
53 |
+
public function get_plugin_filename() {
|
54 |
+
return 'wp-security-audit-log-add-on-for-bbpress/wsal-bbpress.php';
|
55 |
+
}
|
56 |
}
|
57 |
}
|
classes/ThirdPartyExtensions/GravityFormsExtension.php
CHANGED
@@ -10,9 +10,9 @@ if ( ! class_exists( 'WSAL_GravityFormsExtension' ) ) {
|
|
10 |
'addon_for' => 'gravityforms',
|
11 |
'title' => $this->get_plugin_name(),
|
12 |
'image_filename' => 'gravityforms.png',
|
13 |
-
'plugin_slug' =>
|
14 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/activity-log-gravity-forms.latest-stable.zip',
|
15 |
-
'event_tab_id' => '#
|
16 |
'plugin_description' => __( 'Keep a record of when someone adds, modifies or deletes forms, entries and more in the Gravity Forms plugin.', 'wp-security-audit-log' ),
|
17 |
)
|
18 |
);
|
@@ -44,5 +44,9 @@ if ( ! class_exists( 'WSAL_GravityFormsExtension' ) ) {
|
|
44 |
public function get_color() {
|
45 |
return '#F15A29';
|
46 |
}
|
|
|
|
|
|
|
|
|
47 |
}
|
48 |
}
|
10 |
'addon_for' => 'gravityforms',
|
11 |
'title' => $this->get_plugin_name(),
|
12 |
'image_filename' => 'gravityforms.png',
|
13 |
+
'plugin_slug' => $this->get_plugin_filename(),
|
14 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/activity-log-gravity-forms.latest-stable.zip',
|
15 |
+
'event_tab_id' => '#cat-gravity-forms',
|
16 |
'plugin_description' => __( 'Keep a record of when someone adds, modifies or deletes forms, entries and more in the Gravity Forms plugin.', 'wp-security-audit-log' ),
|
17 |
)
|
18 |
);
|
44 |
public function get_color() {
|
45 |
return '#F15A29';
|
46 |
}
|
47 |
+
|
48 |
+
public function get_plugin_filename() {
|
49 |
+
return 'activity-log-gravity-forms/activity-log-gravity-forms.php';
|
50 |
+
}
|
51 |
}
|
52 |
}
|
classes/ThirdPartyExtensions/TablePressExtension.php
CHANGED
@@ -10,12 +10,12 @@ if ( ! class_exists( 'WSAL_TablePressExtension' ) ) {
|
|
10 |
'addon_for' => 'tablepress',
|
11 |
'title' => $this->get_plugin_name(),
|
12 |
'image_filename' => 'tablepress.png',
|
13 |
-
'plugin_slug' =>
|
14 |
'plugin_basename' => 'tablepress.php',
|
15 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/activity-log-tablepress.latest-stable.zip',
|
16 |
-
'event_tab_id' => '#
|
17 |
'plugin_description' => 'Keep a log of all the changes in your TablePress tables.',
|
18 |
-
)
|
19 |
);
|
20 |
|
21 |
// combine the two arrays.
|
@@ -35,7 +35,7 @@ if ( ! class_exists( 'WSAL_TablePressExtension' ) ) {
|
|
35 |
}
|
36 |
|
37 |
public function get_custom_post_types() {
|
38 |
-
return
|
39 |
}
|
40 |
|
41 |
public function get_plugin_name() {
|
@@ -43,11 +43,15 @@ if ( ! class_exists( 'WSAL_TablePressExtension' ) ) {
|
|
43 |
}
|
44 |
|
45 |
public function get_plugin_icon_url() {
|
46 |
-
return 'https://ps.w.org/activity-log-
|
47 |
}
|
48 |
|
49 |
public function get_color() {
|
50 |
return '#a4286a';
|
51 |
}
|
|
|
|
|
|
|
|
|
52 |
}
|
53 |
}
|
10 |
'addon_for' => 'tablepress',
|
11 |
'title' => $this->get_plugin_name(),
|
12 |
'image_filename' => 'tablepress.png',
|
13 |
+
'plugin_slug' => $this->get_plugin_filename(),
|
14 |
'plugin_basename' => 'tablepress.php',
|
15 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/activity-log-tablepress.latest-stable.zip',
|
16 |
+
'event_tab_id' => '#cat-tablepress',
|
17 |
'plugin_description' => 'Keep a log of all the changes in your TablePress tables.',
|
18 |
+
),
|
19 |
);
|
20 |
|
21 |
// combine the two arrays.
|
35 |
}
|
36 |
|
37 |
public function get_custom_post_types() {
|
38 |
+
return array( 'tablepress_table' );
|
39 |
}
|
40 |
|
41 |
public function get_plugin_name() {
|
43 |
}
|
44 |
|
45 |
public function get_plugin_icon_url() {
|
46 |
+
return 'https://ps.w.org/activity-log-tablepress/assets/icon-128x128.png?rev=2393849';
|
47 |
}
|
48 |
|
49 |
public function get_color() {
|
50 |
return '#a4286a';
|
51 |
}
|
52 |
+
|
53 |
+
public function get_plugin_filename() {
|
54 |
+
return 'activity-log-tablepress/wsal-tablepress.php';
|
55 |
+
}
|
56 |
}
|
57 |
}
|
classes/ThirdPartyExtensions/WFCMExtension.php
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! class_exists( 'WSAL_WFCMExtension' ) ) {
|
4 |
+
|
5 |
+
class WSAL_WFCMExtension extends WSAL_AbstractExtension {
|
6 |
+
|
7 |
+
public function __construct() {
|
8 |
+
add_filter( 'wsal_append_dailynotification_email_content', [ $this, 'append_dailynotification_email_content' ], 10, 2 );
|
9 |
+
}
|
10 |
+
|
11 |
+
public function filter_installable_plugins( $plugins ) {
|
12 |
+
$new_plugin = array(
|
13 |
+
array(
|
14 |
+
'addon_for' => 'wfcm',
|
15 |
+
'title' => $this->get_plugin_name(),
|
16 |
+
'image_filename' => 'wfcm.png',
|
17 |
+
'plugin_slug' => $this->get_plugin_filename(),
|
18 |
+
'plugin_basename' => 'website-file-changes-monitor.php',
|
19 |
+
'plugin_url' => 'https://downloads.wordpress.org/plugin/website-file-changes-monitor.latest-stable.zip',
|
20 |
+
'event_tab_id' => '#cat-wfcm',
|
21 |
+
'plugin_description' => 'To keep a log of file changes please install Website File Changes Monitor, a plugin which is also developed by us.',
|
22 |
+
)
|
23 |
+
);
|
24 |
+
|
25 |
+
// combine the two arrays.
|
26 |
+
return array_merge( $plugins, $new_plugin );
|
27 |
+
}
|
28 |
+
|
29 |
+
public function add_event_codes( $addon_event_codes ) {
|
30 |
+
$new_event_codes = array(
|
31 |
+
'wfcm' => array(
|
32 |
+
'name' => $this->get_plugin_name(),
|
33 |
+
'event_ids' => array( 6028, 6029, 6030, 6031, 6032, 6033 ),
|
34 |
+
),
|
35 |
+
);
|
36 |
+
|
37 |
+
// combine the two arrays.
|
38 |
+
return array_merge( $addon_event_codes, $new_event_codes );
|
39 |
+
}
|
40 |
+
|
41 |
+
public function get_plugin_name() {
|
42 |
+
return 'Website File Changes Monitor';
|
43 |
+
}
|
44 |
+
|
45 |
+
public function get_plugin_icon_url() {
|
46 |
+
return 'https://ps.w.org/website-file-changes-monitor/assets/icon-128x128.png?rev=2393849';
|
47 |
+
}
|
48 |
+
|
49 |
+
public function get_color() {
|
50 |
+
return '#a4286a';
|
51 |
+
}
|
52 |
+
|
53 |
+
public function append_dailynotification_email_content( $body, $events ) {
|
54 |
+
|
55 |
+
if ( ! empty( $events ) ) {
|
56 |
+
foreach ( $events as $event ) {
|
57 |
+
if ( 6028 === $event->alert_id ) {
|
58 |
+
$files_modified[] = $event;
|
59 |
+
} elseif ( 6029 === $event->alert_id ) {
|
60 |
+
$files_added[] = $event;
|
61 |
+
} elseif ( 6030 === $event->alert_id ) {
|
62 |
+
$files_deleted[] = $event;
|
63 |
+
}
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
if ( class_exists( 'Website_File_Changes_Monitor' ) ) {
|
68 |
+
// File changes.
|
69 |
+
if ( ! empty( $files_added ) || ! empty( $files_modified ) || ! empty( $files_deleted ) ) {
|
70 |
+
$body .= '<!-- Website File Changes Start --><tr><td><table width="100%" cellpadding="0" cellspacing="0" border="0"><!-- Title Start --><tr><td style="font-family: Verdana, sans-serif; font-weight: bold; font-size: 20px; line-height: 28px; color: #404040; text-align: left; padding-bottom: 13px;">Website File Changes</td></tr><!-- Title End --><!-- Desc Start --><!-- Table Border Start --><tr><td style="padding-bottom: 40px;"><table width="100%" cellpadding="0" cellspacing="0" border="0">';
|
71 |
+
|
72 |
+
$body .= '<tr><td style="font-family: Verdana, sans-serif; font-weight: normal; font-size: 16px; line-height: 28px; color: #404040;padding-bottom: 20px;">During the last file integrity scan on '. date( 'd/m/Y', get_option( 'wfcm_last-scan-timestamp' ) ) .' at '. date( 'H:i:s', get_option( 'wfcm_last-scan-timestamp' ) ) .' we detected the following file changes:</td></tr>';
|
73 |
+
|
74 |
+
if ( ! empty( $files_added ) ) {
|
75 |
+
$body .= '<tr><td style="font-family: Verdana, sans-serif; font-weight: normal; font-size: 16px; line-height: 28px; color: #404040;padding-bottom: 5px;"><img src="' . $this->media['check'] . '" style="height: 14px; width: 14px; position: relative; top: 1px;" /> New files identified</td></tr>';
|
76 |
+
}
|
77 |
+
|
78 |
+
if ( ! empty( $files_modified ) ) {
|
79 |
+
$body .= '<tr><td style="font-family: Verdana, sans-serif; font-weight: normal; font-size: 16px; line-height: 28px; color: #404040;padding-bottom: 5px;padding-top: 0px;"><img src="' . $this->media['check'] . '" style="height: 14px; width: 14px; position: relative; top: 1px;" /> Some files were changed</td></tr>';
|
80 |
+
}
|
81 |
+
|
82 |
+
if ( ! empty( $files_deleted ) ) {
|
83 |
+
$body .= '<tr><td style="font-family: Verdana, sans-serif; font-weight: normal; font-size: 16px; line-height: 28px; color: #404040;padding-bottom: 5px;padding-top: 0px;"><img src="' . $this->media['check'] . '" style="height: 14px; width: 14px; position: relative; top: 1px;" /> Some files were deleted</td></tr>';
|
84 |
+
}
|
85 |
+
|
86 |
+
$body .= '<tr><td style="font-family: Verdana, sans-serif; font-weight: normal; font-size: 16px; line-height: 28px; color: #404040;padding-bottom: 20px;padding-top: 20px;">Click <a href="' . add_query_arg( 'page', 'wfcm-file-changes', admin_url( 'admin.php' ) ) . '" target="_blank" style="font-family: Verdana, sans-serif; font-weight: normal; font-size: 16px; line-height: 28px; color: #149247;">here</a> to see the file changes.</td></tr>';
|
87 |
+
|
88 |
+
$body .= '</table></td></tr><!-- Table Border Start --><!-- Desc End --></table></td></tr><!-- Website File Changes End -->';
|
89 |
+
}
|
90 |
+
|
91 |
+
// No changes to report
|
92 |
+
if ( empty( $files_added ) && empty( $files_modified ) && empty( $files_deleted ) && class_exists( 'Website_File_Changes_Monitor' ) ) {
|
93 |
+
$body .= '<!-- Website File Changes Start --><tr><td><table width="100%" cellpadding="0" cellspacing="0" border="0"><!-- Title Start --><tr><td style="font-family: Verdana, sans-serif; font-weight: bold; font-size: 20px; line-height: 28px; color: #404040; text-align: left; padding-bottom: 13px;">Website File Changes</td></tr><!-- Title End --><!-- Desc Start --><!-- Table Border Start --><tr><td style="padding-bottom: 40px;"><table width="100%" cellpadding="0" cellspacing="0" border="0">';
|
94 |
+
|
95 |
+
$body .= '<tr><td style="font-family: Verdana, sans-serif; font-weight: normal; font-size: 16px; line-height: 28px; color: #404040;padding-bottom: 5px;">Everything is looking good. No file changes detected during the last scan that ran on '. date( 'd/m/Y', get_option( 'wfcm_last-scan-timestamp' ) ) .' at '. date( 'H:i:s', get_option( 'wfcm_last-scan-timestamp' ) ) .'.</td></tr>';
|
96 |
+
|
97 |
+
$body .= '</table></td></tr><!-- Table Border Start --><!-- Desc End --></table></td></tr><!-- Website File Changes End -->';
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
// No WFCM plugin found.
|
102 |
+
if ( ! class_exists( 'Website_File_Changes_Monitor' ) ) {
|
103 |
+
$body .= '<!-- Website File Changes Start --><tr><td><table width="100%" cellpadding="0" cellspacing="0" border="0"><!-- Title Start --><tr><td style="font-family: Verdana, sans-serif; font-weight: bold; font-size: 20px; line-height: 28px; color: #404040; text-align: left; padding-bottom: 13px;">Website File Changes</td></tr><!-- Title End --><!-- Desc Start --><!-- Table Border Start --><tr><td style="padding-bottom: 40px;"><table width="100%" cellpadding="0" cellspacing="0" border="0">';
|
104 |
+
|
105 |
+
$body .= '<tr><td style="font-family: Verdana, sans-serif; font-weight: normal; font-size: 16px; line-height: 28px; color: #404040;padding-bottom: 20px;padding-top: 0px;"><img src="' . $this->media['check'] . '" style="height: 14px; width: 14px; position: relative; top: 1px;" /> To be alerted of file changes install the <a href="https://www.wpwhitesecurity.com/wordpress-plugins/website-file-changes-monitor/" target="_blank" style="font-family: Verdana, sans-serif; font-weight: normal; font-size: 16px; line-height: 28px; color: #149247;">Website File Changes Monitor</a>, a plugin we developed to detect file changes. Once installed, the plugin fully integrates with WP Activity Log.</td></tr>';
|
106 |
+
|
107 |
+
$body .= '</table></td></tr><!-- Table Border Start --><!-- Desc End --></table></td></tr><!-- Website File Changes End -->';
|
108 |
+
}
|
109 |
+
|
110 |
+
return $body;
|
111 |
+
}
|
112 |
+
|
113 |
+
public function get_plugin_filename() {
|
114 |
+
return 'website-file-changes-monitor/website-file-changes-monitor.php';
|
115 |
+
}
|
116 |
+
}
|
117 |
+
}
|
classes/ThirdPartyExtensions/WPFormsExtension.php
CHANGED
@@ -10,10 +10,10 @@ if ( ! class_exists( 'WSAL_WPFormsExtension' ) ) {
|
|
10 |
'addon_for' => 'wpforms',
|
11 |
'title' => $this->get_plugin_name(),
|
12 |
'image_filename' => 'wpforms.png',
|
13 |
-
'plugin_slug' =>
|
14 |
'plugin_basename' => 'wsal-wpforms.php',
|
15 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/wp-security-audit-log-add-on-for-wpforms.latest-stable.zip',
|
16 |
-
'event_tab_id' => '#
|
17 |
'plugin_description' => 'Keep a record of when someone adds, modifies or deletes forms, entries and more in the WPForms plugin.',
|
18 |
)
|
19 |
);
|
@@ -49,5 +49,9 @@ if ( ! class_exists( 'WSAL_WPFormsExtension' ) ) {
|
|
49 |
public function get_color() {
|
50 |
return '#e27730';
|
51 |
}
|
|
|
|
|
|
|
|
|
52 |
}
|
53 |
}
|
10 |
'addon_for' => 'wpforms',
|
11 |
'title' => $this->get_plugin_name(),
|
12 |
'image_filename' => 'wpforms.png',
|
13 |
+
'plugin_slug' => $this->get_plugin_filename(),
|
14 |
'plugin_basename' => 'wsal-wpforms.php',
|
15 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/wp-security-audit-log-add-on-for-wpforms.latest-stable.zip',
|
16 |
+
'event_tab_id' => '#cat-wpforms',
|
17 |
'plugin_description' => 'Keep a record of when someone adds, modifies or deletes forms, entries and more in the WPForms plugin.',
|
18 |
)
|
19 |
);
|
49 |
public function get_color() {
|
50 |
return '#e27730';
|
51 |
}
|
52 |
+
|
53 |
+
public function get_plugin_filename() {
|
54 |
+
return 'wp-security-audit-log-add-on-for-wpforms/wsal-wpforms.php';
|
55 |
+
}
|
56 |
}
|
57 |
}
|
classes/ThirdPartyExtensions/WooCommerceExtension.php
CHANGED
@@ -15,10 +15,10 @@ if ( ! class_exists( 'WSAL_WooCommerceExtension' ) ) {
|
|
15 |
'addon_for' => 'woocommerce',
|
16 |
'title' => $this->get_plugin_name(),
|
17 |
'image_filename' => 'woocommerce.png',
|
18 |
-
'plugin_slug' =>
|
19 |
'plugin_basename' => 'wsal-woocommerce.php',
|
20 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/wp-activity-log-for-woocommerce.latest-stable.zip',
|
21 |
-
'event_tab_id' => '#
|
22 |
'plugin_description' => 'Keep a log of your team\'s store settings, products, orders, coupons and any other changes they might do on your eCommerce store.',
|
23 |
),
|
24 |
);
|
@@ -88,5 +88,9 @@ if ( ! class_exists( 'WSAL_WooCommerceExtension' ) ) {
|
|
88 |
public function get_color() {
|
89 |
return '#7f54b3';
|
90 |
}
|
|
|
|
|
|
|
|
|
91 |
}
|
92 |
}
|
15 |
'addon_for' => 'woocommerce',
|
16 |
'title' => $this->get_plugin_name(),
|
17 |
'image_filename' => 'woocommerce.png',
|
18 |
+
'plugin_slug' => $this->get_plugin_filename(),
|
19 |
'plugin_basename' => 'wsal-woocommerce.php',
|
20 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/wp-activity-log-for-woocommerce.latest-stable.zip',
|
21 |
+
'event_tab_id' => '#cat-woocommerce',
|
22 |
'plugin_description' => 'Keep a log of your team\'s store settings, products, orders, coupons and any other changes they might do on your eCommerce store.',
|
23 |
),
|
24 |
);
|
88 |
public function get_color() {
|
89 |
return '#7f54b3';
|
90 |
}
|
91 |
+
|
92 |
+
public function get_plugin_filename() {
|
93 |
+
return 'wp-activity-log-for-woocommerce/wsal-woocommerce.php';
|
94 |
+
}
|
95 |
}
|
96 |
}
|
classes/ThirdPartyExtensions/YoastSeoExtension.php
CHANGED
@@ -10,10 +10,10 @@ if ( ! class_exists( 'WSAL_YoastSeoExtension' ) ) {
|
|
10 |
'addon_for' => 'wp-seo',
|
11 |
'title' => $this->get_plugin_name(),
|
12 |
'image_filename' => 'yoast.png',
|
13 |
-
'plugin_slug' =>
|
14 |
'plugin_basename' => 'activity-log-wp-seo.php',
|
15 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/activity-log-wp-seo.latest-stable.zip',
|
16 |
-
'event_tab_id' => '#
|
17 |
'plugin_description' => 'Keep a log of all the changes that you and your team do in the Yoast SEO metabox, plugin settings & much more.',
|
18 |
)
|
19 |
);
|
@@ -54,5 +54,9 @@ if ( ! class_exists( 'WSAL_YoastSeoExtension' ) ) {
|
|
54 |
public function get_color() {
|
55 |
return '#a4286a';
|
56 |
}
|
|
|
|
|
|
|
|
|
57 |
}
|
58 |
}
|
10 |
'addon_for' => 'wp-seo',
|
11 |
'title' => $this->get_plugin_name(),
|
12 |
'image_filename' => 'yoast.png',
|
13 |
+
'plugin_slug' => $this->get_plugin_filename(),
|
14 |
'plugin_basename' => 'activity-log-wp-seo.php',
|
15 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/activity-log-wp-seo.latest-stable.zip',
|
16 |
+
'event_tab_id' => '#cat-yoast-seo',
|
17 |
'plugin_description' => 'Keep a log of all the changes that you and your team do in the Yoast SEO metabox, plugin settings & much more.',
|
18 |
)
|
19 |
);
|
54 |
public function get_color() {
|
55 |
return '#a4286a';
|
56 |
}
|
57 |
+
|
58 |
+
public function get_plugin_filename() {
|
59 |
+
return 'activity-log-wp-seo/activity-log-wp-seo.php';
|
60 |
+
}
|
61 |
}
|
62 |
}
|
classes/Upgrade/MetadataMigration.php
ADDED
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly.
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Background process for handling the migration of selected metadata from the meta table to the occurrences table. This
|
10 |
+
* was part of database schema changes introduced in version 4.4.0.
|
11 |
+
*
|
12 |
+
* It handles metadata migration for 1 connection defined as part of the process information. This can be either "local"
|
13 |
+
* to work with the local WP database or a name of connection defined by the Integrations extension.
|
14 |
+
*
|
15 |
+
* @package wsal
|
16 |
+
* @subpackage upgrade
|
17 |
+
* @since 4.4.0
|
18 |
+
*/
|
19 |
+
class WSAL_Upgrade_MetadataMigration extends WSAL_Vendor\WP_Background_Process {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Name of the option holding the information about ongoing metadata migration.
|
23 |
+
*
|
24 |
+
* Note: the wsal_ prefix is automatically added by plugin's settings handling functions.
|
25 |
+
*
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
const OPTION_NAME_MIGRATION_INFO = 'meta_data_migration_info_440';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @inheritDoc
|
32 |
+
*/
|
33 |
+
protected $action = 'wsal_meta_data_migration_440';
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Displays an admin notice if a metadata migration is in progress.
|
37 |
+
*/
|
38 |
+
public static function maybe_display_progress_admin_notice() {
|
39 |
+
if ( ! is_user_logged_in() ) {
|
40 |
+
// Don't show to anonymous users (obviously).
|
41 |
+
return;
|
42 |
+
}
|
43 |
+
|
44 |
+
$current_user = get_userdata( get_current_user_id() );
|
45 |
+
if ( false === $current_user ) {
|
46 |
+
// Bail if there is a problem retrieving the current user.
|
47 |
+
return;
|
48 |
+
}
|
49 |
+
|
50 |
+
$is_admin = in_array( 'administrator', $current_user->roles, true ) || ( function_exists( 'is_super_admin' ) && is_super_admin( $current_user->ID ) );
|
51 |
+
if ( ! $is_admin ) {
|
52 |
+
// Don't show to admin users.
|
53 |
+
return;
|
54 |
+
}
|
55 |
+
|
56 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
57 |
+
$existing_info = $plugin->GetGlobalSetting( self::OPTION_NAME_MIGRATION_INFO, array() );
|
58 |
+
if ( empty( $existing_info ) ) {
|
59 |
+
return;
|
60 |
+
}
|
61 |
+
?>
|
62 |
+
<div class="notice notice-info">
|
63 |
+
<div class="notice-content-wrapper">
|
64 |
+
<p>
|
65 |
+
<strong><?php esc_html_e( 'Activity log database update in progress.', 'wp-security-audit-log' ); ?></strong>
|
66 |
+
<br />
|
67 |
+
<?php esc_html_e( 'WP Activity Log is updating the database tables where it stores the activity log. This is needed to upgrade the activity log tables to the new database schema, so the logs can be stored and read more efficiently. The duration of this process varies, depending on the number of events in the activity log. This process runs in the background and won\'t affect your website. During the upgrade, you might notice some "null" values in the activity log. This is temporary until the process is complete.', 'wp-security-audit-log' ); ?>
|
68 |
+
</p>
|
69 |
+
</div>
|
70 |
+
</div>
|
71 |
+
<?php
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @inheritDoc
|
76 |
+
*
|
77 |
+
* @param array{start_time: int, processed_events_count: int, batch_size: int, connection: string} $item
|
78 |
+
*/
|
79 |
+
protected function task( $item ) {
|
80 |
+
// migrate metadata for the next batch of events
|
81 |
+
$items_migrated = $this->process_next_batch( $item['connection'], $item['batch_size'] );
|
82 |
+
if ( 0 === $items_migrated ) {
|
83 |
+
// all metadata has been migrated
|
84 |
+
try {
|
85 |
+
// delete the migration job info to indicate that the migration is done
|
86 |
+
self::remove_migration_info( $item['connection'] );
|
87 |
+
|
88 |
+
} catch ( Exception $exception ) {
|
89 |
+
$this->handle_error( $exception );
|
90 |
+
}
|
91 |
+
|
92 |
+
return false;
|
93 |
+
}
|
94 |
+
|
95 |
+
// update and save the migration info
|
96 |
+
$item['processed_events_count'] += $items_migrated;
|
97 |
+
self::store_migration_info( $item );
|
98 |
+
|
99 |
+
return $item;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @param string $connection
|
104 |
+
* @param int $batch_size
|
105 |
+
*
|
106 |
+
* @return int
|
107 |
+
*/
|
108 |
+
private function process_next_batch( $connection, $batch_size ) {
|
109 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
110 |
+
if ( 'local' !== $connection && ! is_null( $plugin->external_db_util ) ) {
|
111 |
+
$connection = $plugin->external_db_util->get_connection( $connection );
|
112 |
+
if ( false === $connection ) {
|
113 |
+
return 0;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
$connector = $plugin->getConnector( $connection );
|
118 |
+
/** @var WSAL_Adapters_MySQL_Occurrence $occurrence_adapter */
|
119 |
+
$occurrence_adapter = $connector->getAdapter( 'Occurrence' );
|
120 |
+
|
121 |
+
$occurrences_to_migrate = $occurrence_adapter->get_all_with_meta_to_migrate( $batch_size );
|
122 |
+
if ( ! empty( $occurrences_to_migrate ) ) {
|
123 |
+
$migrated_meta_keys = array_keys( WSAL_Models_Occurrence::$migrated_meta );
|
124 |
+
$lowercase_migrated_meta_keys = array_map( 'strtolower', $migrated_meta_keys );
|
125 |
+
foreach ( $occurrences_to_migrate as $occurrence ) {
|
126 |
+
$all_metadata = $occurrence_adapter->GetMultiMeta( $occurrence );
|
127 |
+
if ( ! empty( $all_metadata ) ) {
|
128 |
+
foreach ( $all_metadata as $meta_model ) {
|
129 |
+
$meta_key = $meta_model->name;
|
130 |
+
$lowercase_meta_key = strtolower($meta_key);
|
131 |
+
|
132 |
+
// We use lowercase meta keys to make sure we handle even legacy meta keys correctly, for
|
133 |
+
// example "username" was changed to "Username" at some point.
|
134 |
+
if ( in_array( $lowercase_meta_key , $lowercase_migrated_meta_keys ) ) {
|
135 |
+
// this will store the meta in the occ table if it belongs there
|
136 |
+
$is_empty_string = is_string( $meta_model->value ) && 0 === strlen( $meta_model->value );
|
137 |
+
if ( ! $is_empty_string && in_array( $meta_key, $migrated_meta_keys )) {
|
138 |
+
// The meta is set in the occurrence object on if it is an exact match, otherwise we
|
139 |
+
// would end up writing and deleting the same meta key endlessly.
|
140 |
+
$occurrence->SetMetaValue( $meta_key, $meta_model->value );
|
141 |
+
}
|
142 |
+
|
143 |
+
$meta_model->Delete();
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
$occurrence->Save();
|
148 |
+
}
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
return count( $occurrences_to_migrate );
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Removes migration info for a particular connection.
|
157 |
+
*
|
158 |
+
* @param string $connection_name Connection name.
|
159 |
+
*/
|
160 |
+
public static function remove_migration_info( $connection_name ) {
|
161 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
162 |
+
$existing_info = $plugin->GetGlobalSetting( self::OPTION_NAME_MIGRATION_INFO, [] );
|
163 |
+
|
164 |
+
if ( array_key_exists( $connection_name, $existing_info ) ) {
|
165 |
+
unset( $existing_info[ $connection_name ] );
|
166 |
+
}
|
167 |
+
|
168 |
+
if ( empty( $existing_info ) ) {
|
169 |
+
$plugin->DeleteGlobalSetting( self::OPTION_NAME_MIGRATION_INFO );
|
170 |
+
} else {
|
171 |
+
$plugin->SetGlobalSetting( self::OPTION_NAME_MIGRATION_INFO, $existing_info );
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* @param Exception $exception
|
177 |
+
*/
|
178 |
+
private function handle_error( $exception ) {
|
179 |
+
// @todo handle migration error
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Stores or updates migration info for one particular connection.
|
184 |
+
*
|
185 |
+
* @param array{start_time: int, processed_events_count: int, batch_size: int, connection: string} $info
|
186 |
+
*/
|
187 |
+
public static function store_migration_info( $info ) {
|
188 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
189 |
+
$existing_info = $plugin->GetGlobalSetting( self::OPTION_NAME_MIGRATION_INFO, [] );
|
190 |
+
$connection_name = $info['connection'];
|
191 |
+
|
192 |
+
$existing_info[ $connection_name ] = $info;
|
193 |
+
$plugin->SetGlobalSetting( self::OPTION_NAME_MIGRATION_INFO, $existing_info );
|
194 |
+
}
|
195 |
+
}
|
classes/Upgrade/Upgrade_43000_to_44400.php
ADDED
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class handles upgrade changes from version 43000 to 44400.
|
5 |
+
*
|
6 |
+
* @package wsal
|
7 |
+
* @subpackage upgrade
|
8 |
+
*
|
9 |
+
* @since 4.4.0
|
10 |
+
*/
|
11 |
+
class WSAL_Upgrade_43000_to_44400 {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Plugin instance.
|
15 |
+
*
|
16 |
+
* @var WpSecurityAuditLog
|
17 |
+
*/
|
18 |
+
private $plugin;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Constructor.
|
22 |
+
*
|
23 |
+
* @param WpSecurityAuditLog $plugin Plugin instance.
|
24 |
+
*/
|
25 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
26 |
+
$this->plugin = $plugin;
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Runs the upgrade process.
|
31 |
+
*/
|
32 |
+
public function run() {
|
33 |
+
|
34 |
+
// Remove some forgotten WFCM settings from the options table.
|
35 |
+
$this->remove_wfcm_leftover_settings();
|
36 |
+
|
37 |
+
// Change occurrence table in local database.
|
38 |
+
$this->upgrade_occurrence_table( 'local' );
|
39 |
+
|
40 |
+
|
41 |
+
$this->stop_autoloading_some_settings();
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Removes a bunch of legacy WFCM extension related settings.
|
46 |
+
*/
|
47 |
+
private function remove_wfcm_leftover_settings() {
|
48 |
+
// Remove all settings related to WFCM plugin.
|
49 |
+
$not_found_page_related_settings = array(
|
50 |
+
'wsal_scan-in-progress',
|
51 |
+
'wsal_last-scanned',
|
52 |
+
'wsal_is_initial_scan_0',
|
53 |
+
'wsal_is_initial_scan_1',
|
54 |
+
'wsal_is_initial_scan_2',
|
55 |
+
'wsal_is_initial_scan_3',
|
56 |
+
'wsal_is_initial_scan_4',
|
57 |
+
'wsal_is_initial_scan_5',
|
58 |
+
'wsal_is_initial_scan_6',
|
59 |
+
'wsal_last_scan_start',
|
60 |
+
'wsal_scanned_dirs',
|
61 |
+
);
|
62 |
+
foreach ( $not_found_page_related_settings as $setting_name ) {
|
63 |
+
$this->plugin->DeleteGlobalSetting( $setting_name );
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Upgrades an occurrence table using given connection.
|
69 |
+
*
|
70 |
+
* It also kicks-off a metadata migration in the background.
|
71 |
+
*
|
72 |
+
* @param string|array $connection Connection alias or configuration data.
|
73 |
+
*
|
74 |
+
* @throws Freemius_Exception Freemius exception.
|
75 |
+
*/
|
76 |
+
private function upgrade_occurrence_table( $connection ) {
|
77 |
+
$connector = $this->plugin->getConnector( $connection );
|
78 |
+
/** @var WSAL_Adapters_MySQL_Occurrence $occurrence_adapter */
|
79 |
+
$occurrence_adapter = $connector->getAdapter( 'Occurrence' );
|
80 |
+
|
81 |
+
// Skip the upgrade it the table does not exist for some reason.
|
82 |
+
if ( ! $connector->isInstalled() ) {
|
83 |
+
return;
|
84 |
+
}
|
85 |
+
|
86 |
+
$table_name = $occurrence_adapter->GetTable();
|
87 |
+
$connector->query( $this->get_occurrence_table_upgrade_query( $table_name ) );
|
88 |
+
|
89 |
+
// Check if there are any events to process.
|
90 |
+
if ( $occurrence_adapter->Count() > 0 ) {
|
91 |
+
// Create a background job to migrate the metadata.
|
92 |
+
$job_info = array(
|
93 |
+
'start_time' => current_time( 'timestamp' ), // phpcs:ignore
|
94 |
+
'processed_events_count' => 0,
|
95 |
+
'batch_size' => 50,
|
96 |
+
'connection' => is_array( $connection ) ? $connection['name'] : $connection,
|
97 |
+
);
|
98 |
+
|
99 |
+
// Store the initial info to the db.
|
100 |
+
WSAL_Upgrade_MetadataMigration::store_migration_info( $job_info );
|
101 |
+
|
102 |
+
// Create and dispatch the background process itself.
|
103 |
+
$bg_process = new WSAL_Upgrade_MetadataMigration();
|
104 |
+
$bg_process->push_to_queue( $job_info );
|
105 |
+
$bg_process->save();
|
106 |
+
$bg_process->dispatch();
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Builds an upgrade query for the occurrence table.
|
112 |
+
*
|
113 |
+
* @param string $table_name Table name.
|
114 |
+
*
|
115 |
+
* @return string
|
116 |
+
*/
|
117 |
+
private function get_occurrence_table_upgrade_query( $table_name ) {
|
118 |
+
return "ALTER TABLE {$table_name}"
|
119 |
+
. ' DROP COLUMN is_read, '
|
120 |
+
. ' DROP COLUMN is_migrated, '
|
121 |
+
. " ADD client_ip VARCHAR(255) NOT NULL DEFAULT '',"
|
122 |
+
. ' ADD severity BIGINT NOT NULL DEFAULT 0,'
|
123 |
+
. " ADD object VARCHAR(255) NOT NULL DEFAULT '',"
|
124 |
+
. " ADD event_type VARCHAR(255) NOT NULL DEFAULT '',"
|
125 |
+
. " ADD user_agent VARCHAR(255) NOT NULL DEFAULT '',"
|
126 |
+
. " ADD user_roles VARCHAR(255) NOT NULL DEFAULT '',"
|
127 |
+
. ' ADD username VARCHAR(255) NULL,'
|
128 |
+
. ' ADD user_id BIGINT NULL ,'
|
129 |
+
. " ADD session_id VARCHAR(255) NOT NULL DEFAULT '',"
|
130 |
+
. " ADD post_status VARCHAR(255) NOT NULL DEFAULT '',"
|
131 |
+
. " ADD post_type VARCHAR(255) NOT NULL DEFAULT '',"
|
132 |
+
. ' ADD post_id BIGINT NOT NULL DEFAULT 0;';
|
133 |
+
}
|
134 |
+
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Change all but selected plugin settings to stop autoloading.
|
138 |
+
*/
|
139 |
+
private function stop_autoloading_some_settings() {
|
140 |
+
$settings_to_leave_on_autoload = array(
|
141 |
+
'wsal_adapter-connection',
|
142 |
+
'wsal_admin-bar-notif-updates',
|
143 |
+
'wsal_db_version',
|
144 |
+
'wsal_disable-admin-bar-notif',
|
145 |
+
'wsal_frontend-events',
|
146 |
+
'wsal_plugin-viewers',
|
147 |
+
'wsal_restrict-log-viewer',
|
148 |
+
'wsal_restrict-plugin-settings',
|
149 |
+
'wsal_setup-modal-dismissed',
|
150 |
+
'wsal_version',
|
151 |
+
'wsal_freemius_state',
|
152 |
+
'wsal_only-me-user-id',
|
153 |
+
);
|
154 |
+
|
155 |
+
// phpcs:disable
|
156 |
+
global $wpdb;
|
157 |
+
$plugin_options = $wpdb->get_results(
|
158 |
+
'SELECT option_name, option_value '
|
159 |
+
. " FROM $wpdb->options "
|
160 |
+
. " WHERE option_name LIKE '" . WpSecurityAuditLog::OPTIONS_PREFIX . "%';",
|
161 |
+
ARRAY_A
|
162 |
+
);
|
163 |
+
// phpcs:enable
|
164 |
+
|
165 |
+
if ( ! empty( $plugin_options ) ) {
|
166 |
+
foreach ( $plugin_options as $option ) {
|
167 |
+
if ( ! in_array( $option['option_name'], $settings_to_leave_on_autoload ) ) { // phpcs:ignore
|
168 |
+
$value = maybe_unserialize( $option['option_value'] );
|
169 |
+
$this->plugin->SetGlobalSetting( $option['option_name'], $value, false );
|
170 |
+
}
|
171 |
+
}
|
172 |
+
}
|
173 |
+
}
|
174 |
+
}
|
classes/Utilities/FileSystemUtils.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Utility class for handling certain file system related functionality.
|
5 |
+
*
|
6 |
+
* @package wsal
|
7 |
+
* @since 4.4.0
|
8 |
+
*/
|
9 |
+
class WSAL_Utilities_FileSystemUtils {
|
10 |
+
/**
|
11 |
+
* Returns a list of files matching given pattern in a given directory.
|
12 |
+
*
|
13 |
+
* It uses transients to cache the list of files for a day.
|
14 |
+
*
|
15 |
+
* @param string $directory Directory to search.
|
16 |
+
* @param string $pattern Filename pattern to narrow down the list of files.
|
17 |
+
*
|
18 |
+
* @return string
|
19 |
+
*
|
20 |
+
* @since 4.4.0
|
21 |
+
*/
|
22 |
+
public static function read_files_in_folder( $directory, $pattern ) {
|
23 |
+
$folder_slashed = trailingslashit( $directory );
|
24 |
+
$cache_key = WpSecurityAuditLog::OPTIONS_PREFIX . '_file_list_' . md5( $folder_slashed . $pattern );
|
25 |
+
$cached_data = get_transient( $cache_key );
|
26 |
+
if ( is_array( $cached_data ) ) {
|
27 |
+
return $cached_data;
|
28 |
+
}
|
29 |
+
|
30 |
+
$result = array();
|
31 |
+
$handle = opendir( $directory );
|
32 |
+
if ( $handle ) {
|
33 |
+
$ignore_list = array( '.', '..' );
|
34 |
+
$regexp = '/' . str_replace( array( '.', '*' ), array( '\.', '.*' ), $pattern ) . '/';
|
35 |
+
while ( false !== ( $file_name = readdir( $handle ) ) ) {
|
36 |
+
if ( ! in_array( $file_name, $ignore_list, true ) && preg_match( $regexp, $file_name ) ) {
|
37 |
+
array_push( $result, $folder_slashed . $file_name );
|
38 |
+
}
|
39 |
+
}
|
40 |
+
closedir( $handle );
|
41 |
+
}
|
42 |
+
|
43 |
+
set_transient( $cache_key, $result, DAY_IN_SECONDS );
|
44 |
+
|
45 |
+
return $result;
|
46 |
+
}
|
47 |
+
}
|
classes/Utilities/PluginInstallAndActivate.php
CHANGED
@@ -133,17 +133,18 @@ if ( ! class_exists( 'WSAL_PluginInstallAndActivate' ) ) {
|
|
133 |
public static function get_installable_plugins() {
|
134 |
$plugins = array(
|
135 |
array(
|
136 |
-
'addon_for'
|
137 |
-
'title'
|
138 |
-
'plugin_slug'
|
139 |
-
'plugin_url'
|
140 |
),
|
141 |
);
|
142 |
-
|
|
|
143 |
// NOTE: this means when using we need to test it's still an array.
|
144 |
$installable_plugins = apply_filters( 'wsal_filter_installable_plugins', $plugins );
|
145 |
|
146 |
-
// Sort them into a
|
147 |
array_multisort( array_column( $installable_plugins, 'title' ), SORT_ASC, $installable_plugins );
|
148 |
|
149 |
return $installable_plugins;
|
133 |
public static function get_installable_plugins() {
|
134 |
$plugins = array(
|
135 |
array(
|
136 |
+
'addon_for' => 'wfcm',
|
137 |
+
'title' => 'Website File Changes Monitor',
|
138 |
+
'plugin_slug' => 'website-file-changes-monitor/website-file-changes-monitor.php',
|
139 |
+
'plugin_url' => 'https://downloads.wordpress.org/plugin/website-file-changes-monitor.latest-stable.zip',
|
140 |
),
|
141 |
);
|
142 |
+
|
143 |
+
// runs through a filter, so it can be added to programmatically.
|
144 |
// NOTE: this means when using we need to test it's still an array.
|
145 |
$installable_plugins = apply_filters( 'wsal_filter_installable_plugins', $plugins );
|
146 |
|
147 |
+
// Sort them into a nice order.
|
148 |
array_multisort( array_column( $installable_plugins, 'title' ), SORT_ASC, $installable_plugins );
|
149 |
|
150 |
return $installable_plugins;
|
classes/Utilities/PluginInstallerAction.php
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
if ( ! class_exists( 'WSAL_PluginInstallerAction' ) ) {
|
12 |
|
13 |
/**
|
14 |
-
* Class to handle the
|
15 |
*
|
16 |
* @since 4.0.1
|
17 |
*/
|
@@ -63,14 +63,20 @@ if ( ! class_exists( 'WSAL_PluginInstallerAction' ) ) {
|
|
63 |
}
|
64 |
}
|
65 |
|
66 |
-
// validate that the plugin is in the allowed list.
|
67 |
$valid = false;
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
73 |
-
$valid = ( $plugin_zip === $plugin['plugin_url'] && $plugin_slug === $plugin['plugin_slug'] ) ? true : false;
|
74 |
}
|
75 |
|
76 |
// bail early if we didn't get a valid url and slug to install.
|
@@ -100,6 +106,11 @@ if ( ! class_exists( 'WSAL_PluginInstallerAction' ) ) {
|
|
100 |
$result = 'success';
|
101 |
}
|
102 |
|
|
|
|
|
|
|
|
|
|
|
103 |
wp_send_json( $result );
|
104 |
}
|
105 |
|
11 |
if ( ! class_exists( 'WSAL_PluginInstallerAction' ) ) {
|
12 |
|
13 |
/**
|
14 |
+
* Class to handle the installation and activation of plugins.
|
15 |
*
|
16 |
* @since 4.0.1
|
17 |
*/
|
63 |
}
|
64 |
}
|
65 |
|
66 |
+
// validate that the plugin is in the allowed list, or it is our helper plugin with external libraries.
|
67 |
$valid = false;
|
68 |
+
$helper_plugin_installation = 'wsal-external-libraries/wsal-external-libraries.php' === $plugin_slug;
|
69 |
+
if ( $helper_plugin_installation ) {
|
70 |
+
$valid = true;
|
71 |
+
} else {
|
72 |
+
foreach ( $predefined_plugins as $plugin ) {
|
73 |
+
// if we have a valid plugin then break.
|
74 |
+
if ( $valid ) {
|
75 |
+
break;
|
76 |
+
}
|
77 |
+
|
78 |
+
$valid = $plugin_zip === $plugin['plugin_url'] && $plugin_slug === $plugin['plugin_slug'];
|
79 |
}
|
|
|
80 |
}
|
81 |
|
82 |
// bail early if we didn't get a valid url and slug to install.
|
106 |
$result = 'success';
|
107 |
}
|
108 |
|
109 |
+
// if we're installing our helper plugin, we also need to delete the nudge to install the helper plugin
|
110 |
+
if ( $helper_plugin_installation ) {
|
111 |
+
WpSecurityAuditLog::GetInstance()->DeleteGlobalSetting( 'show-helper-plugin-needed-nudge' );
|
112 |
+
}
|
113 |
+
|
114 |
wp_send_json( $result );
|
115 |
}
|
116 |
|
classes/Utilities/RequestUtils.php
CHANGED
@@ -46,4 +46,15 @@ class WSAL_Utilities_RequestUtils {
|
|
46 |
|
47 |
return true;
|
48 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
46 |
|
47 |
return true;
|
48 |
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Check if the float is IPv4 instead.
|
52 |
+
*
|
53 |
+
* @param float $ip_address - Number to check.
|
54 |
+
*
|
55 |
+
* @return bool result validation
|
56 |
+
*/
|
57 |
+
public static function is_ip_address( $ip_address ) {
|
58 |
+
return filter_var( $ip_address, FILTER_VALIDATE_IP ) !== false;
|
59 |
+
}
|
60 |
}
|
classes/Utilities/UserUtils.php
CHANGED
@@ -23,8 +23,10 @@ class WSAL_Utilities_UsersUtils {
|
|
23 |
private static $user_label_setting;
|
24 |
|
25 |
/**
|
|
|
|
|
26 |
* @param WpSecurityAuditLog $plugin Instance of WpSecurityAuditLog.
|
27 |
-
* @param WP_User
|
28 |
*
|
29 |
* @return string
|
30 |
* @since 4.3.0
|
@@ -39,10 +41,15 @@ class WSAL_Utilities_UsersUtils {
|
|
39 |
}
|
40 |
|
41 |
if ( 'first_last_name' === self::$user_label_setting && ( ! empty( $user->first_name ) || ! empty( $user->last_name ) ) ) {
|
42 |
-
return trim(
|
43 |
-
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
|
|
|
|
46 |
}
|
47 |
|
48 |
return $user->user_login;
|
@@ -88,12 +95,26 @@ class WSAL_Utilities_UsersUtils {
|
|
88 |
return '';
|
89 |
}
|
90 |
|
91 |
-
$tooltip
|
92 |
$tooltip .= ( ! empty( $user->data->first_name ) ) ? '<strong>' . esc_attr__( 'First name: ', 'wp-security-audit-log' ) . '</strong>' . $user->data->first_name . '</br>' : '';
|
93 |
$tooltip .= ( ! empty( $user->data->first_name ) ) ? '<strong>' . esc_attr__( 'Last Name: ', 'wp-security-audit-log' ) . '</strong>' . $user->data->first_name . '</br>' : '';
|
94 |
$tooltip .= '<strong>' . esc_attr__( 'Email: ', 'wp-security-audit-log' ) . '</strong>' . $user->data->user_email . '</br>';
|
95 |
$tooltip .= '<strong>' . esc_attr__( 'Nickname: ', 'wp-security-audit-log' ) . '</strong>' . $user->data->user_nicename . '</br></br>';
|
96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
return $tooltip;
|
98 |
}
|
99 |
|
@@ -149,4 +170,4 @@ class WSAL_Utilities_UsersUtils {
|
|
149 |
return '<i>' . esc_html__( 'Unknown', 'wp-security-audit-log' ) . '</i>';
|
150 |
|
151 |
}
|
152 |
-
}
|
23 |
private static $user_label_setting;
|
24 |
|
25 |
/**
|
26 |
+
* Build the correct label to display for a given user.
|
27 |
+
*
|
28 |
* @param WpSecurityAuditLog $plugin Instance of WpSecurityAuditLog.
|
29 |
+
* @param WP_User $user WordPress user object.
|
30 |
*
|
31 |
* @return string
|
32 |
* @since 4.3.0
|
41 |
}
|
42 |
|
43 |
if ( 'first_last_name' === self::$user_label_setting && ( ! empty( $user->first_name ) || ! empty( $user->last_name ) ) ) {
|
44 |
+
return trim(
|
45 |
+
implode(
|
46 |
+
' ',
|
47 |
+
array(
|
48 |
+
$user->first_name,
|
49 |
+
$user->last_name,
|
50 |
+
)
|
51 |
+
)
|
52 |
+
);
|
53 |
}
|
54 |
|
55 |
return $user->user_login;
|
95 |
return '';
|
96 |
}
|
97 |
|
98 |
+
$tooltip = '<strong>' . esc_attr__( 'Username: ', 'wp-security-audit-log' ) . '</strong>' . $user->data->user_login . '</br>';
|
99 |
$tooltip .= ( ! empty( $user->data->first_name ) ) ? '<strong>' . esc_attr__( 'First name: ', 'wp-security-audit-log' ) . '</strong>' . $user->data->first_name . '</br>' : '';
|
100 |
$tooltip .= ( ! empty( $user->data->first_name ) ) ? '<strong>' . esc_attr__( 'Last Name: ', 'wp-security-audit-log' ) . '</strong>' . $user->data->first_name . '</br>' : '';
|
101 |
$tooltip .= '<strong>' . esc_attr__( 'Email: ', 'wp-security-audit-log' ) . '</strong>' . $user->data->user_email . '</br>';
|
102 |
$tooltip .= '<strong>' . esc_attr__( 'Nickname: ', 'wp-security-audit-log' ) . '</strong>' . $user->data->user_nicename . '</br></br>';
|
103 |
|
104 |
+
/**
|
105 |
+
* WSAL Filter: `wsal_additional_user_tooltip_content'
|
106 |
+
*
|
107 |
+
* Allows 3rd parties to append HTML to the user tooltip content in audit log viewer.
|
108 |
+
*
|
109 |
+
* @since 4.4.0
|
110 |
+
*
|
111 |
+
* @param string $content Blank string to append to.
|
112 |
+
* @param object $user - User object.
|
113 |
+
*/
|
114 |
+
$additional_content = apply_filters( 'wsal_additional_user_tooltip_content', '', $user );
|
115 |
+
|
116 |
+
$tooltip .= $additional_content;
|
117 |
+
|
118 |
return $tooltip;
|
119 |
}
|
120 |
|
170 |
return '<i>' . esc_html__( 'Unknown', 'wp-security-audit-log' ) . '</i>';
|
171 |
|
172 |
}
|
173 |
+
}
|
classes/ViewManager.php
CHANGED
@@ -89,7 +89,7 @@ class WSAL_ViewManager {
|
|
89 |
$skip_views = apply_filters( 'wsal_skip_views', $skip_views );
|
90 |
|
91 |
// Load views.
|
92 |
-
foreach (
|
93 |
if ( empty( $skip_views ) || ! in_array( $file, $skip_views ) ) {
|
94 |
$this->AddFromFile( $file );
|
95 |
}
|
@@ -118,9 +118,6 @@ class WSAL_ViewManager {
|
|
118 |
new WSAL_Views_SetupWizard( $plugin );
|
119 |
}
|
120 |
|
121 |
-
// Reorder WSAL submenu.
|
122 |
-
add_filter( 'custom_menu_order', array( $this, 'reorder_wsal_submenu' ), 10, 1 );
|
123 |
-
|
124 |
|
125 |
add_action( 'admin_head', array( $this, 'hide_freemius_sites_section' ) );
|
126 |
|
@@ -131,7 +128,6 @@ class WSAL_ViewManager {
|
|
131 |
}
|
132 |
}
|
133 |
|
134 |
-
|
135 |
/**
|
136 |
* Display notice if user is using older version of WFCM
|
137 |
*/
|
@@ -453,50 +449,6 @@ class WSAL_ViewManager {
|
|
453 |
return $not_show;
|
454 |
}
|
455 |
|
456 |
-
/**
|
457 |
-
* Reorder WSAL Submenu.
|
458 |
-
*
|
459 |
-
* @since 3.2.4
|
460 |
-
*
|
461 |
-
* @param boolean $menu_order - Custom order.
|
462 |
-
* @return boolean
|
463 |
-
*/
|
464 |
-
public function reorder_wsal_submenu( $menu_order ) {
|
465 |
-
// Get global $submenu order.
|
466 |
-
global $submenu;
|
467 |
-
|
468 |
-
// Get WSAL admin menu.
|
469 |
-
$auditlog_menu = isset( $submenu['wsal-auditlog'] ) ? $submenu['wsal-auditlog'] : false;
|
470 |
-
$help_link = new stdClass();
|
471 |
-
$account_link = new stdClass();
|
472 |
-
|
473 |
-
if ( ! empty( $auditlog_menu ) ) {
|
474 |
-
foreach ( $auditlog_menu as $key => $auditlog_submenu ) {
|
475 |
-
if ( 'wsal-help' === $auditlog_submenu[2] ) {
|
476 |
-
$help_link->key = $key;
|
477 |
-
$help_link->menu = $auditlog_submenu;
|
478 |
-
} elseif ( 'wsal-auditlog-account' === $auditlog_submenu[2] ) {
|
479 |
-
$account_link->key = $key;
|
480 |
-
$account_link->menu = $auditlog_submenu;
|
481 |
-
}
|
482 |
-
}
|
483 |
-
}
|
484 |
-
|
485 |
-
if ( ! empty( $help_link ) && ! empty( $account_link ) ) {
|
486 |
-
// Swap the menus at their positions.
|
487 |
-
if ( isset( $help_link->key ) && isset( $account_link->menu ) ) {
|
488 |
-
$submenu['wsal-auditlog'][ $help_link->key ] = $account_link->menu;
|
489 |
-
}
|
490 |
-
if ( isset( $account_link->key ) && isset( $help_link->menu ) ) {
|
491 |
-
$submenu['wsal-auditlog'][ $account_link->key ] = $help_link->menu;
|
492 |
-
}
|
493 |
-
if ( isset( $submenu['wsal-auditlog'] ) && is_array( $submenu['wsal-auditlog'] ) ) {
|
494 |
-
ksort( $submenu['wsal-auditlog'] );
|
495 |
-
}
|
496 |
-
}
|
497 |
-
return $menu_order;
|
498 |
-
}
|
499 |
-
|
500 |
|
501 |
/**
|
502 |
* Hide Freemius sites section on the account page
|
89 |
$skip_views = apply_filters( 'wsal_skip_views', $skip_views );
|
90 |
|
91 |
// Load views.
|
92 |
+
foreach ( WSAL_Utilities_FileSystemUtils::read_files_in_folder( $this->_plugin->GetBaseDir() . 'classes/Views', '*.php' ) as $file ) {
|
93 |
if ( empty( $skip_views ) || ! in_array( $file, $skip_views ) ) {
|
94 |
$this->AddFromFile( $file );
|
95 |
}
|
118 |
new WSAL_Views_SetupWizard( $plugin );
|
119 |
}
|
120 |
|
|
|
|
|
|
|
121 |
|
122 |
add_action( 'admin_head', array( $this, 'hide_freemius_sites_section' ) );
|
123 |
|
128 |
}
|
129 |
}
|
130 |
|
|
|
131 |
/**
|
132 |
* Display notice if user is using older version of WFCM
|
133 |
*/
|
449 |
return $not_show;
|
450 |
}
|
451 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
452 |
|
453 |
/**
|
454 |
* Hide Freemius sites section on the account page
|
classes/Views/AuditLog.php
CHANGED
@@ -79,6 +79,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
79 |
add_action( 'wp_ajax_wsal_dismiss_advert', array( $this, 'wsal_dismiss_advert' ) );
|
80 |
add_action( 'wp_ajax_wsal_dismiss_notice_addon_available', array( $this, 'dismiss_notice_addon_available' ) );
|
81 |
add_action( 'wp_ajax_wsal_dismiss_missing_aws_sdk_nudge', array( $this, 'dismiss_missing_aws_sdk_nudge' ) );
|
|
|
82 |
add_action( 'wp_ajax_wsal_dismiss_wp_pointer', array( $this, 'dismiss_wp_pointer' ) );
|
83 |
add_action( 'all_admin_notices', array( $this, 'AdminNotices' ) );
|
84 |
add_action( 'admin_enqueue_scripts', array( $this, 'load_pointers' ), 1000 );
|
@@ -172,7 +173,6 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
172 |
'https://wpactivitylog.com/trial-premium-edition-plugin/'
|
173 |
);
|
174 |
|
175 |
-
// Buy Now button link.
|
176 |
$buy_now = add_query_arg(
|
177 |
array(
|
178 |
'utm_source' => 'plugin',
|
@@ -227,6 +227,10 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
227 |
$screen = get_current_screen();
|
228 |
|
229 |
|
|
|
|
|
|
|
|
|
230 |
if ( $is_current_view && in_array( $screen->base, array( 'toplevel_page_wsal-auditlog', 'toplevel_page_wsal-auditlog-network' ) ) ) {
|
231 |
// Grab list of installed plugins.
|
232 |
$all_plugins = get_plugins();
|
@@ -792,7 +796,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
792 |
}
|
793 |
|
794 |
// Update freemius state.
|
795 |
-
$this->_plugin->SetGlobalSetting( 'freemius_state', 'in' );
|
796 |
} elseif ( 'no' === $choice ) {
|
797 |
if ( ! is_multisite() ) {
|
798 |
wsal_freemius()->skip_connection(); // Opt out.
|
@@ -801,7 +805,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
801 |
}
|
802 |
|
803 |
// Update freemius state.
|
804 |
-
$this->_plugin->SetGlobalSetting( 'freemius_state', 'skipped' );
|
805 |
}
|
806 |
|
807 |
echo wp_json_encode(
|
@@ -1166,7 +1170,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1166 |
die();
|
1167 |
}
|
1168 |
|
1169 |
-
$this->_plugin->SetGlobalBooleanSetting( 'setup-modal-dismissed', true );
|
1170 |
wp_send_json_success();
|
1171 |
}
|
1172 |
|
@@ -1190,23 +1194,32 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1190 |
*/
|
1191 |
public function maybe_build_teaser_html( $event_meta ) {
|
1192 |
$result = '';
|
1193 |
-
if ( array_key_exists( 'PostType', $event_meta ) ) {
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
$result .= '<img src="' . $extension->get_plugin_icon_url() . '" />';
|
1206 |
-
$result .= '</div>';
|
1207 |
-
}
|
1208 |
}
|
1209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1210 |
return $result;
|
1211 |
}
|
1212 |
}
|
79 |
add_action( 'wp_ajax_wsal_dismiss_advert', array( $this, 'wsal_dismiss_advert' ) );
|
80 |
add_action( 'wp_ajax_wsal_dismiss_notice_addon_available', array( $this, 'dismiss_notice_addon_available' ) );
|
81 |
add_action( 'wp_ajax_wsal_dismiss_missing_aws_sdk_nudge', array( $this, 'dismiss_missing_aws_sdk_nudge' ) );
|
82 |
+
add_action( 'wp_ajax_wsal_dismiss_helper_plugin_needed_nudge', array( $this, 'dismiss_helper_plugin_needed_nudge' ) );
|
83 |
add_action( 'wp_ajax_wsal_dismiss_wp_pointer', array( $this, 'dismiss_wp_pointer' ) );
|
84 |
add_action( 'all_admin_notices', array( $this, 'AdminNotices' ) );
|
85 |
add_action( 'admin_enqueue_scripts', array( $this, 'load_pointers' ), 1000 );
|
173 |
'https://wpactivitylog.com/trial-premium-edition-plugin/'
|
174 |
);
|
175 |
|
|
|
176 |
$buy_now = add_query_arg(
|
177 |
array(
|
178 |
'utm_source' => 'plugin',
|
227 |
$screen = get_current_screen();
|
228 |
|
229 |
|
230 |
+
if (class_exists('WSAL_Upgrade_MetadataMigration')) {
|
231 |
+
WSAL_Upgrade_MetadataMigration::maybe_display_progress_admin_notice();
|
232 |
+
}
|
233 |
+
|
234 |
if ( $is_current_view && in_array( $screen->base, array( 'toplevel_page_wsal-auditlog', 'toplevel_page_wsal-auditlog-network' ) ) ) {
|
235 |
// Grab list of installed plugins.
|
236 |
$all_plugins = get_plugins();
|
796 |
}
|
797 |
|
798 |
// Update freemius state.
|
799 |
+
$this->_plugin->SetGlobalSetting( 'freemius_state', 'in', true );
|
800 |
} elseif ( 'no' === $choice ) {
|
801 |
if ( ! is_multisite() ) {
|
802 |
wsal_freemius()->skip_connection(); // Opt out.
|
805 |
}
|
806 |
|
807 |
// Update freemius state.
|
808 |
+
$this->_plugin->SetGlobalSetting( 'freemius_state', 'skipped', true );
|
809 |
}
|
810 |
|
811 |
echo wp_json_encode(
|
1170 |
die();
|
1171 |
}
|
1172 |
|
1173 |
+
$this->_plugin->SetGlobalBooleanSetting( 'setup-modal-dismissed', true, true );
|
1174 |
wp_send_json_success();
|
1175 |
}
|
1176 |
|
1194 |
*/
|
1195 |
public function maybe_build_teaser_html( $event_meta ) {
|
1196 |
$result = '';
|
1197 |
+
if ( ! array_key_exists( 'PostType', $event_meta ) ) {
|
1198 |
+
return $result;
|
1199 |
+
}
|
1200 |
+
|
1201 |
+
$extension = WSAL_AbstractExtension::get_extension_for_post_type( $event_meta['PostType'] );
|
1202 |
+
if ( is_null( $extension ) ) {
|
1203 |
+
return $result;
|
1204 |
+
}
|
1205 |
+
|
1206 |
+
$plugin_filename = $extension->get_plugin_filename();
|
1207 |
+
if ( WSAL_PluginInstallAndActivate::is_plugin_installed( $plugin_filename ) && WpSecurityAuditLog::is_plugin_active( $plugin_filename ) ) {
|
1208 |
+
return $result;
|
|
|
|
|
|
|
1209 |
}
|
1210 |
|
1211 |
+
$result .= '<div class="extension-ad" style="border-color: transparent transparent ' . $extension->get_color() . ' transparent;">';
|
1212 |
+
$result .= '</div>';
|
1213 |
+
$plugin_name = $extension->get_plugin_name();
|
1214 |
+
$link_title = sprintf(
|
1215 |
+
esc_html__( 'Install the activity log extension for %1$s for more detailed logging of changes done in %2$s.', 'wp-security-audit-log' ),
|
1216 |
+
$plugin_name,
|
1217 |
+
$plugin_name
|
1218 |
+
);
|
1219 |
+
$result .= '<a class="icon" title="' . $link_title . '" href="' . $this->get_third_party_plugins_tab_url() . '">';
|
1220 |
+
$result .= '<img src="' . $extension->get_plugin_icon_url() . '" />';
|
1221 |
+
$result .= '</div>';
|
1222 |
+
|
1223 |
return $result;
|
1224 |
}
|
1225 |
}
|
classes/Views/EmailNotifications.php
CHANGED
@@ -32,14 +32,14 @@ class WSAL_Views_EmailNotifications extends WSAL_ExtensionPlaceholderView {
|
|
32 |
* Get View Name.
|
33 |
*/
|
34 |
public function GetName() {
|
35 |
-
return __( 'Notifications ⇪', 'wp-security-audit-log' );
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
* Get View Weight.
|
40 |
*/
|
41 |
public function GetWeight() {
|
42 |
-
return
|
43 |
}
|
44 |
|
45 |
/**
|
32 |
* Get View Name.
|
33 |
*/
|
34 |
public function GetName() {
|
35 |
+
return __( 'Email Notifications ⇪', 'wp-security-audit-log' );
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
* Get View Weight.
|
40 |
*/
|
41 |
public function GetWeight() {
|
42 |
+
return 2;
|
43 |
}
|
44 |
|
45 |
/**
|
classes/Views/Help.php
CHANGED
@@ -131,7 +131,7 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
131 |
* Method: Get View Weight.
|
132 |
*/
|
133 |
public function GetWeight() {
|
134 |
-
return
|
135 |
}
|
136 |
|
137 |
/**
|
@@ -277,10 +277,22 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
277 |
*/
|
278 |
private function sidebar() {
|
279 |
$plugins_data = array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
280 |
array(
|
281 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/password-policy-manager.jpg',
|
282 |
'desc' => __( 'Enforce strong password policies on WordPress', 'wp-security-audit-log' ),
|
283 |
-
'alt' => '
|
284 |
'link' => 'https://www.wpwhitesecurity.com/wordpress-plugins/password-policy-manager-wordpress/?utm_source=plugin&utm_medium=referral&utm_campaign=PPMWP&utm_content=WSAL+banner',
|
285 |
),
|
286 |
array(
|
@@ -289,12 +301,6 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
289 |
'alt' => 'Website File Changes Monitor',
|
290 |
'link' => 'https://www.wpwhitesecurity.com/wordpress-plugins/website-file-changes-monitor/?utm_source=plugin&utm_medium=referral&utm_campaign=WFCM&utm_content=WSAL+banner',
|
291 |
),
|
292 |
-
array(
|
293 |
-
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/wp-2fa-img.jpg',
|
294 |
-
'desc' => __( 'Add an extra layer of security to your login pages with 2FA & require your users to use it.', 'wp-security-audit-log' ),
|
295 |
-
'alt' => 'WP 2FA',
|
296 |
-
'link' => 'https://www.wpwhitesecurity.com/wordpress-plugins/wp-2fa/?utm_source=plugin&utm_medium=referral&utm_campaign=WP2FA&utm_content=WSAL+banner',
|
297 |
-
),
|
298 |
array(
|
299 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/activity-log-for-mainwp.jpg',
|
300 |
'desc' => __( 'See the child sites activity logs from the central MainWP dashboard', 'wp-security-audit-log' ),
|
131 |
* Method: Get View Weight.
|
132 |
*/
|
133 |
public function GetWeight() {
|
134 |
+
return 10;
|
135 |
}
|
136 |
|
137 |
/**
|
277 |
*/
|
278 |
private function sidebar() {
|
279 |
$plugins_data = array(
|
280 |
+
array(
|
281 |
+
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/wp-2fa-img.jpg',
|
282 |
+
'desc' => __( 'Add an extra layer of security to your login pages with 2FA & require your users to use it.', 'wp-security-audit-log' ),
|
283 |
+
'alt' => 'WP 2FA',
|
284 |
+
'link' => 'https://wp2fa.io/?utm_source=plugin&utm_medium=referral&utm_campaign=WP2FA&utm_content=WSAL+banner',
|
285 |
+
),
|
286 |
+
array(
|
287 |
+
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/c4wp.jpg',
|
288 |
+
'desc' => __( 'Protect website forms & login pages from spambots & automated attacks.', 'wp-security-audit-log' ),
|
289 |
+
'alt' => 'Captcha 4WP',
|
290 |
+
'link' => 'https://www.wpwhitesecurity.com/wordpress-plugins/captcha-plugin-wordpress/?utm_source=plugin&utm_medium=referral&utm_campaign=WP2FA&utm_content=WSAL+banner',
|
291 |
+
),
|
292 |
array(
|
293 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/password-policy-manager.jpg',
|
294 |
'desc' => __( 'Enforce strong password policies on WordPress', 'wp-security-audit-log' ),
|
295 |
+
'alt' => 'WPassword',
|
296 |
'link' => 'https://www.wpwhitesecurity.com/wordpress-plugins/password-policy-manager-wordpress/?utm_source=plugin&utm_medium=referral&utm_campaign=PPMWP&utm_content=WSAL+banner',
|
297 |
),
|
298 |
array(
|
301 |
'alt' => 'Website File Changes Monitor',
|
302 |
'link' => 'https://www.wpwhitesecurity.com/wordpress-plugins/website-file-changes-monitor/?utm_source=plugin&utm_medium=referral&utm_campaign=WFCM&utm_content=WSAL+banner',
|
303 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
304 |
array(
|
305 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/activity-log-for-mainwp.jpg',
|
306 |
'desc' => __( 'See the child sites activity logs from the central MainWP dashboard', 'wp-security-audit-log' ),
|
classes/Views/Reports.php
CHANGED
@@ -32,14 +32,14 @@ class WSAL_Views_Reports extends WSAL_ExtensionPlaceholderView {
|
|
32 |
* Method: Get View Name.
|
33 |
*/
|
34 |
public function GetName() {
|
35 |
-
return __( 'Reports ⇪', 'wp-security-audit-log' );
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
* Method: Get View Weight.
|
40 |
*/
|
41 |
public function GetWeight() {
|
42 |
-
return
|
43 |
}
|
44 |
|
45 |
/**
|
32 |
* Method: Get View Name.
|
33 |
*/
|
34 |
public function GetName() {
|
35 |
+
return __( 'Create Reports ⇪', 'wp-security-audit-log' );
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
* Method: Get View Weight.
|
40 |
*/
|
41 |
public function GetWeight() {
|
42 |
+
return 3;
|
43 |
}
|
44 |
|
45 |
/**
|
classes/Views/Search.php
CHANGED
@@ -32,14 +32,14 @@ class WSAL_Views_Search extends WSAL_ExtensionPlaceholderView {
|
|
32 |
* Method: Get View Name.
|
33 |
*/
|
34 |
public function GetName() {
|
35 |
-
return __( 'Search ⇪', 'wp-security-audit-log' );
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
* Method: Get View Weight.
|
40 |
*/
|
41 |
public function GetWeight() {
|
42 |
-
return
|
43 |
}
|
44 |
|
45 |
/**
|
32 |
* Method: Get View Name.
|
33 |
*/
|
34 |
public function GetName() {
|
35 |
+
return __( 'Log Search ⇪', 'wp-security-audit-log' );
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
* Method: Get View Weight.
|
40 |
*/
|
41 |
public function GetWeight() {
|
42 |
+
return 5;
|
43 |
}
|
44 |
|
45 |
/**
|
classes/Views/Settings.php
CHANGED
@@ -183,7 +183,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
183 |
* Method: Get View Weight.
|
184 |
*/
|
185 |
public function GetWeight() {
|
186 |
-
return
|
187 |
}
|
188 |
|
189 |
/**
|
@@ -406,7 +406,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
406 |
elementRef.checked = false;
|
407 |
// Ensure the "no" option is reselected.
|
408 |
jQuery('#delete_data_no').click();
|
409 |
-
}
|
410 |
}
|
411 |
}
|
412 |
|
@@ -1138,7 +1138,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1138 |
private function tab_audit_log_save() {
|
1139 |
// Get $_POST global array.
|
1140 |
$post_array = filter_input_array( INPUT_POST );
|
1141 |
-
|
1142 |
// Get pruning date.
|
1143 |
$pruning_date = isset( $post_array['PruningDate'] ) ? (int) sanitize_text_field( $post_array['PruningDate'] ) : false;
|
1144 |
$pruning_unit = isset( $post_array['pruning-unit'] ) ? sanitize_text_field( $post_array['pruning-unit'] ) : false;
|
@@ -1412,19 +1412,22 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1412 |
</td>
|
1413 |
</tr>
|
1414 |
<!-- / MainWP Child Site Stealth Mode -->
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
|
|
|
|
|
|
1428 |
</tbody>
|
1429 |
</table>
|
1430 |
|
@@ -1498,7 +1501,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1498 |
|
1499 |
$admin_blocking_plugins_support = isset( $post_array['mwp_admin_blocking_support'] ) ? $post_array['mwp_admin_blocking_support'] : false;
|
1500 |
if ( 'yes' === $admin_blocking_plugins_support ) {
|
1501 |
-
$this->_plugin->settings()->set_admin_blocking_plugin_support(true);
|
1502 |
}
|
1503 |
} else {
|
1504 |
$this->_plugin->settings()->deactivate_mainwp_child_stealth_mode();
|
@@ -1649,11 +1652,27 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1649 |
// Filter $_GET array for security.
|
1650 |
$get_array = filter_input_array( INPUT_GET );
|
1651 |
$this->check_ajax_request_is_valid( $get_array );
|
1652 |
-
|
1653 |
-
echo
|
1654 |
exit;
|
1655 |
}
|
1656 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1657 |
/**
|
1658 |
* Create json array of all possible event types.
|
1659 |
*
|
@@ -1667,7 +1686,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1667 |
|
1668 |
$event_types = $this->_plugin->alerts->get_event_type_data();
|
1669 |
|
1670 |
-
echo
|
1671 |
exit;
|
1672 |
}
|
1673 |
|
@@ -1683,8 +1702,8 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1683 |
$this->check_ajax_request_is_valid( $get_array );
|
1684 |
|
1685 |
$event_objects = $this->_plugin->alerts->get_event_objects_data();
|
1686 |
-
|
1687 |
-
echo
|
1688 |
exit;
|
1689 |
}
|
1690 |
|
@@ -1695,7 +1714,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1695 |
* @since 4.3.3
|
1696 |
*/
|
1697 |
public function ajax_get_all_event_ids() {
|
1698 |
-
|
1699 |
$get_array = filter_input_array( INPUT_GET );
|
1700 |
$this->check_ajax_request_is_valid( $get_array );
|
1701 |
|
@@ -1706,10 +1725,10 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1706 |
$alerts[] = (string) $details->code;
|
1707 |
}
|
1708 |
|
1709 |
-
echo
|
1710 |
exit;
|
1711 |
}
|
1712 |
-
|
1713 |
/**
|
1714 |
* Method: Get CPTs ajax handle.
|
1715 |
*
|
183 |
* Method: Get View Weight.
|
184 |
*/
|
185 |
public function GetWeight() {
|
186 |
+
return 8;
|
187 |
}
|
188 |
|
189 |
/**
|
406 |
elementRef.checked = false;
|
407 |
// Ensure the "no" option is reselected.
|
408 |
jQuery('#delete_data_no').click();
|
409 |
+
}
|
410 |
}
|
411 |
}
|
412 |
|
1138 |
private function tab_audit_log_save() {
|
1139 |
// Get $_POST global array.
|
1140 |
$post_array = filter_input_array( INPUT_POST );
|
1141 |
+
|
1142 |
// Get pruning date.
|
1143 |
$pruning_date = isset( $post_array['PruningDate'] ) ? (int) sanitize_text_field( $post_array['PruningDate'] ) : false;
|
1144 |
$pruning_unit = isset( $post_array['pruning-unit'] ) ? sanitize_text_field( $post_array['pruning-unit'] ) : false;
|
1412 |
</td>
|
1413 |
</tr>
|
1414 |
<!-- / MainWP Child Site Stealth Mode -->
|
1415 |
+
<?php $admin_blocking_plugins_support = $this->_plugin->settings()->get_admin_blocking_plugin_support(); ?>
|
1416 |
+
<tr>
|
1417 |
+
<th>
|
1418 |
+
<label for="mwp_admin_blocking_support"><?php esc_html_e( 'Admin blocking plugins support', 'wp-security-audit-log' ); ?></label>
|
1419 |
+
</th>
|
1420 |
+
<td>
|
1421 |
+
<fieldset>
|
1422 |
+
<label for="mwp_admin_blocking_support">
|
1423 |
+
<input type="checkbox" name="mwp_admin_blocking_support" value="yes"
|
1424 |
+
id="mwp_admin_blocking_support" <?php checked( $admin_blocking_plugins_support ); ?> <?php disabled( ! WpSecurityAuditLog::is_mainwp_active() || ! $stealth_mode ); ?>/>
|
1425 |
+
<?php esc_html_e( 'Enable early plugin loading on sites that use admin blocking plugins', 'wp-security-audit-log' ); ?>
|
1426 |
+
</label>
|
1427 |
+
</fieldset>
|
1428 |
+
</td>
|
1429 |
+
</tr>
|
1430 |
+
<!-- / Admin blocking plugins support -->
|
1431 |
</tbody>
|
1432 |
</table>
|
1433 |
|
1501 |
|
1502 |
$admin_blocking_plugins_support = isset( $post_array['mwp_admin_blocking_support'] ) ? $post_array['mwp_admin_blocking_support'] : false;
|
1503 |
if ( 'yes' === $admin_blocking_plugins_support ) {
|
1504 |
+
$this->_plugin->settings()->set_admin_blocking_plugin_support( true );
|
1505 |
}
|
1506 |
} else {
|
1507 |
$this->_plugin->settings()->deactivate_mainwp_child_stealth_mode();
|
1652 |
// Filter $_GET array for security.
|
1653 |
$get_array = filter_input_array( INPUT_GET );
|
1654 |
$this->check_ajax_request_is_valid( $get_array );
|
1655 |
+
|
1656 |
+
echo $this->filter_values_for_searched_term( array_values( WSAL_ConstantManager::getSeverities() ), $get_array['term'] );
|
1657 |
exit;
|
1658 |
}
|
1659 |
|
1660 |
+
/**
|
1661 |
+
* Filters values to return ones matching the desired term.
|
1662 |
+
*
|
1663 |
+
* @param array $items_to_filter
|
1664 |
+
* @param string $term
|
1665 |
+
* @return string
|
1666 |
+
*/
|
1667 |
+
public function filter_values_for_searched_term( $items_to_filter, $term ) {
|
1668 |
+
|
1669 |
+
$result = array_filter( $items_to_filter, function( $value ) use ( $term ) {
|
1670 |
+
return strpos( strtolower( $value ), strtolower( $term ) ) !== false;
|
1671 |
+
});
|
1672 |
+
|
1673 |
+
return wp_json_encode( $result );
|
1674 |
+
}
|
1675 |
+
|
1676 |
/**
|
1677 |
* Create json array of all possible event types.
|
1678 |
*
|
1686 |
|
1687 |
$event_types = $this->_plugin->alerts->get_event_type_data();
|
1688 |
|
1689 |
+
echo $this->filter_values_for_searched_term( array_values( $event_types ), $get_array['term'] );
|
1690 |
exit;
|
1691 |
}
|
1692 |
|
1702 |
$this->check_ajax_request_is_valid( $get_array );
|
1703 |
|
1704 |
$event_objects = $this->_plugin->alerts->get_event_objects_data();
|
1705 |
+
|
1706 |
+
echo $this->filter_values_for_searched_term( array_values( $event_objects ), $get_array['term'] );
|
1707 |
exit;
|
1708 |
}
|
1709 |
|
1714 |
* @since 4.3.3
|
1715 |
*/
|
1716 |
public function ajax_get_all_event_ids() {
|
1717 |
+
|
1718 |
$get_array = filter_input_array( INPUT_GET );
|
1719 |
$this->check_ajax_request_is_valid( $get_array );
|
1720 |
|
1725 |
$alerts[] = (string) $details->code;
|
1726 |
}
|
1727 |
|
1728 |
+
echo $this->filter_values_for_searched_term( array_values( $alerts ), $get_array['term'] );
|
1729 |
exit;
|
1730 |
}
|
1731 |
+
|
1732 |
/**
|
1733 |
* Method: Get CPTs ajax handle.
|
1734 |
*
|
classes/Views/SetupWizard.php
CHANGED
@@ -267,11 +267,12 @@ final class WSAL_Views_SetupWizard {
|
|
267 |
|
268 |
$installer_script_data = array(
|
269 |
'ajaxURL' => admin_url( 'admin-ajax.php' ),
|
270 |
-
'installing' =>
|
271 |
-
'already_installed' =>
|
272 |
-
'installed' =>
|
273 |
-
'activated' =>
|
274 |
-
'failed' =>
|
|
|
275 |
);
|
276 |
wp_localize_script( 'wsal-common', 'wsalCommonData', $installer_script_data );
|
277 |
|
@@ -426,7 +427,7 @@ final class WSAL_Views_SetupWizard {
|
|
426 |
private function wsal_step_welcome() {
|
427 |
// dismiss the setup modal in case if not already done
|
428 |
if ( ! $this->wsal->GetGlobalBooleanSetting( 'setup-modal-dismissed', false ) ) {
|
429 |
-
$this->wsal->SetGlobalBooleanSetting( 'setup-modal-dismissed', true );
|
430 |
}
|
431 |
?>
|
432 |
<p><?php esc_html_e( 'This wizard helps you configure the basic plugin settings. All these settings can be changed at a later stage from the plugin settings.', 'wp-security-audit-log' ); ?></p>
|
267 |
|
268 |
$installer_script_data = array(
|
269 |
'ajaxURL' => admin_url( 'admin-ajax.php' ),
|
270 |
+
'installing' => esc_html__( 'Installing, please wait', 'wp-security-audit-log' ),
|
271 |
+
'already_installed' => esc_html__( 'Already installed', 'wp-security-audit-log' ),
|
272 |
+
'installed' => esc_html__( 'Extension installed', 'wp-security-audit-log' ),
|
273 |
+
'activated' => esc_html__( 'Extension activated', 'wp-security-audit-log' ),
|
274 |
+
'failed' => esc_html__( 'Install failed', 'wp-security-audit-log' ),
|
275 |
+
'reloading_page' => esc_html__( 'Reloading page', 'wp-security-audit-log' )
|
276 |
);
|
277 |
wp_localize_script( 'wsal-common', 'wsalCommonData', $installer_script_data );
|
278 |
|
427 |
private function wsal_step_welcome() {
|
428 |
// dismiss the setup modal in case if not already done
|
429 |
if ( ! $this->wsal->GetGlobalBooleanSetting( 'setup-modal-dismissed', false ) ) {
|
430 |
+
$this->wsal->SetGlobalBooleanSetting( 'setup-modal-dismissed', true, true );
|
431 |
}
|
432 |
?>
|
433 |
<p><?php esc_html_e( 'This wizard helps you configure the basic plugin settings. All these settings can be changed at a later stage from the plugin settings.', 'wp-security-audit-log' ); ?></p>
|
classes/Views/ToggleAlerts.php
CHANGED
@@ -45,7 +45,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
45 |
* Method: Get View Weight.
|
46 |
*/
|
47 |
public function GetWeight() {
|
48 |
-
return
|
49 |
}
|
50 |
|
51 |
/**
|
@@ -83,6 +83,9 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
83 |
// Save enabled front end events.
|
84 |
WSAL_Settings::set_frontend_events( $frontend_events );
|
85 |
|
|
|
|
|
|
|
86 |
$enabled = array_map( 'intval', $post_array['alert'] );
|
87 |
$disabled = array();
|
88 |
$registered_alerts = $this->_plugin->alerts->GetAlerts();
|
@@ -109,15 +112,10 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
109 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
110 |
}
|
111 |
|
112 |
-
$alert = new WSAL_Alert(); // IDE type hinting.
|
113 |
-
$grouped_alerts = $this->_plugin->alerts->GetCategorizedAlerts( false );
|
114 |
-
$safe_names = array_map( array( $this, 'GetSafeCatgName' ), array_keys( $grouped_alerts ) );
|
115 |
-
$safe_names = array_combine( array_keys( $grouped_alerts ), $safe_names );
|
116 |
-
|
117 |
// Filter $_POST array.
|
118 |
$post_array = filter_input_array( INPUT_POST );
|
119 |
|
120 |
-
if ( isset( $post_array['submit'] )
|
121 |
check_admin_referer( 'wsal-togglealerts' );
|
122 |
try {
|
123 |
$this->save();
|
@@ -149,6 +147,11 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
149 |
}
|
150 |
}
|
151 |
|
|
|
|
|
|
|
|
|
|
|
152 |
$disabled_events = $this->_plugin->GetGlobalSetting( 'disabled-alerts' ); // Get disabled events.
|
153 |
$disabled_events = explode( ',', $disabled_events );
|
154 |
|
@@ -165,7 +168,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
165 |
// Allow further items to be added externally.
|
166 |
$subcat_alerts = apply_filters( 'wsal_togglealerts_sub_category_events', $subcat_alerts );
|
167 |
|
168 |
-
$obsolete_events = array( 9999, 2126 );
|
169 |
$obsolete_events = apply_filters( 'wsal_togglealerts_obsolete_events', $obsolete_events );
|
170 |
|
171 |
// check if the disabled events are enforced from the MainWP master site
|
@@ -173,380 +176,280 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
173 |
$enforced_settings = $settings->get_mainwp_enforced_settings();
|
174 |
$disabled_events_enforced_by_mainwp = array_key_exists( 'disabled_events', $enforced_settings ) && ! empty( $enforced_settings[ 'disabled_events' ]);
|
175 |
?>
|
176 |
-
|
177 |
-
<form method="post" id="wsal-alerts-level">
|
178 |
-
<?php wp_nonce_field( 'wsal-log-level', 'wsal-log-level-nonce' ); ?>
|
179 |
-
<fieldset>
|
180 |
-
<label for="wsal-log-level"><?php esc_html_e( 'Log Level: ', 'wp-security-audit-log' ); ?></label>
|
181 |
-
<select name="wsal-log-level" id="wsal-log-level" onchange="this.form.submit()"<?php if ( $disabled_events_enforced_by_mainwp ): ?> disabled="disabled"<?php endif; ?>>
|
182 |
-
<?php foreach ( $log_level_options as $log_level_id => $log_level_label ): ?>
|
183 |
-
<option value="<?php echo $log_level_id; ?>" <?php echo selected( $log_level, $log_level_id ); ?>><?php echo $log_level_label; ?></option>
|
184 |
-
<?php endforeach; ?>
|
185 |
-
</select>
|
186 |
-
<p class="description">
|
187 |
-
<?php echo wp_kses( __( 'Use the Log level drop down menu above to use one of our preset log levels. Alternatively you can enable or disable any of the individual events from the below tabs. Refer to <a href="https://wpactivitylog.com/support/kb/list-wordpress-activity-log-event-ids/" target="_blank">the complete list of WordPress activity log event IDs</a> for reference on all the events the plugin can keep a log of.', 'wp-security-audit-log' ), $this->_plugin->allowed_html_tags ); ?>
|
188 |
-
</p>
|
189 |
-
</fieldset>
|
190 |
-
</form>
|
191 |
-
</p>
|
192 |
<h2 id="wsal-tabs" class="nav-tab-wrapper">
|
193 |
-
|
194 |
-
<a href="#tab-<?php echo esc_attr( $safe ); ?>" class="nav-tab"><?php echo esc_html( $name ); ?></a>
|
195 |
-
<?php endforeach; ?>
|
196 |
<a href="#tab-third-party-plugins" class="nav-tab">
|
197 |
<?php esc_html_e( 'Third party plugins', 'wp-security-audit-log' ); ?>
|
198 |
</a>
|
199 |
-
</h2>
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
continue;
|
213 |
-
}
|
214 |
-
?>
|
215 |
-
<a href="#tab-<?php echo esc_attr( $this->GetSafeCatgName( $subname ) ); ?>"
|
216 |
-
class="nav-tab"
|
217 |
-
data-parent="tab-<?php echo esc_attr( $safe_names[ $name ] ); ?>">
|
218 |
-
<?php echo esc_html( $subname ); ?>
|
219 |
-
</a>
|
220 |
<?php endforeach; ?>
|
221 |
-
</
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
switch ( $name ) {
|
254 |
-
case 'User Accounts':
|
255 |
-
if ( 'Multisite User Profiles' === $subname ) {
|
256 |
-
// Check if this is a multisite.
|
257 |
-
if ( ! is_multisite() ) {
|
258 |
-
$disable_inputs = 'disabled';
|
259 |
-
}
|
260 |
-
}
|
261 |
-
break;
|
262 |
-
|
263 |
-
case 'WooCommerce':
|
264 |
-
case 'WooCommerce Products':
|
265 |
-
// Check if WooCommerce plugin exists.
|
266 |
-
if ( ! WpSecurityAuditLog::is_woocommerce_active() ) {
|
267 |
-
$disable_inputs = 'disabled';
|
268 |
-
}
|
269 |
-
break;
|
270 |
-
|
271 |
-
case 'Yoast SEO':
|
272 |
-
// Check if Yoast SEO plugin exists.
|
273 |
-
if ( ! WpSecurityAuditLog::is_wpseo_active() ) {
|
274 |
-
$disable_inputs = 'disabled';
|
275 |
-
}
|
276 |
-
break;
|
277 |
-
|
278 |
-
case 'Multisite Network Sites':
|
279 |
-
// Disable if not multisite.
|
280 |
-
if ( ! is_multisite() ) {
|
281 |
-
$disable_inputs = 'disabled';
|
282 |
-
}
|
283 |
-
break;
|
284 |
-
|
285 |
-
default:
|
286 |
-
break;
|
287 |
-
}
|
288 |
-
}
|
289 |
-
|
290 |
-
if ( $disabled_events_enforced_by_mainwp ) {
|
291 |
-
$disable_inputs = 'disabled';
|
292 |
-
}
|
293 |
-
?>
|
294 |
-
<table class="wp-list-table wsal-tab widefat fixed wsal-sub-tab" cellspacing="0" id="tab-<?php echo esc_attr( $this->GetSafeCatgName( $subname ) ); ?>">
|
295 |
<thead>
|
296 |
<tr>
|
297 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
298 |
<th width="80"><?php esc_html_e( 'Code', 'wp-security-audit-log' ); ?></th>
|
299 |
<th width="100"><?php esc_html_e( 'Severity', 'wp-security-audit-log' ); ?></th>
|
300 |
<th><?php esc_html_e( 'Description', 'wp-security-audit-log' ); ?></th>
|
|
|
|
|
301 |
</tr>
|
302 |
</thead>
|
303 |
<tbody>
|
304 |
-
<?php if ( __( 'Content', 'wp-security-audit-log' ) === $subname ) : ?>
|
305 |
-
<tr>
|
306 |
-
<td colspan="4">
|
307 |
-
<p class="wsal-tab-help description"><?php echo wp_kses( __( '<strong>Note:</strong> Post refers to any type of content, i.e. blog post, page or a post with a custom post type.', 'wp-security-audit-log' ), $this->_plugin->allowed_html_tags ); ?></p>
|
308 |
-
</td>
|
309 |
-
</tr>
|
310 |
-
<?php elseif ( __( 'WooCommerce', 'wp-security-audit-log' ) === $subname || __( 'WooCommerce Products', 'wp-security-audit-log' ) === $subname ) : ?>
|
311 |
-
<?php if ( ! empty( $disable_inputs ) ) : ?>
|
312 |
-
<tr>
|
313 |
-
<td colspan="4">
|
314 |
-
<p class="wsal-tab-help wsal-tab-notice description"><?php esc_html_e( 'The plugin WooCommerce is not installed on your website so these events have been disabled.', 'wp-security-audit-log' ); ?></p>
|
315 |
-
</td>
|
316 |
-
</tr>
|
317 |
-
<?php endif; ?>
|
318 |
-
<?php if ( __( 'WooCommerce Products', 'wp-security-audit-log' ) === $subname ) : ?>
|
319 |
-
<tr>
|
320 |
-
<td colspan="4">
|
321 |
-
<h3 class="sub-category"><?php esc_html_e( 'Products', 'wp-security-audit-log' ); ?></h3>
|
322 |
-
</td>
|
323 |
-
</tr>
|
324 |
-
<?php endif; ?>
|
325 |
-
<tr>
|
326 |
-
<td colspan="4">
|
327 |
-
<h3 class="sub-category"><?php esc_html_e( 'Post Changes', 'wp-security-audit-log' ); ?></h3>
|
328 |
-
</td>
|
329 |
-
</tr>
|
330 |
-
<?php elseif ( __( 'MultiSite', 'wp-security-audit-log' ) === $subname ) : ?>
|
331 |
-
<?php if ( ! empty( $disable_inputs ) ) : ?>
|
332 |
-
<tr>
|
333 |
-
<td colspan="4">
|
334 |
-
<p class="wsal-tab-help wsal-tab-notice description"><?php esc_html_e( 'Your website is a single site so the multisite events have been disabled.', 'wp-security-audit-log' ); ?></p>
|
335 |
-
</td>
|
336 |
-
</tr>
|
337 |
-
<?php endif; ?>
|
338 |
-
<?php elseif ( __( 'Other User Activity', 'wp-security-audit-log' ) === $subname ) : ?>
|
339 |
-
<tr>
|
340 |
-
<td colspan="4">
|
341 |
-
<h3 class="sub-category"><?php esc_html_e( 'Logins & Logouts', 'wp-security-audit-log' ); ?></h3>
|
342 |
-
</td>
|
343 |
-
</tr>
|
344 |
-
<?php endif; ?>
|
345 |
-
|
346 |
<?php
|
347 |
-
// Events sections loop.
|
348 |
-
foreach ( $alerts as $alert ) {
|
349 |
-
if ( $alert->code <= 0006 ) {
|
350 |
-
continue; // <- Ignore php alerts.
|
351 |
-
}
|
352 |
|
353 |
-
|
354 |
-
|
355 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
356 |
|
357 |
-
|
358 |
-
|
359 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
case false:
|
367 |
-
$attrs = 'title="' . __( 'Not Available', 'wp-security-audit-log' ) . '" class="alert-unavailable"';
|
368 |
-
break;
|
369 |
-
default:
|
370 |
-
// fallback for any other cases would go here
|
371 |
-
break;
|
372 |
-
}
|
373 |
-
if ( in_array( $alert->code, $subcat_alerts, true ) ) {
|
374 |
-
?>
|
375 |
-
<tr>
|
376 |
-
<td colspan="4">
|
377 |
-
<h3 class="sub-category">
|
378 |
-
<?php
|
379 |
-
$subcat_title = '';
|
380 |
-
switch ( $alert->code ) {
|
381 |
-
case 1000:
|
382 |
-
$subcat_title = esc_html__( 'User Logins/Logouts', 'wp-security-audit-log' );
|
383 |
-
break;
|
384 |
-
case 1004:
|
385 |
-
$subcat_title = esc_html__( 'User Sessions', 'wp-security-audit-log' );
|
386 |
-
break;
|
387 |
-
case 2010:
|
388 |
-
$subcat_title = esc_html__( 'Files', 'wp-security-audit-log' );
|
389 |
-
break;
|
390 |
-
case 2011:
|
391 |
-
$subcat_title = esc_html__( 'Post Settings', 'wp-security-audit-log' );
|
392 |
-
break;
|
393 |
-
default:
|
394 |
-
break;
|
395 |
}
|
|
|
396 |
|
397 |
-
|
398 |
-
|
399 |
-
if (
|
400 |
-
|
|
|
401 |
}
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
420 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
?>
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
esc_html_e( 'Critical', 'wp-security-audit-log' );
|
431 |
-
} elseif ( 'E_WARNING' === $severity_obj->name ) {
|
432 |
-
esc_html_e( 'Warning', 'wp-security-audit-log' );
|
433 |
-
} elseif ( 'E_NOTICE' === $severity_obj->name ) {
|
434 |
-
esc_html_e( 'Notification', 'wp-security-audit-log' );
|
435 |
-
} elseif ( 'WSAL_CRITICAL' === $severity_obj->name ) {
|
436 |
-
esc_html_e( 'Critical', 'wp-security-audit-log' );
|
437 |
-
} elseif ( 'WSAL_HIGH' === $severity_obj->name ) {
|
438 |
-
esc_html_e( 'High', 'wp-security-audit-log' );
|
439 |
-
} elseif ( 'WSAL_MEDIUM' === $severity_obj->name ) {
|
440 |
-
esc_html_e( 'Medium', 'wp-security-audit-log' );
|
441 |
-
} elseif ( 'WSAL_LOW' === $severity_obj->name ) {
|
442 |
-
esc_html_e( 'Low', 'wp-security-audit-log' );
|
443 |
-
} elseif ( 'WSAL_INFORMATIONAL' === $severity_obj->name ) {
|
444 |
-
esc_html_e( 'Informational', 'wp-security-audit-log' );
|
445 |
-
} else {
|
446 |
-
esc_html_e( 'Notification', 'wp-security-audit-log' );
|
447 |
}
|
448 |
-
?>
|
449 |
-
</td>
|
450 |
-
<td><?php echo esc_html( $alert->desc ); ?></td>
|
451 |
-
</tr>
|
452 |
-
<?php
|
453 |
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
466 |
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
}
|
480 |
-
if ( 1003 === $alert->code ) {
|
481 |
-
$log_visitor_failed_login_limit = (int) $this->_plugin->GetGlobalSetting( 'log-visitor-failed-login-limit', 10 );
|
482 |
-
$log_visitor_failed_login_limit = ( -1 === $log_visitor_failed_login_limit ) ? '0' : $log_visitor_failed_login_limit;
|
483 |
-
?>
|
484 |
-
<tr>
|
485 |
-
<td></td>
|
486 |
-
<td><input name="log_visitor_failed_login_limit" type="number" class="check_visitor_log" value="<?php echo esc_attr( $log_visitor_failed_login_limit ); ?>"></td>
|
487 |
-
<td colspan="2">
|
488 |
-
<p><?php esc_html_e( 'Number of login attempts to log. Enter 0 to log all failed login attempts. (By default the plugin only logs up to 10 failed login because the process can be very resource intensive in case of a brute force attack)', 'wp-security-audit-log' ); ?></p>
|
489 |
-
</td>
|
490 |
-
</tr>
|
491 |
-
<?php
|
492 |
-
}
|
493 |
|
494 |
-
|
495 |
-
|
496 |
-
?>
|
497 |
-
<tr>
|
498 |
-
<th>
|
499 |
-
<input type="checkbox" name="frontend-events[login]" id="frontend-events-login" value="1" <?php checked( $frontend_events['login'] ); ?>>
|
500 |
-
</th>
|
501 |
-
<td colspan="3">
|
502 |
-
<label for="frontend-events-login"><?php esc_html_e( 'Keep a log of user log in activity on custom login forms (such as WooCommerce & membership plugins)', 'wp-security-audit-log' ); ?></label>
|
503 |
-
</td>
|
504 |
-
</tr>
|
505 |
-
<?php
|
506 |
}
|
507 |
-
|
508 |
-
do_action( 'wsal_togglealerts_append_content_to_toggle', $alert->code );
|
509 |
}
|
510 |
|
511 |
-
// File integrity scan link.
|
512 |
-
if ( __( 'Monitor File Changes', 'wp-security-audit-log' ) === $subname && ! defined( 'WFCM_PLUGIN_FILE' ) ) :
|
513 |
-
$redirect_args = array(
|
514 |
-
'page' => 'wsal-settings',
|
515 |
-
'tab' => 'file-changes',
|
516 |
-
);
|
517 |
-
?>
|
518 |
-
<tr>
|
519 |
-
<td>
|
520 |
-
<div class="addon-wrapper">
|
521 |
-
<img src="<?php echo trailingslashit( WSAL_BASE_URL ) . 'img/help/website-file-changes-monitor.jpg'; ?>">
|
522 |
-
<h4><?php echo esc_html__( 'Website File Changes Monitor', 'wp-security-audit-log' ); ?></h4>
|
523 |
-
<p><?php echo esc_html__( 'To keep a log of file changes please install Website File Changes Monitor, a plugin which is also developed by us.', 'wp-security-audit-log' ); ?></p><br>
|
524 |
-
<p><button class="install-addon button button-primary" data-nonce="<?php echo esc_attr( wp_create_nonce( 'wsal-install-addon' ) ); ?>" data-plugin-slug="website-file-changes-monitor/website-file-changes-monitor.php" data-plugin-download-url="https://downloads.wordpress.org/plugin/website-file-changes-monitor.latest-stable.zip"><?php _e( 'Install plugin now', 'wp-security-audit-log' ); ?></button><span class="spinner" style="display: none; visibility: visible; float: none; margin: 0 0 0 8px;"></span> <a href="https://wpactivitylog.com/support/kb/wordpress-files-changes-warning-activity-logs/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" rel="noopener noreferrer" target="_blank" style="margin-left: 15px;"><?php echo esc_html__( 'Learn More', 'wp-security-audit-log' ); ?></a></p>
|
525 |
-
</div>
|
526 |
-
</td>
|
527 |
-
</tr>
|
528 |
-
<style type="text/css">
|
529 |
-
#tab-monitor-file-changes thead {
|
530 |
-
display: none;
|
531 |
-
}
|
532 |
-
</style>
|
533 |
-
<?php
|
534 |
-
endif;
|
535 |
?>
|
536 |
</tbody>
|
537 |
</table>
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
<?php endforeach; ?>
|
543 |
-
<?php
|
544 |
-
$addons = new WSAL_PluginInstallAndActivate();
|
545 |
-
$addons->render();
|
546 |
-
?>
|
547 |
</div>
|
548 |
-
|
549 |
-
|
|
|
|
|
|
|
|
|
550 |
|
551 |
<?php if ( ! empty( $log_level_to_set ) ) : ?>
|
552 |
<!-- Log level updated modal -->
|
@@ -594,6 +497,16 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
594 |
// Remodal styles.
|
595 |
wp_enqueue_style( 'wsal-remodal', WSAL_BASE_URL . 'css/remodal.css', array(), '1.1.1' );
|
596 |
wp_enqueue_style( 'wsal-remodal-theme', WSAL_BASE_URL . 'css/remodal-default-theme.css', array(), '1.1.1' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
?>
|
598 |
<style type="text/css">
|
599 |
.wsal-tab {
|
@@ -672,28 +585,107 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
672 |
}
|
673 |
.addon-wrapper {
|
674 |
flex: 1 0 30%;
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
}
|
679 |
.addon-wrapper:hover {
|
680 |
border: 1px solid #ccc;
|
681 |
}
|
682 |
.addon-wrapper .button-primary {
|
683 |
position: relative;
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
697 |
}
|
698 |
</style>
|
699 |
<?php
|
@@ -707,12 +699,53 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
707 |
wp_enqueue_script(
|
708 |
'wsal-remodal-js',
|
709 |
WSAL_BASE_URL . 'js/remodal.min.js',
|
710 |
-
array(),
|
711 |
'1.1.1',
|
712 |
true
|
713 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
714 |
?>
|
715 |
<script type="text/javascript">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
716 |
jQuery(document).ready(function(){
|
717 |
var scrollHeight = jQuery(document).scrollTop();
|
718 |
// tab handling code
|
@@ -735,12 +768,12 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
735 |
}, 1);
|
736 |
});
|
737 |
// checkbox handling code
|
738 |
-
jQuery('
|
739 |
-
jQuery(this).parents('table:first').find('tbody>tr>th>:checkbox').attr('checked', this.checked);
|
740 |
});
|
741 |
-
jQuery('
|
742 |
var allchecked = jQuery(this).parents('tbody:first').find('th>:checkbox:not(:checked)').length === 0;
|
743 |
-
jQuery(this).parents('table:first').find('thead>tr>th:first>:checkbox:first').attr('checked', allchecked);
|
744 |
});
|
745 |
|
746 |
var hashlink = jQuery('#wsal-tabs>a[href="' + location.hash + '"]');
|
@@ -756,6 +789,63 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
756 |
jQuery('#wsal-tabs>a:first').click();
|
757 |
jQuery('.wsal-sub-tabs>a:first').click();
|
758 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
759 |
});
|
760 |
|
761 |
if (typeof toggle_modal !== 'undefined') {
|
45 |
* Method: Get View Weight.
|
46 |
*/
|
47 |
public function GetWeight() {
|
48 |
+
return 9;
|
49 |
}
|
50 |
|
51 |
/**
|
83 |
// Save enabled front end events.
|
84 |
WSAL_Settings::set_frontend_events( $frontend_events );
|
85 |
|
86 |
+
// Ensure we attempt to save even if eveything is disabled.
|
87 |
+
$post_array['alert'] = ( isset( $post_array['alert'] ) ) ? $post_array['alert'] : [];
|
88 |
+
|
89 |
$enabled = array_map( 'intval', $post_array['alert'] );
|
90 |
$disabled = array();
|
91 |
$registered_alerts = $this->_plugin->alerts->GetAlerts();
|
112 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
113 |
}
|
114 |
|
|
|
|
|
|
|
|
|
|
|
115 |
// Filter $_POST array.
|
116 |
$post_array = filter_input_array( INPUT_POST );
|
117 |
|
118 |
+
if ( isset( $post_array['submit'] ) ) {
|
119 |
check_admin_referer( 'wsal-togglealerts' );
|
120 |
try {
|
121 |
$this->save();
|
147 |
}
|
148 |
}
|
149 |
|
150 |
+
$alert = new WSAL_Alert(); // IDE type hinting.
|
151 |
+
$grouped_alerts = $this->_plugin->alerts->GetCategorizedAlerts( false );
|
152 |
+
$safe_names = array_map( array( $this, 'GetSafeCatgName' ), array_keys( $grouped_alerts ) );
|
153 |
+
$safe_names = array_combine( array_keys( $grouped_alerts ), $safe_names );
|
154 |
+
|
155 |
$disabled_events = $this->_plugin->GetGlobalSetting( 'disabled-alerts' ); // Get disabled events.
|
156 |
$disabled_events = explode( ',', $disabled_events );
|
157 |
|
168 |
// Allow further items to be added externally.
|
169 |
$subcat_alerts = apply_filters( 'wsal_togglealerts_sub_category_events', $subcat_alerts );
|
170 |
|
171 |
+
$obsolete_events = array( 9999, 2126, 99999 );
|
172 |
$obsolete_events = apply_filters( 'wsal_togglealerts_obsolete_events', $obsolete_events );
|
173 |
|
174 |
// check if the disabled events are enforced from the MainWP master site
|
176 |
$enforced_settings = $settings->get_mainwp_enforced_settings();
|
177 |
$disabled_events_enforced_by_mainwp = array_key_exists( 'disabled_events', $enforced_settings ) && ! empty( $enforced_settings[ 'disabled_events' ]);
|
178 |
?>
|
179 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
<h2 id="wsal-tabs" class="nav-tab-wrapper">
|
181 |
+
<a href="#tab-all" class="nav-tab"><?php esc_html_e( 'Enable/Disable alerts', 'wp-security-audit-log' ); ?></a>
|
|
|
|
|
182 |
<a href="#tab-third-party-plugins" class="nav-tab">
|
183 |
<?php esc_html_e( 'Third party plugins', 'wp-security-audit-log' ); ?>
|
184 |
</a>
|
185 |
+
</h2>
|
186 |
+
|
187 |
+
<div class="nav-tabs">
|
188 |
+
|
189 |
+
<div id="tab-all" class="wsal-tab widefat fixed">
|
190 |
+
|
191 |
+
<form method="post" id="wsal-alerts-level">
|
192 |
+
<?php wp_nonce_field( 'wsal-log-level', 'wsal-log-level-nonce' ); ?>
|
193 |
+
<fieldset>
|
194 |
+
<label for="wsal-log-level"><?php esc_html_e( 'Log Level: ', 'wp-security-audit-log' ); ?></label>
|
195 |
+
<select name="wsal-log-level" id="wsal-log-level" onchange="this.form.submit()"<?php if ( $disabled_events_enforced_by_mainwp ): ?> disabled="disabled"<?php endif; ?>>
|
196 |
+
<?php foreach ( $log_level_options as $log_level_id => $log_level_label ): ?>
|
197 |
+
<option value="<?php echo $log_level_id; ?>" <?php echo selected( $log_level, $log_level_id ); ?>><?php echo $log_level_label; ?></option>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
<?php endforeach; ?>
|
199 |
+
</select>
|
200 |
+
<p class="description">
|
201 |
+
<?php echo wp_kses( __( 'Use the Log level drop down menu above to use one of our preset log levels. Alternatively you can enable or disable any of the individual events from the below tabs. Refer to <a href="https://wpactivitylog.com/support/kb/list-wordpress-activity-log-event-ids/" target="_blank">the complete list of WordPress activity log event IDs</a> for reference on all the events the plugin can keep a log of.', 'wp-security-audit-log' ), $this->_plugin->allowed_html_tags ); ?>
|
202 |
+
</p>
|
203 |
+
</fieldset>
|
204 |
+
</form>
|
205 |
+
|
206 |
+
<form id="audit-log-viewer" method="post">
|
207 |
+
|
208 |
+
<input type="hidden" name="page" value="<?php echo isset( $_GET['page'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_GET['page'] ) ) ) : false; ?>" />
|
209 |
+
<?php wp_nonce_field( 'wsal-togglealerts' ); ?>
|
210 |
+
|
211 |
+
<div id="flitering-options-wrapper">
|
212 |
+
<div class="search">
|
213 |
+
<span class="search-title"><?php esc_html_e( 'Choose your query and enter your search term', 'wp-security-audit-log' ); ?></span>
|
214 |
+
<select name="searchingFor" id="search-subject" class="search-input-style">
|
215 |
+
<option value="code"><?php esc_html_e( 'Event code', 'wp-security-audit-log' ); ?></option>
|
216 |
+
<option value="severity"><?php esc_html_e( 'Severity', 'wp-security-audit-log' ); ?></option>
|
217 |
+
<option value="desc"><?php esc_html_e( 'Description', 'wp-security-audit-log' ); ?></option>
|
218 |
+
</select>
|
219 |
+
<input type="text" id="query-input" class="search-input-style" onkeyup="filterEventTable()" placeholder="Enter search term">
|
220 |
+
</div>
|
221 |
+
<div class="center-bit"><span><?php esc_html_e( 'OR', 'wp-security-audit-log' ); ?></span></div>
|
222 |
+
<div class="choose">
|
223 |
+
<span class="search-title"><?php esc_html_e( 'Choose a category', 'wp-security-audit-log' ); ?></span>
|
224 |
+
<select name="catFilter" id="filter-cat" class="search-input-style">
|
225 |
+
<option value="all"><?php esc_html_e( 'All categories', 'wp-security-audit-log' ); ?></option>
|
226 |
+
</select>
|
227 |
+
</div>
|
228 |
+
</div>
|
229 |
+
|
230 |
+
<table id="event-toggle-table">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
<thead>
|
232 |
<tr>
|
233 |
+
<?php
|
234 |
+
foreach ( $grouped_alerts as $name => $group ) {
|
235 |
+
foreach ( $group as $subname => $alerts ) {
|
236 |
+
$active = array();
|
237 |
+
$allactive = true;
|
238 |
+
/** @var WSAL_Alert $alert */
|
239 |
+
foreach ( $alerts as $alert ) {
|
240 |
+
if ( $alert->code <= 0006 ) {
|
241 |
+
continue; // <- Ignore php alerts.
|
242 |
+
}
|
243 |
+
if ( in_array( $alert->code, $obsolete_events, true ) ) {
|
244 |
+
continue; // <- Ignore promo alerts.
|
245 |
+
}
|
246 |
+
$active[ $alert->code ] = $this->_plugin->alerts->IsEnabled( $alert->code );
|
247 |
+
if ( ! $active[ $alert->code ] ) {
|
248 |
+
$allactive = false;
|
249 |
+
}
|
250 |
+
}
|
251 |
+
}
|
252 |
+
}
|
253 |
+
?>
|
254 |
+
<th width="48"><input type="checkbox" <?php checked( $allactive ); ?> /></th>
|
255 |
<th width="80"><?php esc_html_e( 'Code', 'wp-security-audit-log' ); ?></th>
|
256 |
<th width="100"><?php esc_html_e( 'Severity', 'wp-security-audit-log' ); ?></th>
|
257 |
<th><?php esc_html_e( 'Description', 'wp-security-audit-log' ); ?></th>
|
258 |
+
<th style="display: none;"></th>
|
259 |
+
<th style="display: none;"></th>
|
260 |
</tr>
|
261 |
</thead>
|
262 |
<tbody>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
263 |
<?php
|
|
|
|
|
|
|
|
|
|
|
264 |
|
265 |
+
foreach ( $grouped_alerts as $name => $group ) {
|
266 |
+
foreach ( $group as $subname => $alerts ) {
|
267 |
+
$active = array();
|
268 |
+
$allactive = true;
|
269 |
+
/** @var WSAL_Alert $alert */
|
270 |
+
foreach ( $alerts as $alert ) {
|
271 |
+
$active[ $alert->code ] = $this->_plugin->alerts->IsEnabled( $alert->code );
|
272 |
+
if ( ! $active[ $alert->code ] ) {
|
273 |
+
$allactive = false;
|
274 |
+
}
|
275 |
+
}
|
276 |
|
277 |
+
// Disabled alerts.
|
278 |
+
$disable_inputs = '';
|
279 |
+
$disabled_message = '';
|
280 |
+
|
281 |
+
// Skip Pages and CPTs section.
|
282 |
+
if ( __( 'Custom Post Types', 'wp-security-audit-log' ) === $subname || __( 'Pages', 'wp-security-audit-log' ) === $subname ) {
|
283 |
+
continue;
|
284 |
+
} elseif (
|
285 |
+
'bbPress Forums' === $name
|
286 |
+
|| 'WooCommerce' === $name
|
287 |
+
|| 'Yoast SEO' === $name
|
288 |
+
|| 'Multisite Network Sites' === $name
|
289 |
+
|| 'User Accounts' === $name
|
290 |
+
) {
|
291 |
+
switch ( $name ) {
|
292 |
+
case 'User Accounts':
|
293 |
+
if ( 'Multisite User Profiles' === $subname ) {
|
294 |
+
// Check if this is a multisite.
|
295 |
+
if ( ! is_multisite() ) {
|
296 |
+
$disable_inputs = 'disabled';
|
297 |
+
}
|
298 |
+
}
|
299 |
+
break;
|
300 |
+
|
301 |
+
case 'WooCommerce':
|
302 |
+
case 'WooCommerce Products':
|
303 |
+
// Check if WooCommerce plugin exists.
|
304 |
+
if ( ! WpSecurityAuditLog::is_woocommerce_active() ) {
|
305 |
+
$disable_inputs = 'disabled';
|
306 |
+
$disabled_message = esc_html__( 'Please activate WooCommerce to enable this alert', 'wp-security-audit-log' );
|
307 |
+
}
|
308 |
+
break;
|
309 |
|
310 |
+
case 'Yoast SEO':
|
311 |
+
// Check if Yoast SEO plugin exists.
|
312 |
+
if ( ! WpSecurityAuditLog::is_wpseo_active() ) {
|
313 |
+
$disable_inputs = 'disabled';
|
314 |
+
$disabled_message = esc_html__( 'Please activate the Yoast SEO Plugin', 'wp-security-audit-log' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
315 |
}
|
316 |
+
break;
|
317 |
|
318 |
+
case 'Multisite Network Sites':
|
319 |
+
// Disable if not multisite.
|
320 |
+
if ( ! is_multisite() ) {
|
321 |
+
$disable_inputs = 'disabled';
|
322 |
+
$disabled_message = esc_html__( 'Your website is a single site so the multisite events have been disabled.', 'wp-security-audit-log' );
|
323 |
}
|
324 |
+
break;
|
325 |
+
|
326 |
+
default:
|
327 |
+
break;
|
328 |
+
}
|
329 |
+
}
|
330 |
+
|
331 |
+
if ( $disabled_events_enforced_by_mainwp ) {
|
332 |
+
$disable_inputs = 'disabled';
|
333 |
+
}
|
334 |
+
|
335 |
+
foreach ( $alerts as $alert ) {
|
336 |
+
|
337 |
+
if ( $alert->code <= 0006 ) {
|
338 |
+
continue; // <- Ignore php alerts.
|
339 |
+
}
|
340 |
+
if ( in_array( $alert->code, $obsolete_events, true ) ) {
|
341 |
+
continue; // <- Ignore promo alerts.
|
342 |
+
}
|
343 |
+
|
344 |
+
$disable_inputs_needed = ( ! empty( $disable_inputs ) ) ? esc_attr( $disable_inputs ) : '';
|
345 |
+
$disabled_tooltip = ( $disabled_message ) ? 'data-tooltip="' . $disabled_message . '"' : '';
|
346 |
+
$checkbox_markup = '<input name="alert[]" type="checkbox" class="alert"'. checked( $this->_plugin->alerts->IsEnabled( $alert->code ), true, false ) .' value="'. esc_attr( (int) $alert->code ) .'" '. $disable_inputs_needed .' />';
|
347 |
+
$severity = '';
|
348 |
+
$severity_obj = $this->_plugin->constants->GetConstantBy( 'value', $alert->severity );
|
349 |
+
|
350 |
+
if ( is_object( $severity_obj ) ) {
|
351 |
+
if ( 'E_CRITICAL' === $severity_obj->name ) {
|
352 |
+
$severity = esc_html__( 'Critical', 'wp-security-audit-log' );
|
353 |
+
} elseif ( 'E_WARNING' === $severity_obj->name ) {
|
354 |
+
$severity = esc_html__( 'Warning', 'wp-security-audit-log' );
|
355 |
+
} elseif ( 'E_NOTICE' === $severity_obj->name ) {
|
356 |
+
$severity = esc_html__( 'Notification', 'wp-security-audit-log' );
|
357 |
+
} elseif ( 'WSAL_CRITICAL' === $severity_obj->name ) {
|
358 |
+
$severity = esc_html__( 'Critical', 'wp-security-audit-log' );
|
359 |
+
} elseif ( 'WSAL_HIGH' === $severity_obj->name ) {
|
360 |
+
$severity = esc_html__( 'High', 'wp-security-audit-log' );
|
361 |
+
} elseif ( 'WSAL_MEDIUM' === $severity_obj->name ) {
|
362 |
+
$severity = esc_html__( 'Medium', 'wp-security-audit-log' );
|
363 |
+
} elseif ( 'WSAL_LOW' === $severity_obj->name ) {
|
364 |
+
$severity = esc_html__( 'Low', 'wp-security-audit-log' );
|
365 |
+
} elseif ( 'WSAL_INFORMATIONAL' === $severity_obj->name ) {
|
366 |
+
$severity = esc_html__( 'Informational', 'wp-security-audit-log' );
|
367 |
+
} else {
|
368 |
+
$severity = esc_html__( 'Notification', 'wp-security-audit-log' );
|
369 |
}
|
370 |
+
}
|
371 |
+
|
372 |
+
echo '<tr class="alert-wrapper '. $disable_inputs_needed .'" data-alert-cat="' . $alert->catg . '" data-alert-subcat="' . $alert->subcatg . '" ' . $disabled_tooltip . '>';
|
373 |
+
echo '<th>' . $checkbox_markup . '</th>';
|
374 |
+
echo '<td>' . $alert->code . '</td>';
|
375 |
+
echo '<td>' . $severity . '</td>';
|
376 |
+
echo '<td>' . $alert->desc . '</td>';
|
377 |
+
echo '<td style="display: none;">' . $alert->catg . '</td>';
|
378 |
+
echo '<td style="display: none;">' . $alert->subcatg . '</td>';
|
379 |
+
echo '</tr>';
|
380 |
+
|
381 |
+
if ( 4000 === $alert->code ) {
|
382 |
+
$frontend_events = WSAL_Settings::get_frontend_events();
|
383 |
?>
|
384 |
+
<tr class="alert-wrapper" data-alert-cat="Users Logins & Sessions Events" data-alert-subcat="User Activity">
|
385 |
+
<td></td>
|
386 |
+
<td><input type="checkbox" name="frontend-events[register]" id="frontend-events-register" value="1" <?php checked( $frontend_events['register'] ); ?>></td>
|
387 |
+
<td colspan="2">
|
388 |
+
<label for="frontend-events-register"><?php esc_html_e( 'Keep a log when a visitor registers a user on the website. Only enable this if you allow visitors to register as users on your website. User registration is disabled by default in WordPress.', 'wp-security-audit-log' ); ?></label>
|
389 |
+
</td>
|
390 |
+
</tr>
|
391 |
+
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
392 |
}
|
|
|
|
|
|
|
|
|
|
|
393 |
|
394 |
+
if ( 1002 === $alert->code ) {
|
395 |
+
$log_failed_login_limit = (int) $this->_plugin->GetGlobalSetting( 'log-failed-login-limit', 10 );
|
396 |
+
$log_failed_login_limit = ( -1 === $log_failed_login_limit ) ? '0' : $log_failed_login_limit;
|
397 |
+
?>
|
398 |
+
<tr class="alert-wrapper" data-alert-cat="Users Logins & Sessions Events" data-alert-subcat="User Activity">
|
399 |
+
<td></td>
|
400 |
+
<td><input name="log_failed_login_limit" type="number" class="check_visitor_log" value="<?php echo esc_attr( $log_failed_login_limit ); ?>"></td>
|
401 |
+
<td colspan="2">
|
402 |
+
<?php esc_html_e( 'Number of login attempts to log. Enter 0 to log all failed login attempts. (By default the plugin only logs up to 10 failed login because the process can be very resource intensive in case of a brute force attack)', 'wp-security-audit-log' ); ?>
|
403 |
+
</td>
|
404 |
+
</tr>
|
405 |
+
<?php
|
406 |
+
}
|
407 |
+
if ( 1003 === $alert->code ) {
|
408 |
+
$log_visitor_failed_login_limit = (int) $this->_plugin->GetGlobalSetting( 'log-visitor-failed-login-limit', 10 );
|
409 |
+
$log_visitor_failed_login_limit = ( -1 === $log_visitor_failed_login_limit ) ? '0' : $log_visitor_failed_login_limit;
|
410 |
+
?>
|
411 |
+
<tr class="alert-wrapper" data-alert-cat="Users Logins & Sessions Events" data-alert-subcat="User Activity">
|
412 |
+
<td></td>
|
413 |
+
<td><input name="log_visitor_failed_login_limit" type="number" class="check_visitor_log" value="<?php echo esc_attr( $log_visitor_failed_login_limit ); ?>"></td>
|
414 |
+
<td colspan="2">
|
415 |
+
<p><?php esc_html_e( 'Number of login attempts to log. Enter 0 to log all failed login attempts. (By default the plugin only logs up to 10 failed login because the process can be very resource intensive in case of a brute force attack)', 'wp-security-audit-log' ); ?></p>
|
416 |
+
</td>
|
417 |
+
</tr>
|
418 |
+
<?php
|
419 |
+
}
|
420 |
|
421 |
+
if ( 1000 === $alert->code ) {
|
422 |
+
$frontend_events = WSAL_Settings::get_frontend_events();
|
423 |
+
?>
|
424 |
+
<tr class="alert-wrapper" data-alert-cat="Users Logins & Sessions Events" data-alert-subcat="User Activity">
|
425 |
+
<td></td>
|
426 |
+
<td><input type="checkbox" name="frontend-events[login]" id="frontend-events-login" value="1" <?php checked( $frontend_events['login'] ); ?>></td>
|
427 |
+
<td colspan="3">
|
428 |
+
<label for="frontend-events-login"><?php esc_html_e( 'Keep a log of user log in activity on custom login forms (such as WooCommerce & membership plugins)', 'wp-security-audit-log' ); ?></label>
|
429 |
+
</td>
|
430 |
+
</tr>
|
431 |
+
<?php
|
432 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
433 |
|
434 |
+
do_action( 'wsal_togglealerts_append_content_to_toggle', $alert->code );
|
435 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
436 |
}
|
|
|
|
|
437 |
}
|
438 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
439 |
?>
|
440 |
</tbody>
|
441 |
</table>
|
442 |
+
|
443 |
+
<p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php echo esc_attr( __( 'Save Changes', 'wp-security-audit-log' ) ); ?>"></p>
|
444 |
+
</form>
|
445 |
+
|
|
|
|
|
|
|
|
|
|
|
446 |
</div>
|
447 |
+
<?php
|
448 |
+
$addons = new WSAL_PluginInstallAndActivate();
|
449 |
+
$addons->render();
|
450 |
+
?>
|
451 |
+
</div>
|
452 |
+
|
453 |
|
454 |
<?php if ( ! empty( $log_level_to_set ) ) : ?>
|
455 |
<!-- Log level updated modal -->
|
497 |
// Remodal styles.
|
498 |
wp_enqueue_style( 'wsal-remodal', WSAL_BASE_URL . 'css/remodal.css', array(), '1.1.1' );
|
499 |
wp_enqueue_style( 'wsal-remodal-theme', WSAL_BASE_URL . 'css/remodal-default-theme.css', array(), '1.1.1' );
|
500 |
+
|
501 |
+
|
502 |
+
// Darktooltip styles.
|
503 |
+
wp_enqueue_style(
|
504 |
+
'darktooltip',
|
505 |
+
WSAL_BASE_URL . 'css/darktooltip.css',
|
506 |
+
array(),
|
507 |
+
'0.4.0'
|
508 |
+
);
|
509 |
+
|
510 |
?>
|
511 |
<style type="text/css">
|
512 |
.wsal-tab {
|
585 |
}
|
586 |
.addon-wrapper {
|
587 |
flex: 1 0 30%;
|
588 |
+
margin: 0 5px 11px 5px;
|
589 |
+
border: 1px solid #eee;
|
590 |
+
padding: 20px;
|
591 |
}
|
592 |
.addon-wrapper:hover {
|
593 |
border: 1px solid #ccc;
|
594 |
}
|
595 |
.addon-wrapper .button-primary {
|
596 |
position: relative;
|
597 |
+
padding: 13px 26px !important;
|
598 |
+
font-weight: 500;
|
599 |
+
font-size: 16px;
|
600 |
+
line-height: 1;
|
601 |
+
color: white;
|
602 |
+
background: #007cba;
|
603 |
+
border: none;
|
604 |
+
outline: none;
|
605 |
+
overflow: hidden;
|
606 |
+
cursor: pointer;
|
607 |
+
filter: drop-shadow(0 2px 8px rgba(39, 94, 254, 0.32));
|
608 |
+
transition: 0.3s cubic-bezier(0.215, 0.61, 0.355, 1);
|
609 |
+
line-height: 1 !important;
|
610 |
+
}
|
611 |
+
|
612 |
+
#flitering-options-wrapper {
|
613 |
+
display: flex;
|
614 |
+
}
|
615 |
+
#flitering-options-wrapper .search, #flitering-options-wrapper .choose {
|
616 |
+
padding: 10px 0;
|
617 |
+
}
|
618 |
+
#flitering-options-wrapper > div {
|
619 |
+
min-width: 80px;
|
620 |
+
}
|
621 |
+
.search-title {
|
622 |
+
display: flex;
|
623 |
+
margin-bottom: 10px;
|
624 |
+
}
|
625 |
+
.center-bit {
|
626 |
+
text-align: center;
|
627 |
+
line-height: 82px;
|
628 |
+
}
|
629 |
+
.center-bit span {
|
630 |
+
background: #2271b1;
|
631 |
+
color: #fff;
|
632 |
+
width: 48px;
|
633 |
+
height: 48px;
|
634 |
+
border-radius: 50%;
|
635 |
+
display: inline-block;
|
636 |
+
line-height: 47px;
|
637 |
+
margin-top: 20px;
|
638 |
+
}
|
639 |
+
.search-input-style {
|
640 |
+
background-position: 10px 12px;
|
641 |
+
background-repeat: no-repeat;
|
642 |
+
font-size: 16px;
|
643 |
+
margin-bottom: 12px;
|
644 |
+
}
|
645 |
+
#query-input {
|
646 |
+
width: 450px;
|
647 |
+
position: relative;
|
648 |
+
top: -3px;
|
649 |
+
}
|
650 |
+
#search-subject {
|
651 |
+
width: 190px;
|
652 |
+
padding: 2px 8px;
|
653 |
+
}
|
654 |
+
|
655 |
+
#filter-cat {
|
656 |
+
width: 400px;
|
657 |
+
padding: 2px 8px;
|
658 |
+
}
|
659 |
+
|
660 |
+
#event-toggle-table {
|
661 |
+
border-collapse: collapse;
|
662 |
+
width: 100%;
|
663 |
+
border: 1px solid #ddd;
|
664 |
+
font-size: 18px;
|
665 |
+
}
|
666 |
+
|
667 |
+
#event-toggle-table th, #event-toggle-table td {
|
668 |
+
text-align: left;
|
669 |
+
padding: 12px;
|
670 |
+
}
|
671 |
+
|
672 |
+
#event-toggle-table tr {
|
673 |
+
border-bottom: 1px solid #ddd;
|
674 |
+
}
|
675 |
+
|
676 |
+
#event-toggle-table tr.disabled {
|
677 |
+
opacity: 0.5;
|
678 |
+
}
|
679 |
+
|
680 |
+
#event-toggle-table tr.header, #event-toggle-table tr:hover {
|
681 |
+
background-color: #f1f1f1;
|
682 |
+
}
|
683 |
+
#tab-all {
|
684 |
+
background: #fff;
|
685 |
+
margin-top: 10px;
|
686 |
+
padding: 10px;
|
687 |
+
border: 1px solid #c3c4c7;
|
688 |
+
box-shadow: 0 1px 1px rgb(0 0 0 / 4%);
|
689 |
}
|
690 |
</style>
|
691 |
<?php
|
699 |
wp_enqueue_script(
|
700 |
'wsal-remodal-js',
|
701 |
WSAL_BASE_URL . 'js/remodal.min.js',
|
702 |
+
array( 'jquery-ui-tooltip' ),
|
703 |
'1.1.1',
|
704 |
true
|
705 |
);
|
706 |
+
|
707 |
+
// Darktooltip js.
|
708 |
+
wp_enqueue_script(
|
709 |
+
'darktooltip', // Identifier.
|
710 |
+
WSAL_BASE_URL . 'js/jquery.darktooltip.js', // Script location.
|
711 |
+
array( 'jquery' ), // Depends on jQuery.
|
712 |
+
'0.4.0', // Script version.
|
713 |
+
true
|
714 |
+
);
|
715 |
+
|
716 |
?>
|
717 |
<script type="text/javascript">
|
718 |
+
function filterEventTable() {
|
719 |
+
// Declare variables
|
720 |
+
var input, filter, table, tr, td, i, txtValue;
|
721 |
+
input = document.getElementById("query-input");
|
722 |
+
filter = input.value.toUpperCase();
|
723 |
+
table = document.getElementById("event-toggle-table");
|
724 |
+
tr = table.getElementsByTagName("tr");
|
725 |
+
|
726 |
+
var e = document.getElementById("search-subject");
|
727 |
+
var strSearch = e.options[e.selectedIndex].value;
|
728 |
+
|
729 |
+
// Loop through all table rows, and hide those who don't match the search query
|
730 |
+
for (i = 0; i < tr.length; i++) {
|
731 |
+
if ( strSearch == 'code' ) {
|
732 |
+
td = tr[i].getElementsByTagName("td")[0];
|
733 |
+
} else if ( strSearch == 'severity' ) {
|
734 |
+
td = tr[i].getElementsByTagName("td")[1];
|
735 |
+
} else if ( strSearch == 'desc' ) {
|
736 |
+
td = tr[i].getElementsByTagName("td")[2];
|
737 |
+
}
|
738 |
+
if (td) {
|
739 |
+
txtValue = td.textContent || td.innerText;
|
740 |
+
if (txtValue.toUpperCase().indexOf(filter) > -1) {
|
741 |
+
tr[i].style.display = "";
|
742 |
+
} else {
|
743 |
+
tr[i].style.display = "none";
|
744 |
+
}
|
745 |
+
}
|
746 |
+
}
|
747 |
+
}
|
748 |
+
|
749 |
jQuery(document).ready(function(){
|
750 |
var scrollHeight = jQuery(document).scrollTop();
|
751 |
// tab handling code
|
768 |
}, 1);
|
769 |
});
|
770 |
// checkbox handling code
|
771 |
+
jQuery('#event-toggle-table thead>tr>th>:checkbox').change(function(){
|
772 |
+
jQuery(this).parents('table:first').find('tbody>tr:visible>th>:checkbox').attr('checked', this.checked);
|
773 |
});
|
774 |
+
jQuery('#event-toggle-table tr checkbox').change(function(){
|
775 |
var allchecked = jQuery(this).parents('tbody:first').find('th>:checkbox:not(:checked)').length === 0;
|
776 |
+
jQuery(this).parents('table:first').find('thead>tr:visible>th:first>:checkbox:first').attr('checked', allchecked);
|
777 |
});
|
778 |
|
779 |
var hashlink = jQuery('#wsal-tabs>a[href="' + location.hash + '"]');
|
789 |
jQuery('#wsal-tabs>a:first').click();
|
790 |
jQuery('.wsal-sub-tabs>a:first').click();
|
791 |
}
|
792 |
+
|
793 |
+
// Add options to category select box.
|
794 |
+
var categories = [];
|
795 |
+
jQuery('[data-alert-cat]').each( function( index, value ) {
|
796 |
+
var title = jQuery( this ).attr( 'data-alert-cat');
|
797 |
+
var found = jQuery.inArray(title, categories);
|
798 |
+
if (found >= 0) {
|
799 |
+
// Nothing needed.
|
800 |
+
} else {
|
801 |
+
categories.push( title );
|
802 |
+
}
|
803 |
+
});
|
804 |
+
jQuery( categories ).each( function( index, value ) {
|
805 |
+
jQuery('#filter-cat').append('<option value="'+ value +'">'+ value +'</option>');
|
806 |
+
});
|
807 |
+
|
808 |
+
// Display a specific category based on browser hash.
|
809 |
+
var hash = window.location.hash;
|
810 |
+
jQuery('ul'+hash+':first').show();
|
811 |
+
|
812 |
+
if (window.location.href.indexOf( '#cat-' ) > -1) {
|
813 |
+
var hash = window.location.hash.toUpperCase();
|
814 |
+
hash = hash.replace('#CAT-', '');
|
815 |
+
jQuery('[data-alert-cat]').each( function( index, value ) {
|
816 |
+
var title = jQuery( this ).attr( 'data-alert-cat').toUpperCase();
|
817 |
+
if ( title == hash ) {
|
818 |
+
jQuery( this ).css( 'display', '' );
|
819 |
+
} else {
|
820 |
+
jQuery( this ).css( 'display', 'none' );
|
821 |
+
}
|
822 |
+
});
|
823 |
+
}
|
824 |
+
|
825 |
+
// Filter items based on category.
|
826 |
+
jQuery('#filter-cat').on('change', function() {
|
827 |
+
var filter = jQuery( "#filter-cat option:selected" ).text().toUpperCase();
|
828 |
+
var val = jQuery("#filter-cat").val();
|
829 |
+
if ( 'all' == val ) {
|
830 |
+
jQuery( '#event-toggle-table tr' ).css( 'display', '' );
|
831 |
+
} else {
|
832 |
+
jQuery('[data-alert-cat]').each( function( index, value ) {
|
833 |
+
var title = jQuery( this ).attr( 'data-alert-cat').toUpperCase();
|
834 |
+
if ( title == filter ) {
|
835 |
+
jQuery( this ).css( 'display', '' );
|
836 |
+
} else {
|
837 |
+
jQuery( this ).css( 'display', 'none' );
|
838 |
+
}
|
839 |
+
});
|
840 |
+
}
|
841 |
+
});
|
842 |
+
|
843 |
+
// Lovely tooltop.s
|
844 |
+
jQuery( '#event-toggle-table tr' ).darkTooltip( {
|
845 |
+
animation: 'fadeIn',
|
846 |
+
gravity: 'north',
|
847 |
+
size: 'large',
|
848 |
+
} );
|
849 |
});
|
850 |
|
851 |
if (typeof toggle_modal !== 'undefined') {
|
classes/Views/addons/html-view.php
CHANGED
@@ -13,7 +13,9 @@ $utm_params = array(
|
|
13 |
'utm_source' => 'plugin',
|
14 |
'utm_medium' => 'referral',
|
15 |
'utm_campaign' => 'WSAL',
|
|
|
16 |
);
|
|
|
17 |
switch ( $this->hook_suffix ) {
|
18 |
case 'wp-activity-log_page_wsal-loginusers':
|
19 |
$utm_params['utm_content'] = 'sessions';
|
13 |
'utm_source' => 'plugin',
|
14 |
'utm_medium' => 'referral',
|
15 |
'utm_campaign' => 'WSAL',
|
16 |
+
'utm_content' => 'sessions',
|
17 |
);
|
18 |
+
|
19 |
switch ( $this->hook_suffix ) {
|
20 |
case 'wp-activity-log_page_wsal-loginusers':
|
21 |
$utm_params['utm_content'] = 'sessions';
|
css/admin-notices.css
CHANGED
@@ -67,6 +67,11 @@ div.wsal_notice__wrapper p {
|
|
67 |
bottom: 3px;
|
68 |
}
|
69 |
|
|
|
|
|
|
|
|
|
|
|
70 |
/* Addon Notices */
|
71 |
.notice-addon-available {
|
72 |
display: flex;
|
@@ -90,7 +95,13 @@ div.wsal_notice__wrapper p {
|
|
90 |
margin-top: 5px;
|
91 |
}
|
92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
.updated.wsal_notice {
|
94 |
border: 3px solid #049443;
|
95 |
overflow: hidden;
|
96 |
-
}
|
67 |
bottom: 3px;
|
68 |
}
|
69 |
|
70 |
+
.wsal_notice__btns a.start-trial-link {
|
71 |
+
position: absolute;
|
72 |
+
right: 14px;
|
73 |
+
bottom: 20px;
|
74 |
+
}
|
75 |
/* Addon Notices */
|
76 |
.notice-addon-available {
|
77 |
display: flex;
|
95 |
margin-top: 5px;
|
96 |
}
|
97 |
|
98 |
+
.wsal_notice__btns a.wsal_notice__btn.notice-cta {
|
99 |
+
padding: 2px 25px;
|
100 |
+
font-weight: bold;
|
101 |
+
font-size: 16px;
|
102 |
+
}
|
103 |
+
|
104 |
.updated.wsal_notice {
|
105 |
border: 3px solid #049443;
|
106 |
overflow: hidden;
|
107 |
+
}
|
defaults.php
CHANGED
@@ -1912,6 +1912,22 @@ function wsaldefaults_wsal_init() {
|
|
1912 |
'user',
|
1913 |
'modified'
|
1914 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1915 |
|
1916 |
array(
|
1917 |
4025,
|
@@ -2056,6 +2072,32 @@ function wsaldefaults_wsal_init() {
|
|
2056 |
'user',
|
2057 |
'created'
|
2058 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2059 |
),
|
2060 |
),
|
2061 |
|
@@ -2166,7 +2208,7 @@ function wsaldefaults_wsal_init() {
|
|
2166 |
__( 'Install location', 'wp-security-audit-log' ) => '%install_directory%',
|
2167 |
],
|
2168 |
[],
|
2169 |
-
'
|
2170 |
'enabled'
|
2171 |
),
|
2172 |
|
@@ -2179,7 +2221,7 @@ function wsaldefaults_wsal_init() {
|
|
2179 |
__( 'Install location', 'wp-security-audit-log' ) => '%install_directory%',
|
2180 |
],
|
2181 |
[],
|
2182 |
-
'
|
2183 |
'enabled'
|
2184 |
),
|
2185 |
|
@@ -2918,7 +2960,7 @@ function wsaldefaults_wsal_init() {
|
|
2918 |
6017,
|
2919 |
WSAL_INFORMATIONAL,
|
2920 |
__( 'Modified the list of keywords for comments moderation', 'wp-security-audit-log' ),
|
2921 |
-
__( 'Modified the list of keywords for comments
|
2922 |
[],
|
2923 |
[],
|
2924 |
'system-setting',
|
@@ -3057,6 +3099,19 @@ function wsaldefaults_wsal_init() {
|
|
3057 |
'system-setting',
|
3058 |
'modified'
|
3059 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3060 |
),
|
3061 |
|
3062 |
__( 'Database Events', 'wp-security-audit-log' ) => array(
|
1912 |
'user',
|
1913 |
'modified'
|
1914 |
),
|
1915 |
+
array(
|
1916 |
+
4021,
|
1917 |
+
WSAL_MEDIUM,
|
1918 |
+
__( 'User\'s website URL was modified', 'wp-security-audit-log' ),
|
1919 |
+
__( 'Changed the website URL of the user %TargetUsername% to %new_url%.', 'wp-security-audit-log' ),
|
1920 |
+
[
|
1921 |
+
__( 'Role', 'wp-security-audit-log' ) => '%Roles%',
|
1922 |
+
__( 'First name', 'wp-security-audit-log' ) => '%FirstName%',
|
1923 |
+
__( 'Last name', 'wp-security-audit-log' ) => '%LastName%',
|
1924 |
+
__( 'Previous website URL', 'wp-security-audit-log' ) => '%old_url%',
|
1925 |
+
|
1926 |
+
],
|
1927 |
+
wsaldefaults_build_links( [ 'EditUserLink' ] ),
|
1928 |
+
'user',
|
1929 |
+
'modified'
|
1930 |
+
),
|
1931 |
|
1932 |
array(
|
1933 |
4025,
|
2072 |
'user',
|
2073 |
'created'
|
2074 |
),
|
2075 |
+
array(
|
2076 |
+
4013,
|
2077 |
+
WSAL_HIGH,
|
2078 |
+
__( 'Network user has been activated', 'wp-security-audit-log' ),
|
2079 |
+
__( 'User %NewUserData->Username% has been activated.', 'wp-security-audit-log' ),
|
2080 |
+
[
|
2081 |
+
__( 'Role', 'wp-security-audit-log' ) => '%NewUserData->Roles%',
|
2082 |
+
__( 'First name', 'wp-security-audit-log' ) => '%NewUserData->FirstName%',
|
2083 |
+
__( 'Last name', 'wp-security-audit-log' ) => '%NewUserData->LastName%'
|
2084 |
+
],
|
2085 |
+
wsaldefaults_build_links( [ 'EditUserLink' ] ),
|
2086 |
+
'user',
|
2087 |
+
'activated'
|
2088 |
+
),
|
2089 |
+
array(
|
2090 |
+
4024,
|
2091 |
+
WSAL_LOW,
|
2092 |
+
__( 'Network user has signed-up', 'wp-security-audit-log' ),
|
2093 |
+
__( 'User with the email address %email_address% has signed up to the network.', 'wp-security-audit-log' ),
|
2094 |
+
[
|
2095 |
+
__( 'Username', 'wp-security-audit-log' ) => '%username%'
|
2096 |
+
],
|
2097 |
+
[],
|
2098 |
+
'user',
|
2099 |
+
'created'
|
2100 |
+
),
|
2101 |
),
|
2102 |
),
|
2103 |
|
2208 |
__( 'Install location', 'wp-security-audit-log' ) => '%install_directory%',
|
2209 |
],
|
2210 |
[],
|
2211 |
+
'plugin',
|
2212 |
'enabled'
|
2213 |
),
|
2214 |
|
2221 |
__( 'Install location', 'wp-security-audit-log' ) => '%install_directory%',
|
2222 |
],
|
2223 |
[],
|
2224 |
+
'theme',
|
2225 |
'enabled'
|
2226 |
),
|
2227 |
|
2960 |
6017,
|
2961 |
WSAL_INFORMATIONAL,
|
2962 |
__( 'Modified the list of keywords for comments moderation', 'wp-security-audit-log' ),
|
2963 |
+
__( 'Modified the list of keywords for comments moderation in WordPress.', 'wp-security-audit-log' ),
|
2964 |
[],
|
2965 |
[],
|
2966 |
'system-setting',
|
3099 |
'system-setting',
|
3100 |
'modified'
|
3101 |
),
|
3102 |
+
|
3103 |
+
array(
|
3104 |
+
6059,
|
3105 |
+
WSAL_HIGH,
|
3106 |
+
__( 'Option Site Title changed', 'wp-security-audit-log' ),
|
3107 |
+
__( 'Changed the <strong>Site Title</strong> to %new_value%.', 'wp-security-audit-log' ),
|
3108 |
+
[
|
3109 |
+
__( 'Previous setting', 'wp-security-audit-log' ) => '%previous_value%'
|
3110 |
+
],
|
3111 |
+
[],
|
3112 |
+
'system-setting',
|
3113 |
+
'modified'
|
3114 |
+
),
|
3115 |
),
|
3116 |
|
3117 |
__( 'Database Events', 'wp-security-audit-log' ) => array(
|
img/addons/wfcm.png
ADDED
Binary file
|
img/help/c4wp.jpg
ADDED
Binary file
|
img/help/password-policy-manager.jpg
CHANGED
Binary file
|
img/help/wp-2fa-img.jpg
CHANGED
Binary file
|
js/auditlog.js
CHANGED
@@ -576,4 +576,11 @@ jQuery( document ).ready( function() {
|
|
576 |
});
|
577 |
});
|
578 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
579 |
});
|
576 |
});
|
577 |
});
|
578 |
|
579 |
+
jQuery( '[data-shortened-text]' ).on( 'click', function( event ) {
|
580 |
+
var elm = jQuery( this );
|
581 |
+
var full_text = elm.data( 'shortened-text' );
|
582 |
+
elm.parent().find( 'span' ).text( full_text );
|
583 |
+
elm.remove();
|
584 |
+
} );
|
585 |
+
|
586 |
});
|
js/common.js
CHANGED
@@ -54,59 +54,75 @@ jQuery( document ).ready( function() {
|
|
54 |
jQuery( 'head' ).append( '<style>.wp-submenu .dashicons-external:before{vertical-align: bottom;}</style>' );
|
55 |
|
56 |
// Add on installer
|
57 |
-
jQuery(".install-addon").
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
// Disable other buttons whilst the process is happening.
|
59 |
jQuery(".install-addon").not(this).prop('disabled', true);
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
var PluginSlug =
|
64 |
-
var nonceValue =
|
65 |
-
var PluginDownloadUrl =
|
66 |
-
var RedirectToTab =
|
67 |
-
|
68 |
-
|
69 |
jQuery.ajax({
|
70 |
type: 'POST',
|
71 |
-
dataType
|
72 |
url: wsalCommonData.ajaxURL,
|
73 |
-
data
|
74 |
action: "wsal_run_addon_install",
|
75 |
plugin_slug: PluginSlug,
|
76 |
plugin_url: PluginDownloadUrl,
|
77 |
_wpnonce: nonceValue
|
78 |
},
|
79 |
-
complete: function(
|
80 |
var do_redirect = true;
|
81 |
-
if(
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
} else if (
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
} else if (
|
90 |
-
|
91 |
-
|
92 |
do_redirect = false;
|
93 |
-
} else if (
|
94 |
-
|
95 |
-
|
96 |
}
|
97 |
|
98 |
-
if (do_redirect
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
}
|
106 |
-
|
107 |
},
|
108 |
});
|
109 |
-
}
|
110 |
|
111 |
// Totally disabling the button.
|
112 |
jQuery(".install-addon.disabled").prop('disabled', true);
|
54 |
jQuery( 'head' ).append( '<style>.wp-submenu .dashicons-external:before{vertical-align: bottom;}</style>' );
|
55 |
|
56 |
// Add on installer
|
57 |
+
jQuery(".install-addon").on( 'click', function( e ) {
|
58 |
+
return wsalCommonData.install_addon( e, this );
|
59 |
+
});
|
60 |
+
|
61 |
+
wsalCommonData.install_addon = function( event, button_elm ) {
|
62 |
+
var currentButton = jQuery( button_elm );
|
63 |
+
if (currentButton.hasClass('disabled')) {
|
64 |
+
return;
|
65 |
+
}
|
66 |
+
|
67 |
// Disable other buttons whilst the process is happening.
|
68 |
jQuery(".install-addon").not(this).prop('disabled', true);
|
69 |
|
70 |
+
currentButton.html(wsalCommonData.installing);
|
71 |
+
|
72 |
+
var PluginSlug = currentButton.attr('data-plugin-slug');
|
73 |
+
var nonceValue = currentButton.attr('data-nonce');
|
74 |
+
var PluginDownloadUrl = currentButton.attr('data-plugin-download-url');
|
75 |
+
var RedirectToTab = currentButton.attr('data-plugin-event-tab-id');
|
76 |
+
currentButton.next('.spinner').show('200');
|
77 |
+
event.preventDefault();
|
78 |
jQuery.ajax({
|
79 |
type: 'POST',
|
80 |
+
dataType: "json",
|
81 |
url: wsalCommonData.ajaxURL,
|
82 |
+
data: {
|
83 |
action: "wsal_run_addon_install",
|
84 |
plugin_slug: PluginSlug,
|
85 |
plugin_url: PluginDownloadUrl,
|
86 |
_wpnonce: nonceValue
|
87 |
},
|
88 |
+
complete: function (data) {
|
89 |
var do_redirect = true;
|
90 |
+
if (data.responseText == '"already_installed"') {
|
91 |
+
currentButton.html(wsalCommonData.already_installed).addClass('disabled');
|
92 |
+
currentButton.next('.spinner').hide('200');
|
93 |
+
currentButton.addClass('disabled');
|
94 |
+
} else if (data.responseText == '"activated"') {
|
95 |
+
currentButton.html(wsalCommonData.activated).addClass('disabled');
|
96 |
+
currentButton.next('.spinner').hide('200');
|
97 |
+
currentButton.addClass('disabled');
|
98 |
+
} else if (JSON.stringify(data.responseText).toLowerCase().indexOf('failed') >= 0) {
|
99 |
+
currentButton.html(wsalCommonData.failed).addClass('disabled');
|
100 |
+
currentButton.next('.spinner').hide('200');
|
101 |
do_redirect = false;
|
102 |
+
} else if (data.responseText == '"success"' || JSON.stringify(data.responseText).toLowerCase().indexOf('success') >= 0) {
|
103 |
+
currentButton.html(wsalCommonData.installed).addClass('disabled');
|
104 |
+
currentButton.next('.spinner').hide('200');
|
105 |
}
|
106 |
|
107 |
+
if ( do_redirect ) {
|
108 |
+
if ( typeof RedirectToTab !== 'undefined' ) {
|
109 |
+
setTimeout(function () {
|
110 |
+
window.location = "admin.php?page=wsal-togglealerts" + RedirectToTab;
|
111 |
+
jQuery('[href="' + RedirectToTab + '"]').trigger('click');
|
112 |
+
// Reload as tabs are not present on page.
|
113 |
+
window.location.reload();
|
114 |
+
}, 100);
|
115 |
+
} else {
|
116 |
+
currentButton.html( wsalCommonData.reloading_page );
|
117 |
+
setTimeout(function () {
|
118 |
+
window.location.reload();
|
119 |
+
}, 100);
|
120 |
+
}
|
121 |
}
|
122 |
+
jQuery(".install-addon").not(this).prop('disabled', false);
|
123 |
},
|
124 |
});
|
125 |
+
};
|
126 |
|
127 |
// Totally disabling the button.
|
128 |
jQuery(".install-addon.disabled").prop('disabled', true);
|
languages/index.php
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Nothing to see here.
|
4 |
+
*/
|
languages/wp-security-audit-log.pot
CHANGED
@@ -27,281 +27,281 @@ msgstr ""
|
|
27 |
msgid "Exclude custom field from the monitoring"
|
28 |
msgstr ""
|
29 |
|
30 |
-
#: classes/AlertFormatter.php:
|
31 |
msgid "unknown"
|
32 |
msgstr ""
|
33 |
|
34 |
-
#: classes/AlertFormatter.php:
|
35 |
msgid "Download the log file."
|
36 |
msgstr ""
|
37 |
|
38 |
-
#: classes/AlertFormatter.php:
|
39 |
msgid "published"
|
40 |
msgstr ""
|
41 |
|
42 |
-
#: classes/AlertManager.php:
|
43 |
#, php-format
|
44 |
msgid "Event with code %d has not be registered."
|
45 |
msgstr ""
|
46 |
|
47 |
-
#: classes/AlertManager.php:
|
48 |
#, php-format
|
49 |
msgid "Event %s already registered with WP Activity Log."
|
50 |
msgstr ""
|
51 |
|
52 |
-
#: classes/AlertManager.php:
|
53 |
msgid "You have custom events that are using the same ID or IDs which are already registered in the plugin, so they have been disabled."
|
54 |
msgstr ""
|
55 |
|
56 |
-
#: classes/AlertManager.php:
|
57 |
#, php-format
|
58 |
msgid "%4$s to help you solve this issue."
|
59 |
msgstr ""
|
60 |
|
61 |
-
#: classes/AlertManager.php:
|
62 |
msgid "ERROR:"
|
63 |
msgstr ""
|
64 |
|
65 |
-
#: classes/AlertManager.php:
|
66 |
msgid "Contact us"
|
67 |
msgstr ""
|
68 |
|
69 |
-
#: classes/AlertManager.php:
|
70 |
#: classes/AuditLogListView.php:306 classes/Views/Settings.php:1086
|
71 |
#: classes/WidgetManager.php:76 defaults.php:1706
|
72 |
msgid "User"
|
73 |
msgstr ""
|
74 |
|
75 |
-
#: classes/AlertManager.php:
|
76 |
-
#: classes/AuditLogGridView.php:
|
77 |
-
#: defaults.php:
|
78 |
msgid "System"
|
79 |
msgstr ""
|
80 |
|
81 |
-
#: classes/AlertManager.php:
|
82 |
-
#: classes/AuditLogListView.php:436 defaults.php:
|
83 |
msgid "Plugin"
|
84 |
msgstr ""
|
85 |
|
86 |
-
#: classes/AlertManager.php:
|
87 |
msgid "Database"
|
88 |
msgstr ""
|
89 |
|
90 |
-
#: classes/AlertManager.php:
|
91 |
msgid "Post"
|
92 |
msgstr ""
|
93 |
|
94 |
-
#: classes/AlertManager.php:
|
95 |
msgid "File"
|
96 |
msgstr ""
|
97 |
|
98 |
-
#: classes/AlertManager.php:
|
99 |
msgid "Tag"
|
100 |
msgstr ""
|
101 |
|
102 |
-
#: classes/AlertManager.php:
|
103 |
msgid "Comment"
|
104 |
msgstr ""
|
105 |
|
106 |
-
#: classes/AlertManager.php:
|
107 |
msgid "Setting"
|
108 |
msgstr ""
|
109 |
|
110 |
-
#: classes/AlertManager.php:
|
111 |
msgid "System Setting"
|
112 |
msgstr ""
|
113 |
|
114 |
-
#: classes/AlertManager.php:
|
115 |
msgid "MainWP Network"
|
116 |
msgstr ""
|
117 |
|
118 |
-
#: classes/AlertManager.php:
|
119 |
msgid "MainWP"
|
120 |
msgstr ""
|
121 |
|
122 |
-
#: classes/AlertManager.php:
|
123 |
msgid "Category"
|
124 |
msgstr ""
|
125 |
|
126 |
-
#: classes/AlertManager.php:
|
127 |
msgid "Custom Field"
|
128 |
msgstr ""
|
129 |
|
130 |
-
#: classes/AlertManager.php:
|
131 |
msgid "Widget"
|
132 |
msgstr ""
|
133 |
|
134 |
-
#: classes/AlertManager.php:
|
135 |
msgid "Menu"
|
136 |
msgstr ""
|
137 |
|
138 |
-
#: classes/AlertManager.php:
|
139 |
msgid "Theme"
|
140 |
msgstr ""
|
141 |
|
142 |
-
#: classes/AlertManager.php:
|
143 |
msgid "Activity log"
|
144 |
msgstr ""
|
145 |
|
146 |
-
#: classes/AlertManager.php:
|
147 |
msgid "WP Activity Log"
|
148 |
msgstr ""
|
149 |
|
150 |
-
#: classes/AlertManager.php:
|
151 |
msgid "Multisite Network"
|
152 |
msgstr ""
|
153 |
|
154 |
-
#: classes/AlertManager.php:
|
155 |
msgid "IP Address"
|
156 |
msgstr ""
|
157 |
|
158 |
-
#: classes/AlertManager.php:
|
159 |
msgid "unknown object"
|
160 |
msgstr ""
|
161 |
|
162 |
-
#: classes/AlertManager.php:
|
163 |
msgid "Login"
|
164 |
msgstr ""
|
165 |
|
166 |
-
#: classes/AlertManager.php:
|
167 |
msgid "Logout"
|
168 |
msgstr ""
|
169 |
|
170 |
-
#: classes/AlertManager.php:
|
171 |
msgid "Installed"
|
172 |
msgstr ""
|
173 |
|
174 |
-
#: classes/AlertManager.php:
|
175 |
msgid "Activated"
|
176 |
msgstr ""
|
177 |
|
178 |
-
#: classes/AlertManager.php:
|
179 |
msgid "Deactivated"
|
180 |
msgstr ""
|
181 |
|
182 |
-
#: classes/AlertManager.php:
|
183 |
msgid "Uninstalled"
|
184 |
msgstr ""
|
185 |
|
186 |
-
#: classes/AlertManager.php:
|
187 |
msgid "Updated"
|
188 |
msgstr ""
|
189 |
|
190 |
-
#: classes/AlertManager.php:
|
191 |
msgid "Created"
|
192 |
msgstr ""
|
193 |
|
194 |
-
#: classes/AlertManager.php:
|
195 |
msgid "Modified"
|
196 |
msgstr ""
|
197 |
|
198 |
-
#: classes/AlertManager.php:
|
199 |
msgid "Deleted"
|
200 |
msgstr ""
|
201 |
|
202 |
-
#: classes/AlertManager.php:
|
203 |
msgid "Published"
|
204 |
msgstr ""
|
205 |
|
206 |
-
#: classes/AlertManager.php:
|
207 |
msgid "Approved"
|
208 |
msgstr ""
|
209 |
|
210 |
-
#: classes/AlertManager.php:
|
211 |
msgid "Unapproved"
|
212 |
msgstr ""
|
213 |
|
214 |
-
#: classes/AlertManager.php:
|
215 |
msgid "Enabled"
|
216 |
msgstr ""
|
217 |
|
218 |
-
#: classes/AlertManager.php:
|
219 |
msgid "Disabled"
|
220 |
msgstr ""
|
221 |
|
222 |
-
#: classes/AlertManager.php:
|
223 |
msgid "Added"
|
224 |
msgstr ""
|
225 |
|
226 |
-
#: classes/AlertManager.php:
|
227 |
msgid "Failed Login"
|
228 |
msgstr ""
|
229 |
|
230 |
-
#: classes/AlertManager.php:
|
231 |
msgid "Blocked"
|
232 |
msgstr ""
|
233 |
|
234 |
-
#: classes/AlertManager.php:
|
235 |
msgid "Uploaded"
|
236 |
msgstr ""
|
237 |
|
238 |
-
#: classes/AlertManager.php:
|
239 |
msgid "Restored"
|
240 |
msgstr ""
|
241 |
|
242 |
-
#: classes/AlertManager.php:
|
243 |
msgid "Opened"
|
244 |
msgstr ""
|
245 |
|
246 |
-
#: classes/AlertManager.php:
|
247 |
msgid "Viewed"
|
248 |
msgstr ""
|
249 |
|
250 |
-
#: classes/AlertManager.php:
|
251 |
msgid "Started"
|
252 |
msgstr ""
|
253 |
|
254 |
-
#: classes/AlertManager.php:
|
255 |
msgid "Stopped"
|
256 |
msgstr ""
|
257 |
|
258 |
-
#: classes/AlertManager.php:
|
259 |
msgid "Removed"
|
260 |
msgstr ""
|
261 |
|
262 |
-
#: classes/AlertManager.php:
|
263 |
msgid "Unblocked"
|
264 |
msgstr ""
|
265 |
|
266 |
-
#: classes/AlertManager.php:
|
267 |
msgid "Renamed"
|
268 |
msgstr ""
|
269 |
|
270 |
-
#: classes/AlertManager.php:
|
271 |
msgid "Duplicated"
|
272 |
msgstr ""
|
273 |
|
274 |
-
#: classes/AlertManager.php:
|
275 |
msgid "Submitted"
|
276 |
msgstr ""
|
277 |
|
278 |
-
#: classes/AlertManager.php:
|
279 |
msgid "Revoked"
|
280 |
msgstr ""
|
281 |
|
282 |
-
#: classes/AlertManager.php:
|
283 |
msgid "unknown type"
|
284 |
msgstr ""
|
285 |
|
286 |
-
#: classes/AlertManager.php:
|
287 |
-
#:
|
288 |
msgid "Pages"
|
289 |
msgstr ""
|
290 |
|
291 |
-
#: classes/AlertManager.php:
|
292 |
-
#:
|
293 |
msgid "Custom Post Types"
|
294 |
msgstr ""
|
295 |
|
296 |
-
#: classes/AlertManager.php:
|
297 |
msgid "System Activity"
|
298 |
msgstr ""
|
299 |
|
300 |
-
#: classes/AlertManager.php:
|
301 |
msgid "Unknown error code."
|
302 |
msgstr ""
|
303 |
|
304 |
-
#: classes/AlertManager.php:
|
305 |
msgid "Unknown Site"
|
306 |
msgstr ""
|
307 |
|
@@ -330,7 +330,7 @@ msgid "— End of Activity Log —"
|
|
330 |
msgstr ""
|
331 |
|
332 |
#: classes/AuditLogGridView.php:211 classes/AuditLogListView.php:209
|
333 |
-
#: classes/Views/AuditLog.php:
|
334 |
msgid "All Sites"
|
335 |
msgstr ""
|
336 |
|
@@ -342,7 +342,8 @@ msgstr ""
|
|
342 |
|
343 |
#: classes/AuditLogGridView.php:272 classes/AuditLogGridView.php:298
|
344 |
#: classes/AuditLogListView.php:270 classes/AuditLogListView.php:300
|
345 |
-
#: classes/Views/Settings.php:1082 classes/Views/ToggleAlerts.php:
|
|
|
346 |
msgid "Severity"
|
347 |
msgstr ""
|
348 |
|
@@ -373,57 +374,57 @@ msgid "Message:"
|
|
373 |
msgstr ""
|
374 |
|
375 |
#: classes/AuditLogGridView.php:401 classes/AuditLogGridView.php:405
|
376 |
-
#: classes/AuditLogListView.php:413 classes/Utilities/UserUtils.php:
|
377 |
msgid "Unknown"
|
378 |
msgstr ""
|
379 |
|
380 |
-
#: classes/AuditLogGridView.php:
|
381 |
-
#: defaults.php:
|
382 |
msgid "Plugins"
|
383 |
msgstr ""
|
384 |
|
385 |
-
#: classes/AuditLogGridView.php:
|
386 |
msgid "Unregistered user"
|
387 |
msgstr ""
|
388 |
|
389 |
-
#: classes/AuditLogGridView.php:
|
390 |
#: classes/AuditLogListView.php:473 classes/AuditLogListView.php:486
|
391 |
msgid "Show me all activity originating from this IP Address"
|
392 |
msgstr ""
|
393 |
|
394 |
-
#: classes/AuditLogGridView.php:
|
395 |
msgid "Date:"
|
396 |
msgstr ""
|
397 |
|
398 |
-
#: classes/AuditLogGridView.php:
|
399 |
msgid "Time:"
|
400 |
msgstr ""
|
401 |
|
402 |
-
#: classes/AuditLogGridView.php:
|
403 |
msgid "User:"
|
404 |
msgstr ""
|
405 |
|
406 |
-
#: classes/AuditLogGridView.php:
|
407 |
msgid "IP:"
|
408 |
msgstr ""
|
409 |
|
410 |
-
#: classes/AuditLogGridView.php:
|
411 |
msgid "Object:"
|
412 |
msgstr ""
|
413 |
|
414 |
-
#: classes/AuditLogGridView.php:
|
415 |
msgid "Event Type:"
|
416 |
msgstr ""
|
417 |
|
418 |
-
#: classes/AuditLogGridView.php:
|
419 |
msgid "View all details of this change"
|
420 |
msgstr ""
|
421 |
|
422 |
-
#: classes/AuditLogGridView.php:
|
423 |
msgid "Alert Data Inspector"
|
424 |
msgstr ""
|
425 |
|
426 |
-
#: classes/AuditLogGridView.php:
|
427 |
msgid "Select All"
|
428 |
msgstr ""
|
429 |
|
@@ -445,11 +446,11 @@ msgstr ""
|
|
445 |
msgid "Event Type"
|
446 |
msgstr ""
|
447 |
|
448 |
-
#: classes/AuditLogListView.php:382 classes/Models/Occurrence.php:
|
449 |
msgid "Alert message not found."
|
450 |
msgstr ""
|
451 |
|
452 |
-
#: classes/AuditLogListView.php:383 classes/Models/Occurrence.php:
|
453 |
msgid "Alert description not found."
|
454 |
msgstr ""
|
455 |
|
@@ -463,89 +464,85 @@ msgid "Code %1$d: %2$s"
|
|
463 |
msgstr ""
|
464 |
|
465 |
#: classes/ConstantManager.php:159 classes/ConstantManager.php:165
|
466 |
-
#: classes/Views/ToggleAlerts.php:
|
467 |
msgid "Critical"
|
468 |
msgstr ""
|
469 |
|
470 |
-
#: classes/ConstantManager.php:161 classes/Views/ToggleAlerts.php:
|
471 |
msgid "Warning"
|
472 |
msgstr ""
|
473 |
|
474 |
-
#: classes/ConstantManager.php:163 classes/Views/ToggleAlerts.php:
|
475 |
-
#: classes/Views/ToggleAlerts.php:
|
476 |
msgid "Notification"
|
477 |
msgstr ""
|
478 |
|
479 |
-
#: classes/ConstantManager.php:167 classes/Views/ToggleAlerts.php:
|
480 |
msgid "High"
|
481 |
msgstr ""
|
482 |
|
483 |
-
#: classes/ConstantManager.php:169 classes/Views/ToggleAlerts.php:
|
484 |
msgid "Medium"
|
485 |
msgstr ""
|
486 |
|
487 |
-
#: classes/ConstantManager.php:171 classes/Views/ToggleAlerts.php:
|
488 |
msgid "Low"
|
489 |
msgstr ""
|
490 |
|
491 |
-
#: classes/ConstantManager.php:173 classes/Views/ToggleAlerts.php:
|
492 |
msgid "Informational"
|
493 |
msgstr ""
|
494 |
|
495 |
-
#: classes/Models/Occurrence.php:
|
496 |
-
msgid "WFCM"
|
497 |
-
msgstr ""
|
498 |
-
|
499 |
-
#: classes/Models/Occurrence.php:231
|
500 |
#, php-format
|
501 |
msgid "This type of activity / change is no longer monitored. You can create your own custom event IDs to keep a log of such change. Read more about custom events %1$shere%2$s."
|
502 |
msgstr ""
|
503 |
|
504 |
-
#: classes/Sensors/Content.php:
|
505 |
msgid "Default template"
|
506 |
msgstr ""
|
507 |
|
508 |
-
#: classes/Sensors/Content.php:
|
509 |
msgid "Default"
|
510 |
msgstr ""
|
511 |
|
512 |
-
#: classes/Sensors/Content.php:
|
513 |
msgid "No previous image"
|
514 |
msgstr ""
|
515 |
|
516 |
-
#: classes/Sensors/Content.php:
|
517 |
msgid "No image"
|
518 |
msgstr ""
|
519 |
|
520 |
-
#: classes/Sensors/Content.php:
|
521 |
msgid "Password Protected"
|
522 |
msgstr ""
|
523 |
|
524 |
-
#: classes/Sensors/Content.php:
|
525 |
msgid "Private"
|
526 |
msgstr ""
|
527 |
|
528 |
-
#: classes/Sensors/Content.php:
|
529 |
msgid "Public"
|
530 |
msgstr ""
|
531 |
|
532 |
-
#: classes/Sensors/Content.php:
|
533 |
msgid "no tags"
|
534 |
msgstr ""
|
535 |
|
536 |
-
#: classes/Sensors/Multisite.php:
|
537 |
msgid "disabled"
|
538 |
msgstr ""
|
539 |
|
540 |
-
#: classes/Sensors/Multisite.php:
|
541 |
msgid "user accounts only"
|
542 |
msgstr ""
|
543 |
|
544 |
-
#: classes/Sensors/Multisite.php:
|
545 |
msgid "users can register new sites"
|
546 |
msgstr ""
|
547 |
|
548 |
-
#: classes/Sensors/Multisite.php:
|
549 |
msgid "sites & users can be registered"
|
550 |
msgstr ""
|
551 |
|
@@ -569,39 +566,39 @@ msgstr ""
|
|
569 |
msgid "This function is deprecated"
|
570 |
msgstr ""
|
571 |
|
572 |
-
#: classes/Settings.php:
|
573 |
msgid "Root directory of WordPress (excluding sub directories)"
|
574 |
msgstr ""
|
575 |
|
576 |
-
#: classes/Settings.php:
|
577 |
msgid "WP Admin directory (/wp-admin/)"
|
578 |
msgstr ""
|
579 |
|
580 |
-
#: classes/Settings.php:
|
581 |
msgid "WP Includes directory (/wp-includes/)"
|
582 |
msgstr ""
|
583 |
|
584 |
-
#: classes/Settings.php:
|
585 |
msgid "/wp-content/ directory (excluding plugins, themes & uploads directories)"
|
586 |
msgstr ""
|
587 |
|
588 |
-
#: classes/Settings.php:
|
589 |
msgid "Themes directory (/wp-content/themes/)"
|
590 |
msgstr ""
|
591 |
|
592 |
-
#: classes/Settings.php:
|
593 |
msgid "Plugins directory (/wp-content/plugins/)"
|
594 |
msgstr ""
|
595 |
|
596 |
-
#: classes/Settings.php:
|
597 |
msgid "Uploads directory (/wp-content/uploads/)"
|
598 |
msgstr ""
|
599 |
|
600 |
-
#: classes/Settings.php:
|
601 |
msgid "Uploads directory of all sub sites on this network (/wp-content/sites/*)"
|
602 |
msgstr ""
|
603 |
|
604 |
-
#: classes/Settings.php:
|
605 |
msgid "None provided"
|
606 |
msgstr ""
|
607 |
|
@@ -609,6 +606,14 @@ msgstr ""
|
|
609 |
msgid "Keep a record of when someone adds, modifies or deletes forms, entries and more in the Gravity Forms plugin."
|
610 |
msgstr ""
|
611 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
612 |
#: classes/Utilities/Emailer.php:54
|
613 |
#, php-format
|
614 |
msgid "WP Activity Log plugin disabled on %s"
|
@@ -628,83 +633,83 @@ msgid "WP Activity Log can keep a log of changes done on other plugins. Install
|
|
628 |
msgstr ""
|
629 |
|
630 |
#: classes/Utilities/PluginInstallAndActivate.php:101
|
631 |
-
#: classes/Views/SetupWizard.php:
|
632 |
msgid "Extension for "
|
633 |
msgstr ""
|
634 |
|
635 |
#: classes/Utilities/PluginInstallAndActivate.php:106
|
636 |
-
#: classes/Views/SetupWizard.php:
|
637 |
msgid "Extension installed, activate now?"
|
638 |
msgstr ""
|
639 |
|
640 |
#: classes/Utilities/PluginInstallAndActivate.php:108
|
641 |
-
#: classes/Views/SetupWizard.php:272 classes/Views/SetupWizard.php:
|
642 |
-
#: wp-security-audit-log.php:
|
643 |
msgid "Extension installed"
|
644 |
msgstr ""
|
645 |
|
646 |
#: classes/Utilities/PluginInstallAndActivate.php:110
|
647 |
-
#: classes/Views/SetupWizard.php:
|
648 |
msgid "Install Extension"
|
649 |
msgstr ""
|
650 |
|
651 |
-
#: classes/Utilities/PluginInstallerAction.php:
|
652 |
msgid "Tried to install a zip or slug that was not in the allowed list"
|
653 |
msgstr ""
|
654 |
|
655 |
-
#: classes/Utilities/UserUtils.php:
|
656 |
msgid "Username: "
|
657 |
msgstr ""
|
658 |
|
659 |
-
#: classes/Utilities/UserUtils.php:
|
660 |
msgid "First name: "
|
661 |
msgstr ""
|
662 |
|
663 |
-
#: classes/Utilities/UserUtils.php:
|
664 |
msgid "Last Name: "
|
665 |
msgstr ""
|
666 |
|
667 |
-
#: classes/Utilities/UserUtils.php:
|
668 |
msgid "Email: "
|
669 |
msgstr ""
|
670 |
|
671 |
-
#: classes/Utilities/UserUtils.php:
|
672 |
msgid "Nickname: "
|
673 |
msgstr ""
|
674 |
|
675 |
-
#: classes/ViewManager.php:
|
676 |
msgid "WP Activity Log requires Website File Changes Monitor 1.6.0. Please upgrade that plugin."
|
677 |
msgstr ""
|
678 |
|
679 |
-
#: classes/ViewManager.php:
|
680 |
msgid "Free Premium Trial"
|
681 |
msgstr ""
|
682 |
|
683 |
-
#: classes/Views/AuditLog.php:
|
684 |
msgid "Get email notifications about website changes, view logged-in users, do granular log searches, create detailed reports, and more."
|
685 |
msgstr ""
|
686 |
|
687 |
-
#: classes/Views/AuditLog.php:
|
688 |
msgid "Upgrade to premium today and get more out of your activity logs!"
|
689 |
msgstr ""
|
690 |
|
691 |
-
#: classes/Views/AuditLog.php:
|
692 |
msgid "Instant SMS & email alerts, search & filters, reports, users sessions management and much more!"
|
693 |
msgstr ""
|
694 |
|
695 |
-
#: classes/Views/AuditLog.php:
|
696 |
msgid "Upgrade to premium to get more out of your activity logs!"
|
697 |
msgstr ""
|
698 |
|
699 |
-
#: classes/Views/AuditLog.php:
|
700 |
msgid "See who logged in on your site in real-time, generate reports, get SMS & email alerts of critical changes and more!"
|
701 |
msgstr ""
|
702 |
|
703 |
-
#: classes/Views/AuditLog.php:
|
704 |
msgid "Unlock these and other powerful features with WP Activity Log Premium."
|
705 |
msgstr ""
|
706 |
|
707 |
-
#: classes/Views/AuditLog.php:
|
708 |
msgid "Learn more"
|
709 |
msgstr ""
|
710 |
|
@@ -744,106 +749,106 @@ msgstr ""
|
|
744 |
msgid "No, thank you"
|
745 |
msgstr ""
|
746 |
|
747 |
-
#: classes/Views/AuditLog.php:
|
748 |
msgid "We noticed you have"
|
749 |
msgstr ""
|
750 |
|
751 |
-
#: classes/Views/AuditLog.php:
|
752 |
msgid "installed."
|
753 |
msgstr ""
|
754 |
|
755 |
-
#: classes/Views/AuditLog.php:
|
756 |
msgid "Install extension"
|
757 |
msgstr ""
|
758 |
|
759 |
-
#: classes/Views/AuditLog.php:
|
760 |
msgid "Activity Log Viewer"
|
761 |
msgstr ""
|
762 |
|
763 |
-
#: classes/Views/AuditLog.php:
|
764 |
msgid "Log Viewer"
|
765 |
msgstr ""
|
766 |
|
767 |
-
#: classes/Views/AuditLog.php:
|
768 |
-
#: classes/Views/ToggleAlerts.php:
|
769 |
msgid "You do not have sufficient permissions to access this page."
|
770 |
msgstr ""
|
771 |
|
772 |
-
#: classes/Views/AuditLog.php:
|
773 |
msgid "Thank you for installing WP Activity Log. Do you want to run the wizard to configure the basic plugin settings?"
|
774 |
msgstr ""
|
775 |
|
776 |
-
#: classes/Views/AuditLog.php:
|
777 |
#: classes/Views/Settings.php:559 classes/Views/Settings.php:625
|
778 |
#: classes/Views/Settings.php:683 classes/Views/Settings.php:1118
|
779 |
-
#: classes/Views/Settings.php:1402 classes/Views/Settings.php:
|
780 |
-
#: classes/Views/Settings.php:
|
781 |
-
#: classes/Views/SetupWizard.php:
|
782 |
msgid "Yes"
|
783 |
msgstr ""
|
784 |
|
785 |
-
#: classes/Views/AuditLog.php:
|
786 |
#: classes/Views/Settings.php:564 classes/Views/Settings.php:655
|
787 |
#: classes/Views/Settings.php:693 classes/Views/Settings.php:1123
|
788 |
-
#: classes/Views/Settings.php:1409 classes/Views/Settings.php:
|
789 |
-
#: classes/Views/Settings.php:
|
790 |
-
#: classes/Views/SetupWizard.php:
|
791 |
msgid "No"
|
792 |
msgstr ""
|
793 |
|
794 |
-
#: classes/Views/AuditLog.php:
|
795 |
msgid "Please enter the number of alerts you would like to see on one page:"
|
796 |
msgstr ""
|
797 |
|
798 |
-
#: classes/Views/AuditLog.php:
|
799 |
msgid "No Results"
|
800 |
msgstr ""
|
801 |
|
802 |
-
#: classes/Views/AuditLog.php:
|
803 |
-
#: classes/Views/AuditLog.php:
|
804 |
-
#: classes/Views/AuditLog.php:
|
805 |
-
#: classes/Views/Settings.php:
|
806 |
msgid "Nonce verification failed."
|
807 |
msgstr ""
|
808 |
|
809 |
-
#: classes/Views/AuditLog.php:
|
810 |
msgid "No users found."
|
811 |
msgstr ""
|
812 |
|
813 |
-
#: classes/Views/AuditLog.php:
|
814 |
msgid "Freemius opt choice selected."
|
815 |
msgstr ""
|
816 |
|
817 |
-
#: classes/Views/AuditLog.php:
|
818 |
msgid "Freemius opt choice not found."
|
819 |
msgstr ""
|
820 |
|
821 |
-
#: classes/Views/AuditLog.php:
|
822 |
#, php-format
|
823 |
msgid "<br>An error occurred when trying to install and activate the plugin. Please try install it again from the %1$sevent settings%2$s page."
|
824 |
msgstr ""
|
825 |
|
826 |
-
#: classes/Views/AuditLog.php:
|
827 |
msgid "WordPress Activity Log"
|
828 |
msgstr ""
|
829 |
|
830 |
-
#: classes/Views/AuditLog.php:
|
831 |
msgid "When a user makes a change on your website the plugin will keep a record of that event here. Right now there is nothing because this is a new install."
|
832 |
msgstr ""
|
833 |
|
834 |
-
#: classes/Views/AuditLog.php:
|
835 |
msgid "Thank you for using WP Activity Log"
|
836 |
msgstr ""
|
837 |
|
838 |
-
#: classes/Views/AuditLog.php:
|
839 |
msgid "You do not have sufficient permissions to dismiss this notice."
|
840 |
msgstr ""
|
841 |
|
842 |
-
#: classes/Views/AuditLog.php:
|
843 |
msgid "Access Denied"
|
844 |
msgstr ""
|
845 |
|
846 |
-
#: classes/Views/AuditLog.php:
|
847 |
#, php-format
|
848 |
msgid "Install the activity log extension for %1$s for more detailed logging of changes done in %2$s."
|
849 |
msgstr ""
|
@@ -853,7 +858,7 @@ msgid "Notifications Extension"
|
|
853 |
msgstr ""
|
854 |
|
855 |
#: classes/Views/EmailNotifications.php:35
|
856 |
-
msgid "Notifications ⇪"
|
857 |
msgstr ""
|
858 |
|
859 |
#: classes/Views/EmailNotifications.php:49
|
@@ -1049,26 +1054,30 @@ msgid "Rate Plugin"
|
|
1049 |
msgstr ""
|
1050 |
|
1051 |
#: classes/Views/Help.php:282
|
1052 |
-
msgid "
|
1053 |
msgstr ""
|
1054 |
|
1055 |
#: classes/Views/Help.php:288
|
1056 |
-
msgid "
|
1057 |
msgstr ""
|
1058 |
|
1059 |
#: classes/Views/Help.php:294
|
1060 |
-
msgid "
|
1061 |
msgstr ""
|
1062 |
|
1063 |
#: classes/Views/Help.php:300
|
1064 |
-
msgid "
|
1065 |
msgstr ""
|
1066 |
|
1067 |
#: classes/Views/Help.php:306
|
|
|
|
|
|
|
|
|
1068 |
msgid "Our other WordPress plugins"
|
1069 |
msgstr ""
|
1070 |
|
1071 |
-
#: classes/Views/Help.php:
|
1072 |
msgid "LEARN MORE"
|
1073 |
msgstr ""
|
1074 |
|
@@ -1125,7 +1134,7 @@ msgid "Reports Extension"
|
|
1125 |
msgstr ""
|
1126 |
|
1127 |
#: classes/Views/Reports.php:35
|
1128 |
-
msgid "Reports ⇪"
|
1129 |
msgstr ""
|
1130 |
|
1131 |
#: classes/Views/Reports.php:49
|
@@ -1173,7 +1182,7 @@ msgid "Search Extension"
|
|
1173 |
msgstr ""
|
1174 |
|
1175 |
#: classes/Views/Search.php:35
|
1176 |
-
msgid "Search ⇪"
|
1177 |
msgstr ""
|
1178 |
|
1179 |
#: classes/Views/Search.php:49
|
@@ -1248,8 +1257,8 @@ msgstr ""
|
|
1248 |
msgid "Unknown settings tab."
|
1249 |
msgstr ""
|
1250 |
|
1251 |
-
#: classes/Views/Settings.php:224 classes/Views/Settings.php:
|
1252 |
-
#: classes/Views/Settings.php:
|
1253 |
msgid "Access Denied."
|
1254 |
msgstr ""
|
1255 |
|
@@ -1261,11 +1270,11 @@ msgstr ""
|
|
1261 |
msgid "Message sent successfully."
|
1262 |
msgstr ""
|
1263 |
|
1264 |
-
#: classes/Views/Settings.php:340 classes/Views/ToggleAlerts.php:
|
1265 |
msgid "Settings have been saved."
|
1266 |
msgstr ""
|
1267 |
|
1268 |
-
#: classes/Views/Settings.php:346 classes/Views/ToggleAlerts.php:
|
1269 |
msgid "Error: "
|
1270 |
msgstr ""
|
1271 |
|
@@ -1483,7 +1492,7 @@ msgstr ""
|
|
1483 |
#: classes/Views/Settings.php:834 classes/Views/Settings.php:1217
|
1484 |
#: classes/Views/Settings.php:1238 classes/Views/Settings.php:1259
|
1485 |
#: classes/Views/Settings.php:1281 classes/Views/Settings.php:1329
|
1486 |
-
#: classes/Views/Settings.php:
|
1487 |
msgid "Remove"
|
1488 |
msgstr ""
|
1489 |
|
@@ -1639,19 +1648,19 @@ msgstr ""
|
|
1639 |
msgid "Enable Events for WordPress Background Activity"
|
1640 |
msgstr ""
|
1641 |
|
1642 |
-
#: classes/Views/Settings.php:1172
|
1643 |
msgid "Website File Changes Monitor"
|
1644 |
msgstr ""
|
1645 |
|
1646 |
-
#: classes/Views/Settings.php:1173
|
1647 |
msgid "To keep a log of file changes please install Website File Changes Monitor, a plugin which is also developed by us."
|
1648 |
msgstr ""
|
1649 |
|
1650 |
-
#: classes/Views/Settings.php:1174
|
1651 |
msgid "Install plugin now"
|
1652 |
msgstr ""
|
1653 |
|
1654 |
-
#: classes/Views/Settings.php:1174
|
1655 |
msgid "Learn More"
|
1656 |
msgstr ""
|
1657 |
|
@@ -1755,119 +1764,119 @@ msgstr ""
|
|
1755 |
msgid "Enable MainWP Child Site Stealth Mode"
|
1756 |
msgstr ""
|
1757 |
|
1758 |
-
#: classes/Views/Settings.php:
|
1759 |
msgid "Admin blocking plugins support"
|
1760 |
msgstr ""
|
1761 |
|
1762 |
-
#: classes/Views/Settings.php:
|
1763 |
msgid "Enable early plugin loading on sites that use admin blocking plugins"
|
1764 |
msgstr ""
|
1765 |
|
1766 |
-
#: classes/Views/Settings.php:
|
1767 |
msgid "Do you want to delete the plugin data from the database upon uninstall?"
|
1768 |
msgstr ""
|
1769 |
|
1770 |
-
#: classes/Views/Settings.php:
|
1771 |
msgid "The plugin saves the activity log data and settings in the WordPress database. By default upon uninstalling the plugin the data is kept in the database so if it is installed again, you can still access the data. If the data is deleted it is not possible to recover it so you won't be able to access it again even when you reinstall the plugin."
|
1772 |
msgstr ""
|
1773 |
|
1774 |
-
#: classes/Views/Settings.php:
|
1775 |
msgid "Remove Data on Uninstall"
|
1776 |
msgstr ""
|
1777 |
|
1778 |
-
#: classes/Views/Settings.php:
|
1779 |
msgid "Are you sure you want to reset all the plugin settings to default? This action cannot be undone."
|
1780 |
msgstr ""
|
1781 |
|
1782 |
-
#: classes/Views/Settings.php:
|
1783 |
msgid "Are you sure you want to purge all the activity log data?"
|
1784 |
msgstr ""
|
1785 |
|
1786 |
-
#: classes/Views/Settings.php:
|
1787 |
msgid "MainWP Child plugin is not active on this website."
|
1788 |
msgstr ""
|
1789 |
|
1790 |
-
#: classes/Views/Settings.php:
|
1791 |
msgid "The specified value is not a valid URL!"
|
1792 |
msgstr ""
|
1793 |
|
1794 |
-
#: classes/Views/Settings.php:
|
1795 |
msgid "The specified value is not a valid post type!"
|
1796 |
msgstr ""
|
1797 |
|
1798 |
-
#: classes/Views/Settings.php:
|
1799 |
msgid "The specified value is not a valid IP address!"
|
1800 |
msgstr ""
|
1801 |
|
1802 |
-
#: classes/Views/Settings.php:
|
1803 |
msgid "The specified value is not a user nor a role!"
|
1804 |
msgstr ""
|
1805 |
|
1806 |
-
#: classes/Views/Settings.php:
|
1807 |
msgid "Filename cannot be added because it contains invalid characters."
|
1808 |
msgstr ""
|
1809 |
|
1810 |
-
#: classes/Views/Settings.php:
|
1811 |
msgid "File extension cannot be added because it contains invalid characters."
|
1812 |
msgstr ""
|
1813 |
|
1814 |
-
#: classes/Views/Settings.php:
|
1815 |
msgid "Directory cannot be added because it contains invalid characters."
|
1816 |
msgstr ""
|
1817 |
|
1818 |
-
#: classes/Views/Settings.php:
|
1819 |
msgid "Please save any changes before switching tabs."
|
1820 |
msgstr ""
|
1821 |
|
1822 |
-
#: classes/Views/Settings.php:
|
1823 |
msgid "Nonce Verification Failed."
|
1824 |
msgstr ""
|
1825 |
|
1826 |
-
#: classes/Views/Settings.php:
|
1827 |
msgid "Plugin settings have been reset."
|
1828 |
msgstr ""
|
1829 |
|
1830 |
-
#: classes/Views/Settings.php:
|
1831 |
msgid "Tables has been reset."
|
1832 |
msgstr ""
|
1833 |
|
1834 |
-
#: classes/Views/Settings.php:
|
1835 |
msgid "Reset query failed."
|
1836 |
msgstr ""
|
1837 |
|
1838 |
-
#: classes/Views/Settings.php:
|
1839 |
msgid "Activity log retention"
|
1840 |
msgstr ""
|
1841 |
|
1842 |
-
#: classes/Views/Settings.php:
|
1843 |
msgid "Keep all data"
|
1844 |
msgstr ""
|
1845 |
|
1846 |
-
#: classes/Views/Settings.php:
|
1847 |
msgid "Days"
|
1848 |
msgstr ""
|
1849 |
|
1850 |
-
#: classes/Views/Settings.php:
|
1851 |
msgid "Months"
|
1852 |
msgstr ""
|
1853 |
|
1854 |
-
#: classes/Views/Settings.php:
|
1855 |
msgid "Years"
|
1856 |
msgstr ""
|
1857 |
|
1858 |
-
#: classes/Views/Settings.php:
|
1859 |
msgid "Delete events older than"
|
1860 |
msgstr ""
|
1861 |
|
1862 |
-
#: classes/Views/Settings.php:
|
1863 |
msgid "The next scheduled purging of activity log data that is older than "
|
1864 |
msgstr ""
|
1865 |
|
1866 |
-
#: classes/Views/Settings.php:
|
1867 |
msgid "You can run the purging process now by clicking the button below."
|
1868 |
msgstr ""
|
1869 |
|
1870 |
-
#: classes/Views/Settings.php:
|
1871 |
msgid "Purge Old Data"
|
1872 |
msgstr ""
|
1873 |
|
@@ -1891,8 +1900,8 @@ msgstr ""
|
|
1891 |
msgid "Log Retention"
|
1892 |
msgstr ""
|
1893 |
|
1894 |
-
#: classes/Views/SetupWizard.php:202 classes/Views/SetupWizard.php:
|
1895 |
-
#: classes/Views/SetupWizard.php:
|
1896 |
msgid "Finish"
|
1897 |
msgstr ""
|
1898 |
|
@@ -1908,156 +1917,160 @@ msgstr ""
|
|
1908 |
msgid "Specified value in not an IP address."
|
1909 |
msgstr ""
|
1910 |
|
1911 |
-
#: classes/Views/SetupWizard.php:270 wp-security-audit-log.php:
|
1912 |
msgid "Installing, please wait"
|
1913 |
msgstr ""
|
1914 |
|
1915 |
-
#: classes/Views/SetupWizard.php:271 wp-security-audit-log.php:
|
1916 |
msgid "Already installed"
|
1917 |
msgstr ""
|
1918 |
|
1919 |
-
#: classes/Views/SetupWizard.php:273 wp-security-audit-log.php:
|
1920 |
msgid "Extension activated"
|
1921 |
msgstr ""
|
1922 |
|
1923 |
-
#: classes/Views/SetupWizard.php:274 wp-security-audit-log.php:
|
1924 |
msgid "Install failed"
|
1925 |
msgstr ""
|
1926 |
|
1927 |
-
#: classes/Views/SetupWizard.php:
|
|
|
|
|
|
|
|
|
1928 |
msgid "WP Activity Log › Setup Wizard"
|
1929 |
msgstr ""
|
1930 |
|
1931 |
-
#: classes/Views/SetupWizard.php:
|
1932 |
msgid "Close Wizard"
|
1933 |
msgstr ""
|
1934 |
|
1935 |
-
#: classes/Views/SetupWizard.php:
|
1936 |
#, php-format
|
1937 |
msgid "You have reached an invaild step - %1$sreturn to the start of the wizard%2$s."
|
1938 |
msgstr ""
|
1939 |
|
1940 |
-
#: classes/Views/SetupWizard.php:
|
1941 |
msgid "This wizard helps you configure the basic plugin settings. All these settings can be changed at a later stage from the plugin settings."
|
1942 |
msgstr ""
|
1943 |
|
1944 |
-
#: classes/Views/SetupWizard.php:
|
1945 |
msgid "Start Configuring the Plugin"
|
1946 |
msgstr ""
|
1947 |
|
1948 |
-
#: classes/Views/SetupWizard.php:
|
1949 |
msgid "Exit Wizard"
|
1950 |
msgstr ""
|
1951 |
|
1952 |
-
#: classes/Views/SetupWizard.php:
|
1953 |
msgid "Please select the level of detail for your WordPress activity logs:"
|
1954 |
msgstr ""
|
1955 |
|
1956 |
-
#: classes/Views/SetupWizard.php:
|
1957 |
msgid "Basic (I want a high level overview and I am not interested in the detail)"
|
1958 |
msgstr ""
|
1959 |
|
1960 |
-
#: classes/Views/SetupWizard.php:
|
1961 |
msgid "Geek (I want to know everything that is happening on my WordPress)"
|
1962 |
msgstr ""
|
1963 |
|
1964 |
-
#: classes/Views/SetupWizard.php:
|
1965 |
msgid "Note: You can change the WordPress logging level from the plugin’s settings anytime."
|
1966 |
msgstr ""
|
1967 |
|
1968 |
-
#: classes/Views/SetupWizard.php:
|
1969 |
-
#: classes/Views/SetupWizard.php:
|
1970 |
-
#: classes/Views/SetupWizard.php:
|
1971 |
-
#: classes/Views/SetupWizard.php:
|
1972 |
msgid "Next"
|
1973 |
msgstr ""
|
1974 |
|
1975 |
-
#: classes/Views/SetupWizard.php:
|
1976 |
msgid "Do you or your users use other pages to log in to WordPress other than the default login page ( /wp-admin/ )?"
|
1977 |
msgstr ""
|
1978 |
|
1979 |
-
#: classes/Views/SetupWizard.php:
|
1980 |
msgid "Yes, we use other pages to login to WordPress."
|
1981 |
msgstr ""
|
1982 |
|
1983 |
-
#: classes/Views/SetupWizard.php:
|
1984 |
msgid "No, we only use the default WordPress login page."
|
1985 |
msgstr ""
|
1986 |
|
1987 |
-
#: classes/Views/SetupWizard.php:
|
1988 |
msgid "If your website is a membership or ecommerce website most probably you have more than one area from where the users can login. If you are not sure, select Yes."
|
1989 |
msgstr ""
|
1990 |
|
1991 |
-
#: classes/Views/SetupWizard.php:
|
1992 |
-
#: classes/Views/SetupWizard.php:
|
1993 |
msgid "Note: You can change the WordPress activity log retention settings at any time from the plugin settings later on."
|
1994 |
msgstr ""
|
1995 |
|
1996 |
-
#: classes/Views/SetupWizard.php:
|
1997 |
msgid "Can visitors register as a user on your website?"
|
1998 |
msgstr ""
|
1999 |
|
2000 |
-
#: classes/Views/SetupWizard.php:
|
2001 |
msgid "If you are not sure about this setting, check if the Membership setting in the WordPress General settings is checked or not. If it is not checked (default) select No."
|
2002 |
msgstr ""
|
2003 |
|
2004 |
-
#: classes/Views/SetupWizard.php:
|
2005 |
msgid "How long do you want to keep the data in the WordPress activity Log?"
|
2006 |
msgstr ""
|
2007 |
|
2008 |
-
#: classes/Views/SetupWizard.php:
|
2009 |
msgid "6 months (data older than 6 months will be deleted)"
|
2010 |
msgstr ""
|
2011 |
|
2012 |
-
#: classes/Views/SetupWizard.php:
|
2013 |
msgid "12 months (data older than 12 months will be deleted)"
|
2014 |
msgstr ""
|
2015 |
|
2016 |
-
#: classes/Views/SetupWizard.php:
|
2017 |
msgid "Keep all data."
|
2018 |
msgstr ""
|
2019 |
|
2020 |
-
#: classes/Views/SetupWizard.php:
|
2021 |
msgid "The plugin stores the data in the WordPress database in a very efficient way, though the more data you keep the more hard disk space it will consume. If you need need to retain a lot of data we would recommend you to <a href=\"https://wpactivitylog.com/features/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=wizard+configuration\" target=\"_blank\">upgrade to Premium</a> and use the Database tools to store the WordPress activity log in an external database."
|
2022 |
msgstr ""
|
2023 |
|
2024 |
-
#: classes/Views/SetupWizard.php:
|
2025 |
msgid "Your plugin is all set and it is ready to start keeping a record of everything that is happening on your WordPress in a WordPress activity log."
|
2026 |
msgstr ""
|
2027 |
|
2028 |
-
#: classes/Views/SetupWizard.php:
|
2029 |
msgid "Below are a few useful links you might need to refer to:"
|
2030 |
msgstr ""
|
2031 |
|
2032 |
-
#: classes/Views/SetupWizard.php:
|
2033 |
msgid "Getting started with the WP Activity Log plugin"
|
2034 |
msgstr ""
|
2035 |
|
2036 |
-
#: classes/Views/SetupWizard.php:
|
2037 |
msgid "Knowledge Base & Support Documents"
|
2038 |
msgstr ""
|
2039 |
|
2040 |
-
#: classes/Views/SetupWizard.php:
|
2041 |
msgid "Benefits of keeping a WordPress activity log"
|
2042 |
msgstr ""
|
2043 |
|
2044 |
-
#: classes/Views/SetupWizard.php:
|
2045 |
msgid "We trust this plugin meets all your activity log requirements. Should you encounter any problems, have feature requests or would like to share some feedback"
|
2046 |
msgstr ""
|
2047 |
|
2048 |
-
#: classes/Views/SetupWizard.php:
|
2049 |
msgid "please get in touch!"
|
2050 |
msgstr ""
|
2051 |
|
2052 |
-
#: classes/Views/SetupWizard.php:
|
2053 |
msgid "Third Party Extensions"
|
2054 |
msgstr ""
|
2055 |
|
2056 |
-
#: classes/Views/SetupWizard.php:
|
2057 |
msgid "Monitoring changes done in third party plugins"
|
2058 |
msgstr ""
|
2059 |
|
2060 |
-
#: classes/Views/SetupWizard.php:
|
2061 |
msgid "We noticed that the below plugins are installed on this website. You can install our extensions to also keep a log of changes users do on these plugins."
|
2062 |
msgstr ""
|
2063 |
|
@@ -2065,173 +2078,133 @@ msgstr ""
|
|
2065 |
msgid "Enable/Disable Events"
|
2066 |
msgstr ""
|
2067 |
|
2068 |
-
#: classes/Views/ToggleAlerts.php:
|
2069 |
msgid "Basic"
|
2070 |
msgstr ""
|
2071 |
|
2072 |
-
#: classes/Views/ToggleAlerts.php:
|
2073 |
msgid "Geek"
|
2074 |
msgstr ""
|
2075 |
|
2076 |
-
#: classes/Views/ToggleAlerts.php:
|
2077 |
msgid "Custom"
|
2078 |
msgstr ""
|
2079 |
|
2080 |
-
#: classes/Views/ToggleAlerts.php:
|
2081 |
-
msgid "
|
2082 |
msgstr ""
|
2083 |
|
2084 |
-
#: classes/Views/ToggleAlerts.php:
|
2085 |
-
msgid "Use the Log level drop down menu above to use one of our preset log levels. Alternatively you can enable or disable any of the individual events from the below tabs. Refer to <a href=\"https://wpactivitylog.com/support/kb/list-wordpress-activity-log-event-ids/\" target=\"_blank\">the complete list of WordPress activity log event IDs</a> for reference on all the events the plugin can keep a log of."
|
2086 |
-
msgstr ""
|
2087 |
-
|
2088 |
-
#: classes/Views/ToggleAlerts.php:197
|
2089 |
msgid "Third party plugins"
|
2090 |
msgstr ""
|
2091 |
|
2092 |
-
#: classes/Views/ToggleAlerts.php:
|
2093 |
-
msgid "
|
2094 |
-
msgstr ""
|
2095 |
-
|
2096 |
-
#: classes/Views/ToggleAlerts.php:300 classes/WidgetManager.php:79
|
2097 |
-
msgid "Description"
|
2098 |
-
msgstr ""
|
2099 |
-
|
2100 |
-
#: classes/Views/ToggleAlerts.php:304 defaults.php:342
|
2101 |
-
msgid "Content"
|
2102 |
-
msgstr ""
|
2103 |
-
|
2104 |
-
#: classes/Views/ToggleAlerts.php:307
|
2105 |
-
msgid "<strong>Note:</strong> Post refers to any type of content, i.e. blog post, page or a post with a custom post type."
|
2106 |
-
msgstr ""
|
2107 |
-
|
2108 |
-
#: classes/Views/ToggleAlerts.php:310
|
2109 |
-
msgid "WooCommerce"
|
2110 |
-
msgstr ""
|
2111 |
-
|
2112 |
-
#: classes/Views/ToggleAlerts.php:310 classes/Views/ToggleAlerts.php:318
|
2113 |
-
msgid "WooCommerce Products"
|
2114 |
-
msgstr ""
|
2115 |
-
|
2116 |
-
#: classes/Views/ToggleAlerts.php:314
|
2117 |
-
msgid "The plugin WooCommerce is not installed on your website so these events have been disabled."
|
2118 |
msgstr ""
|
2119 |
|
2120 |
-
#: classes/Views/ToggleAlerts.php:
|
2121 |
-
msgid "
|
2122 |
msgstr ""
|
2123 |
|
2124 |
-
#: classes/Views/ToggleAlerts.php:
|
2125 |
-
msgid "
|
2126 |
msgstr ""
|
2127 |
|
2128 |
-
#: classes/Views/ToggleAlerts.php:
|
2129 |
-
msgid "
|
2130 |
msgstr ""
|
2131 |
|
2132 |
-
#: classes/Views/ToggleAlerts.php:
|
2133 |
-
|
|
|
2134 |
msgstr ""
|
2135 |
|
2136 |
-
#: classes/Views/ToggleAlerts.php:
|
2137 |
-
msgid "
|
2138 |
msgstr ""
|
2139 |
|
2140 |
-
#: classes/Views/ToggleAlerts.php:
|
2141 |
-
msgid "
|
2142 |
msgstr ""
|
2143 |
|
2144 |
-
#: classes/Views/ToggleAlerts.php:
|
2145 |
-
|
2146 |
-
msgid "Monitor File Changes"
|
2147 |
msgstr ""
|
2148 |
|
2149 |
-
#: classes/Views/ToggleAlerts.php:
|
2150 |
-
msgid "
|
2151 |
msgstr ""
|
2152 |
|
2153 |
-
#: classes/Views/ToggleAlerts.php:
|
2154 |
-
msgid "
|
2155 |
msgstr ""
|
2156 |
|
2157 |
-
#: classes/Views/ToggleAlerts.php:
|
2158 |
-
msgid "
|
2159 |
msgstr ""
|
2160 |
|
2161 |
-
#: classes/Views/ToggleAlerts.php:
|
2162 |
-
msgid "
|
2163 |
msgstr ""
|
2164 |
|
2165 |
#: classes/Views/ToggleAlerts.php:388
|
2166 |
-
msgid "Files"
|
2167 |
-
msgstr ""
|
2168 |
-
|
2169 |
-
#: classes/Views/ToggleAlerts.php:391
|
2170 |
-
msgid "Post Settings"
|
2171 |
-
msgstr ""
|
2172 |
-
|
2173 |
-
#: classes/Views/ToggleAlerts.php:422 defaults.php:3361
|
2174 |
-
msgid "File Changes"
|
2175 |
-
msgstr ""
|
2176 |
-
|
2177 |
-
#: classes/Views/ToggleAlerts.php:461
|
2178 |
msgid "Keep a log when a visitor registers a user on the website. Only enable this if you allow visitors to register as users on your website. User registration is disabled by default in WordPress."
|
2179 |
msgstr ""
|
2180 |
|
2181 |
-
#: classes/Views/ToggleAlerts.php:
|
2182 |
msgid "Number of login attempts to log. Enter 0 to log all failed login attempts. (By default the plugin only logs up to 10 failed login because the process can be very resource intensive in case of a brute force attack)"
|
2183 |
msgstr ""
|
2184 |
|
2185 |
-
#: classes/Views/ToggleAlerts.php:
|
2186 |
msgid "Keep a log of user log in activity on custom login forms (such as WooCommerce & membership plugins)"
|
2187 |
msgstr ""
|
2188 |
|
2189 |
-
#: classes/Views/ToggleAlerts.php:
|
2190 |
msgid "Save Changes"
|
2191 |
msgstr ""
|
2192 |
|
2193 |
-
#: classes/Views/ToggleAlerts.php:
|
2194 |
msgid "Log Level Updated"
|
2195 |
msgstr ""
|
2196 |
|
2197 |
-
#: classes/Views/ToggleAlerts.php:
|
2198 |
#, php-format
|
2199 |
msgid "The %s log level has been successfully loaded and applied."
|
2200 |
msgstr ""
|
2201 |
|
2202 |
-
#: classes/Views/ToggleAlerts.php:
|
2203 |
msgid "OK"
|
2204 |
msgstr ""
|
2205 |
|
2206 |
-
#: classes/Views/ToggleAlerts.php:
|
2207 |
msgid "Enable File Integrity Scanner"
|
2208 |
msgstr ""
|
2209 |
|
2210 |
-
#: classes/Views/ToggleAlerts.php:
|
2211 |
msgid "The file integrity scanner is switched off. To enable this event it has to be switched on."
|
2212 |
msgstr ""
|
2213 |
|
2214 |
-
#: classes/Views/ToggleAlerts.php:
|
2215 |
msgid "SWITCH ON"
|
2216 |
msgstr ""
|
2217 |
|
2218 |
-
#: classes/Views/ToggleAlerts.php:
|
2219 |
msgid "DISABLE EVENT"
|
2220 |
msgstr ""
|
2221 |
|
2222 |
-
#: classes/Views/addons/html-view.php:
|
2223 |
msgid "Upgrade to Premium"
|
2224 |
msgstr ""
|
2225 |
|
2226 |
-
#: classes/Views/addons/html-view.php:
|
2227 |
msgid "More Information"
|
2228 |
msgstr ""
|
2229 |
|
2230 |
-
#: classes/Views/addons/html-view.php:
|
2231 |
msgid "Screenshots"
|
2232 |
msgstr ""
|
2233 |
|
2234 |
-
#: classes/Views/addons/html-view.php:
|
2235 |
msgid "Start Free 14-Day Premium Trial"
|
2236 |
msgstr ""
|
2237 |
|
@@ -2275,8 +2248,8 @@ msgstr ""
|
|
2275 |
msgid "View menu"
|
2276 |
msgstr ""
|
2277 |
|
2278 |
-
#: defaults.php:117 defaults.php:126 defaults.php:
|
2279 |
-
#: defaults.php:
|
2280 |
msgid "URL"
|
2281 |
msgstr ""
|
2282 |
|
@@ -2392,9 +2365,9 @@ msgstr ""
|
|
2392 |
#: defaults.php:1746 defaults.php:1760 defaults.php:1774 defaults.php:1789
|
2393 |
#: defaults.php:1804 defaults.php:1818 defaults.php:1832 defaults.php:1848
|
2394 |
#: defaults.php:1863 defaults.php:1877 defaults.php:1891 defaults.php:1906
|
2395 |
-
#: defaults.php:
|
2396 |
-
#: defaults.php:
|
2397 |
-
#: defaults.php:
|
2398 |
msgid "Role"
|
2399 |
msgstr ""
|
2400 |
|
@@ -2450,6 +2423,10 @@ msgstr ""
|
|
2450 |
msgid "Content & Comments"
|
2451 |
msgstr ""
|
2452 |
|
|
|
|
|
|
|
|
|
2453 |
#: defaults.php:346
|
2454 |
msgid "User created a new post and saved it as draft"
|
2455 |
msgstr ""
|
@@ -2468,8 +2445,8 @@ msgstr ""
|
|
2468 |
#: defaults.php:918 defaults.php:933 defaults.php:950 defaults.php:965
|
2469 |
#: defaults.php:986 defaults.php:1001 defaults.php:1016 defaults.php:1031
|
2470 |
#: defaults.php:1046 defaults.php:1061 defaults.php:1076 defaults.php:1091
|
2471 |
-
#: defaults.php:1106 defaults.php:1121 defaults.php:1140 defaults.php:
|
2472 |
-
#: defaults.php:
|
2473 |
msgid "Post ID"
|
2474 |
msgstr ""
|
2475 |
|
@@ -2483,8 +2460,8 @@ msgstr ""
|
|
2483 |
#: defaults.php:919 defaults.php:934 defaults.php:951 defaults.php:966
|
2484 |
#: defaults.php:987 defaults.php:1002 defaults.php:1017 defaults.php:1032
|
2485 |
#: defaults.php:1047 defaults.php:1062 defaults.php:1077 defaults.php:1092
|
2486 |
-
#: defaults.php:1107 defaults.php:1122 defaults.php:1141 defaults.php:
|
2487 |
-
#: defaults.php:
|
2488 |
msgid "Post type"
|
2489 |
msgstr ""
|
2490 |
|
@@ -2498,7 +2475,7 @@ msgstr ""
|
|
2498 |
#: defaults.php:935 defaults.php:952 defaults.php:967 defaults.php:988
|
2499 |
#: defaults.php:1003 defaults.php:1018 defaults.php:1033 defaults.php:1048
|
2500 |
#: defaults.php:1063 defaults.php:1078 defaults.php:1093 defaults.php:1108
|
2501 |
-
#: defaults.php:1123 defaults.php:1142 defaults.php:
|
2502 |
msgid "Post status"
|
2503 |
msgstr ""
|
2504 |
|
@@ -2550,7 +2527,7 @@ msgstr ""
|
|
2550 |
msgid "Changed the URL of the post %PostTitle%."
|
2551 |
msgstr ""
|
2552 |
|
2553 |
-
#: defaults.php:436 defaults.php:
|
2554 |
msgid "Previous URL"
|
2555 |
msgstr ""
|
2556 |
|
@@ -3704,18 +3681,20 @@ msgstr ""
|
|
3704 |
#: defaults.php:1719 defaults.php:1733 defaults.php:1747 defaults.php:1761
|
3705 |
#: defaults.php:1775 defaults.php:1790 defaults.php:1805 defaults.php:1819
|
3706 |
#: defaults.php:1833 defaults.php:1849 defaults.php:1878 defaults.php:1892
|
3707 |
-
#: defaults.php:1907 defaults.php:
|
3708 |
-
#: defaults.php:
|
3709 |
-
#: defaults.php:
|
|
|
3710 |
msgid "First name"
|
3711 |
msgstr ""
|
3712 |
|
3713 |
#: defaults.php:1720 defaults.php:1734 defaults.php:1748 defaults.php:1762
|
3714 |
#: defaults.php:1776 defaults.php:1791 defaults.php:1806 defaults.php:1820
|
3715 |
#: defaults.php:1834 defaults.php:1850 defaults.php:1865 defaults.php:1893
|
3716 |
-
#: defaults.php:1908 defaults.php:
|
3717 |
-
#: defaults.php:
|
3718 |
-
#: defaults.php:
|
|
|
3719 |
msgid "Last name"
|
3720 |
msgstr ""
|
3721 |
|
@@ -3727,7 +3706,7 @@ msgstr ""
|
|
3727 |
msgid "Changed the role of user %TargetUsername% to %NewRole%."
|
3728 |
msgstr ""
|
3729 |
|
3730 |
-
#: defaults.php:1732 defaults.php:
|
3731 |
msgid "Previous role"
|
3732 |
msgstr ""
|
3733 |
|
@@ -3791,11 +3770,11 @@ msgstr ""
|
|
3791 |
msgid "Changed the value of the custom field %custom_field_name% in the user profile %TargetUsername%."
|
3792 |
msgstr ""
|
3793 |
|
3794 |
-
#: defaults.php:1835 defaults.php:
|
3795 |
msgid "Previous value"
|
3796 |
msgstr ""
|
3797 |
|
3798 |
-
#: defaults.php:1836 defaults.php:
|
3799 |
msgid "New value"
|
3800 |
msgstr ""
|
3801 |
|
@@ -3855,1259 +3834,1316 @@ msgstr ""
|
|
3855 |
msgid "Previous display name"
|
3856 |
msgstr ""
|
3857 |
|
3858 |
-
#: defaults.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3859 |
msgid "User created an application password"
|
3860 |
msgstr ""
|
3861 |
|
3862 |
-
#: defaults.php:
|
3863 |
msgid "The application password %friendly_name%."
|
3864 |
msgstr ""
|
3865 |
|
3866 |
-
#: defaults.php:
|
3867 |
msgid "The application password %friendly_name% for the user %login%."
|
3868 |
msgstr ""
|
3869 |
|
3870 |
-
#: defaults.php:
|
3871 |
msgid "User revoked all application passwords"
|
3872 |
msgstr ""
|
3873 |
|
3874 |
-
#: defaults.php:
|
3875 |
msgid "All application passwords."
|
3876 |
msgstr ""
|
3877 |
|
3878 |
-
#: defaults.php:
|
3879 |
msgid "User revoked all application passwords for a user"
|
3880 |
msgstr ""
|
3881 |
|
3882 |
-
#: defaults.php:
|
3883 |
msgid "All application passwords from the user %login%."
|
3884 |
msgstr ""
|
3885 |
|
3886 |
-
#: defaults.php:
|
3887 |
msgid "Admin sent a password reset request to a user"
|
3888 |
msgstr ""
|
3889 |
|
3890 |
-
#: defaults.php:
|
3891 |
msgid "Sent a password reset request to the user %login%."
|
3892 |
msgstr ""
|
3893 |
|
3894 |
-
#: defaults.php:
|
3895 |
msgid "Multisite User Profiles"
|
3896 |
msgstr ""
|
3897 |
|
3898 |
-
#: defaults.php:
|
3899 |
msgid "User granted Super Admin privileges"
|
3900 |
msgstr ""
|
3901 |
|
3902 |
-
#: defaults.php:
|
3903 |
msgid "Granted Super Admin privileges to the user %TargetUsername%."
|
3904 |
msgstr ""
|
3905 |
|
3906 |
-
#: defaults.php:
|
3907 |
msgid "User revoked from Super Admin privileges"
|
3908 |
msgstr ""
|
3909 |
|
3910 |
-
#: defaults.php:
|
3911 |
msgid "Revoked Super Admin privileges from %TargetUsername%."
|
3912 |
msgstr ""
|
3913 |
|
3914 |
-
#: defaults.php:
|
3915 |
msgid "Existing user added to a site"
|
3916 |
msgstr ""
|
3917 |
|
3918 |
-
#: defaults.php:
|
3919 |
msgid "Added user %TargetUsername% to the site %SiteName%."
|
3920 |
msgstr ""
|
3921 |
|
3922 |
-
#: defaults.php:
|
3923 |
msgid "User removed from site"
|
3924 |
msgstr ""
|
3925 |
|
3926 |
-
#: defaults.php:
|
3927 |
msgid "Removed user %TargetUsername% from the site %SiteName%"
|
3928 |
msgstr ""
|
3929 |
|
3930 |
-
#: defaults.php:
|
3931 |
msgid "Site role"
|
3932 |
msgstr ""
|
3933 |
|
3934 |
-
#: defaults.php:
|
3935 |
msgid "New network user created"
|
3936 |
msgstr ""
|
3937 |
|
3938 |
-
#: defaults.php:
|
3939 |
msgid "Created the new network user %NewUserData->Username%."
|
3940 |
msgstr ""
|
3941 |
|
3942 |
-
#: defaults.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3943 |
msgid "Plugins & Themes"
|
3944 |
msgstr ""
|
3945 |
|
3946 |
-
#: defaults.php:
|
3947 |
msgid "User installed a plugin"
|
3948 |
msgstr ""
|
3949 |
|
3950 |
-
#: defaults.php:
|
3951 |
msgid "Installed the plugin %Plugin->Name%."
|
3952 |
msgstr ""
|
3953 |
|
3954 |
-
#: defaults.php:
|
3955 |
-
#: defaults.php:
|
3956 |
-
#: defaults.php:
|
3957 |
msgid "Version"
|
3958 |
msgstr ""
|
3959 |
|
3960 |
-
#: defaults.php:
|
3961 |
-
#: defaults.php:
|
3962 |
-
#: defaults.php:
|
3963 |
-
#: defaults.php:
|
3964 |
msgid "Install location"
|
3965 |
msgstr ""
|
3966 |
|
3967 |
-
#: defaults.php:
|
3968 |
msgid "User activated a WordPress plugin"
|
3969 |
msgstr ""
|
3970 |
|
3971 |
-
#: defaults.php:
|
3972 |
msgid "Activated the plugin %PluginData->Name%."
|
3973 |
msgstr ""
|
3974 |
|
3975 |
-
#: defaults.php:
|
3976 |
msgid "User deactivated a WordPress plugin"
|
3977 |
msgstr ""
|
3978 |
|
3979 |
-
#: defaults.php:
|
3980 |
msgid "Deactivated the plugin %PluginData->Name%."
|
3981 |
msgstr ""
|
3982 |
|
3983 |
-
#: defaults.php:
|
3984 |
msgid "User uninstalled a plugin"
|
3985 |
msgstr ""
|
3986 |
|
3987 |
-
#: defaults.php:
|
3988 |
msgid "Uninstalled the plugin %PluginData->Name%."
|
3989 |
msgstr ""
|
3990 |
|
3991 |
-
#: defaults.php:
|
3992 |
msgid "User upgraded a plugin"
|
3993 |
msgstr ""
|
3994 |
|
3995 |
-
#: defaults.php:
|
3996 |
msgid "Updated the plugin %PluginData->Name%."
|
3997 |
msgstr ""
|
3998 |
|
3999 |
-
#: defaults.php:
|
4000 |
msgid "Updated version"
|
4001 |
msgstr ""
|
4002 |
|
4003 |
-
#: defaults.php:
|
4004 |
msgid "A plugin created a post"
|
4005 |
msgstr ""
|
4006 |
|
4007 |
-
#: defaults.php:
|
4008 |
msgid "The plugin created the post %PostTitle%."
|
4009 |
msgstr ""
|
4010 |
|
4011 |
-
#: defaults.php:
|
4012 |
msgid "A plugin deleted a post"
|
4013 |
msgstr ""
|
4014 |
|
4015 |
-
#: defaults.php:
|
4016 |
msgid "A plugin deleted the post %PostTitle%."
|
4017 |
msgstr ""
|
4018 |
|
4019 |
-
#: defaults.php:
|
4020 |
msgid "Changed the Automatic updates setting for a plugin."
|
4021 |
msgstr ""
|
4022 |
|
4023 |
-
#: defaults.php:
|
4024 |
msgid "Changed the Automatic updates setting for the plugin %name%."
|
4025 |
msgstr ""
|
4026 |
|
4027 |
-
#: defaults.php:
|
4028 |
msgid "Changed the Automatic updates setting for a theme."
|
4029 |
msgstr ""
|
4030 |
|
4031 |
-
#: defaults.php:
|
4032 |
msgid "Changed the Automatic updates setting for the theme %name%."
|
4033 |
msgstr ""
|
4034 |
|
4035 |
-
#: defaults.php:
|
4036 |
msgid "User changed a file using the plugin editor"
|
4037 |
msgstr ""
|
4038 |
|
4039 |
-
#: defaults.php:
|
4040 |
msgid "Modified the file %File% with the plugin editor."
|
4041 |
msgstr ""
|
4042 |
|
4043 |
-
#: defaults.php:
|
4044 |
msgid "Themes"
|
4045 |
msgstr ""
|
4046 |
|
4047 |
-
#: defaults.php:
|
4048 |
msgid "User installed a theme"
|
4049 |
msgstr ""
|
4050 |
|
4051 |
-
#: defaults.php:
|
4052 |
msgid "Installed the theme %Theme->Name%."
|
4053 |
msgstr ""
|
4054 |
|
4055 |
-
#: defaults.php:
|
4056 |
msgid "User activated a theme"
|
4057 |
msgstr ""
|
4058 |
|
4059 |
-
#: defaults.php:
|
4060 |
msgid "Activated the theme %Theme->Name%."
|
4061 |
msgstr ""
|
4062 |
|
4063 |
-
#: defaults.php:
|
4064 |
msgid "User uninstalled a theme"
|
4065 |
msgstr ""
|
4066 |
|
4067 |
-
#: defaults.php:
|
4068 |
msgid "Deleted the theme %Theme->Name%."
|
4069 |
msgstr ""
|
4070 |
|
4071 |
-
#: defaults.php:
|
4072 |
msgid "User updated a theme"
|
4073 |
msgstr ""
|
4074 |
|
4075 |
-
#: defaults.php:
|
4076 |
msgid "Updated the theme %Theme->Name%."
|
4077 |
msgstr ""
|
4078 |
|
4079 |
-
#: defaults.php:
|
4080 |
msgid "New version"
|
4081 |
msgstr ""
|
4082 |
|
4083 |
-
#: defaults.php:
|
4084 |
msgid "User changed a file using the theme editor"
|
4085 |
msgstr ""
|
4086 |
|
4087 |
-
#: defaults.php:
|
4088 |
msgid "Modified the file %Theme%/%File% with the theme editor."
|
4089 |
msgstr ""
|
4090 |
|
4091 |
-
#: defaults.php:
|
4092 |
msgid "Themes on Multisite"
|
4093 |
msgstr ""
|
4094 |
|
4095 |
-
#: defaults.php:
|
4096 |
msgid "Activated theme on network"
|
4097 |
msgstr ""
|
4098 |
|
4099 |
-
#: defaults.php:
|
4100 |
msgid "Network activated the theme %Theme->Name%."
|
4101 |
msgstr ""
|
4102 |
|
4103 |
-
#: defaults.php:
|
4104 |
msgid "Deactivated theme from network"
|
4105 |
msgstr ""
|
4106 |
|
4107 |
-
#: defaults.php:
|
4108 |
msgid "Network deactivated the theme %Theme->Name%."
|
4109 |
msgstr ""
|
4110 |
|
4111 |
-
#: defaults.php:
|
4112 |
msgid "WordPress & System"
|
4113 |
msgstr ""
|
4114 |
|
4115 |
-
#: defaults.php:
|
4116 |
msgid "Unknown Error"
|
4117 |
msgstr ""
|
4118 |
|
4119 |
-
#: defaults.php:
|
4120 |
msgid "An unexpected error has occurred."
|
4121 |
msgstr ""
|
4122 |
|
4123 |
-
#: defaults.php:
|
4124 |
msgid "PHP error"
|
4125 |
msgstr ""
|
4126 |
|
4127 |
-
#: defaults.php:
|
4128 |
-
#: defaults.php:
|
4129 |
msgid "%Message%."
|
4130 |
msgstr ""
|
4131 |
|
4132 |
-
#: defaults.php:
|
4133 |
msgid "PHP warning"
|
4134 |
msgstr ""
|
4135 |
|
4136 |
-
#: defaults.php:
|
4137 |
msgid "PHP notice"
|
4138 |
msgstr ""
|
4139 |
|
4140 |
-
#: defaults.php:
|
4141 |
msgid "PHP exception"
|
4142 |
msgstr ""
|
4143 |
|
4144 |
-
#: defaults.php:
|
4145 |
msgid "PHP shutdown error"
|
4146 |
msgstr ""
|
4147 |
|
4148 |
-
#: defaults.php:
|
4149 |
msgid "WordPress was updated"
|
4150 |
msgstr ""
|
4151 |
|
4152 |
-
#: defaults.php:
|
4153 |
msgid "Updated WordPress."
|
4154 |
msgstr ""
|
4155 |
|
4156 |
-
#: defaults.php:
|
4157 |
msgid "Previous version"
|
4158 |
msgstr ""
|
4159 |
|
4160 |
-
#: defaults.php:
|
4161 |
msgid "Advertising Extensions"
|
4162 |
msgstr ""
|
4163 |
|
4164 |
-
#: defaults.php:
|
4165 |
msgid "%PromoName% %PromoMessage%"
|
4166 |
msgstr ""
|
4167 |
|
4168 |
-
#: defaults.php:
|
4169 |
msgid "Activity log plugin"
|
4170 |
msgstr ""
|
4171 |
|
4172 |
-
#: defaults.php:
|
4173 |
msgid "Events automatically pruned by system"
|
4174 |
msgstr ""
|
4175 |
|
4176 |
-
#: defaults.php:
|
4177 |
msgid "System automatically deleted %EventCount% events from the activity log."
|
4178 |
msgstr ""
|
4179 |
|
4180 |
-
#: defaults.php:
|
4181 |
msgid "Reset the plugin's settings to default"
|
4182 |
msgstr ""
|
4183 |
|
4184 |
-
#: defaults.php:
|
4185 |
msgid "Reset the activity log plugin's settings to default."
|
4186 |
msgstr ""
|
4187 |
|
4188 |
-
#: defaults.php:
|
4189 |
msgid "Purged the activity log"
|
4190 |
msgstr ""
|
4191 |
|
4192 |
-
#: defaults.php:
|
4193 |
msgid "Purged the activity log."
|
4194 |
msgstr ""
|
4195 |
|
4196 |
-
#: defaults.php:
|
4197 |
msgid "Deleted all the data about a user from the activity log."
|
4198 |
msgstr ""
|
4199 |
|
4200 |
-
#: defaults.php:
|
4201 |
msgid "Deleted all the data about the user <strong>%user%</strong> from the activity log."
|
4202 |
msgstr ""
|
4203 |
|
4204 |
-
#: defaults.php:
|
4205 |
msgid "Deleted all the data of a specific type from the activity log."
|
4206 |
msgstr ""
|
4207 |
|
4208 |
-
#: defaults.php:
|
4209 |
msgid "Deleted all the data about the %deleted_data_type% %deleted_data% from the activity log."
|
4210 |
msgstr ""
|
4211 |
|
4212 |
-
#: defaults.php:
|
4213 |
msgid "Some WP Activity Log plugin settings on this site were propagated and overridden from the MainWP dashboard"
|
4214 |
msgstr ""
|
4215 |
|
4216 |
-
#: defaults.php:
|
4217 |
msgid "Some <strong>WP Activity Log</strong> plugin settings on this site were propagated and overridden from the MainWP dashboard."
|
4218 |
msgstr ""
|
4219 |
|
4220 |
-
#: defaults.php:
|
4221 |
msgid "Changed the status of the Login Page Notification"
|
4222 |
msgstr ""
|
4223 |
|
4224 |
-
#: defaults.php:
|
4225 |
msgid "Changed the status of the <strong>Login Page Notification.</strong>"
|
4226 |
msgstr ""
|
4227 |
|
4228 |
-
#: defaults.php:
|
4229 |
msgid "Changed the text of the Login Page Notification"
|
4230 |
msgstr ""
|
4231 |
|
4232 |
-
#: defaults.php:
|
4233 |
msgid "Changed the text of the <strong>Login Page Notification.</strong>"
|
4234 |
msgstr ""
|
4235 |
|
4236 |
-
#: defaults.php:
|
4237 |
msgid "Changed the status of the Reverse proxy / firewall option"
|
4238 |
msgstr ""
|
4239 |
|
4240 |
-
#: defaults.php:
|
4241 |
msgid "Changed the status of the <strong>Reverse proxy / firewall option.</strong>"
|
4242 |
msgstr ""
|
4243 |
|
4244 |
-
#: defaults.php:
|
4245 |
msgid "Changed the Restrict plugin access setting"
|
4246 |
msgstr ""
|
4247 |
|
4248 |
-
#: defaults.php:
|
4249 |
msgid "Changed the <strong>Restrict plugin access</strong> setting to %new_setting%."
|
4250 |
msgstr ""
|
4251 |
|
4252 |
-
#: defaults.php:
|
4253 |
-
#: defaults.php:
|
4254 |
msgid "Previous setting"
|
4255 |
msgstr ""
|
4256 |
|
4257 |
-
#: defaults.php:
|
4258 |
msgid "The user %user% to / from the list of users who can view the activity log"
|
4259 |
msgstr ""
|
4260 |
|
4261 |
-
#: defaults.php:
|
4262 |
msgid "The user %user% to / from the list of users who can view the activity log."
|
4263 |
msgstr ""
|
4264 |
|
4265 |
-
#: defaults.php:
|
4266 |
msgid "Previous list of users who had access to view the activity log"
|
4267 |
msgstr ""
|
4268 |
|
4269 |
-
#: defaults.php:
|
4270 |
msgid "Changed the status of the Hide plugin in plugins page setting"
|
4271 |
msgstr ""
|
4272 |
|
4273 |
-
#: defaults.php:
|
4274 |
msgid "Changed the status of the <strong>Hide plugin in plugins page</strong> setting."
|
4275 |
msgstr ""
|
4276 |
|
4277 |
-
#: defaults.php:
|
4278 |
msgid "Changed the Activity log retention setting"
|
4279 |
msgstr ""
|
4280 |
|
4281 |
-
#: defaults.php:
|
4282 |
msgid "Changed the <strong>Activity log retention</strong> to %new_setting%."
|
4283 |
msgstr ""
|
4284 |
|
4285 |
-
#: defaults.php:
|
4286 |
msgid "A user was added to / from the list of excluded users from the activity log"
|
4287 |
msgstr ""
|
4288 |
|
4289 |
-
#: defaults.php:
|
4290 |
msgid "The user %user% to / from the list of excluded users from the activity log."
|
4291 |
msgstr ""
|
4292 |
|
4293 |
-
#: defaults.php:
|
4294 |
msgid "Previous list of users"
|
4295 |
msgstr ""
|
4296 |
|
4297 |
-
#: defaults.php:
|
4298 |
msgid "A user role was added to / from the list of excluded roles from the activity log"
|
4299 |
msgstr ""
|
4300 |
|
4301 |
-
#: defaults.php:
|
4302 |
msgid "The user role %role% to / from the list of excluded roles from the activity log."
|
4303 |
msgstr ""
|
4304 |
|
4305 |
-
#: defaults.php:
|
4306 |
msgid "An IP address was added to / from the list of excluded IP addresses from the activity log"
|
4307 |
msgstr ""
|
4308 |
|
4309 |
-
#: defaults.php:
|
4310 |
msgid "The IP address %ip% to / from the list of excluded IP addresses from the activity log."
|
4311 |
msgstr ""
|
4312 |
|
4313 |
-
#: defaults.php:
|
4314 |
msgid "Previous list of IPs"
|
4315 |
msgstr ""
|
4316 |
|
4317 |
-
#: defaults.php:
|
4318 |
msgid "A post type was added to / from the list of excluded post types from the activity log"
|
4319 |
msgstr ""
|
4320 |
|
4321 |
-
#: defaults.php:
|
4322 |
msgid "The post type %post_type% to / from the list of excluded post types from the activity log."
|
4323 |
msgstr ""
|
4324 |
|
4325 |
-
#: defaults.php:
|
4326 |
msgid "Previous list of Post types"
|
4327 |
msgstr ""
|
4328 |
|
4329 |
-
#: defaults.php:
|
4330 |
msgid "A custom field was added to / from the list of excluded custom fields from the activity log"
|
4331 |
msgstr ""
|
4332 |
|
4333 |
-
#: defaults.php:
|
4334 |
msgid "The custom field %custom_field% to / from the list of excluded custom fields from the activity log."
|
4335 |
msgstr ""
|
4336 |
|
4337 |
-
#: defaults.php:
|
4338 |
msgid "Previous list of Custom fields"
|
4339 |
msgstr ""
|
4340 |
|
4341 |
-
#: defaults.php:
|
4342 |
msgid "A custom field was added to / from the list of excluded user profile custom fields from the activity log"
|
4343 |
msgstr ""
|
4344 |
|
4345 |
-
#: defaults.php:
|
4346 |
msgid "The custom field %custom_field% to / from the list of excluded user profile custom fields from the activity log."
|
4347 |
msgstr ""
|
4348 |
|
4349 |
-
#: defaults.php:
|
4350 |
msgid "Previous list of user profile Custom fields"
|
4351 |
msgstr ""
|
4352 |
|
4353 |
-
#: defaults.php:
|
4354 |
msgid "Notifications & Integrations"
|
4355 |
msgstr ""
|
4356 |
|
4357 |
-
#: defaults.php:
|
4358 |
msgid "Changed the status of the Daily Summary of Activity Log"
|
4359 |
msgstr ""
|
4360 |
|
4361 |
-
#: defaults.php:
|
4362 |
msgid "Changed the status of the <strong>Daily Summary of Activity Log.</strong>."
|
4363 |
msgstr ""
|
4364 |
|
4365 |
-
#: defaults.php:
|
4366 |
msgid "Modified the reciepients of the Daily Summary of Activity Log."
|
4367 |
msgstr ""
|
4368 |
|
4369 |
-
#: defaults.php:
|
4370 |
msgid "Modified the reciepients of the <strong>Daily Summary of Activity Log</strong>."
|
4371 |
msgstr ""
|
4372 |
|
4373 |
-
#: defaults.php:
|
4374 |
msgid "New recipient"
|
4375 |
msgstr ""
|
4376 |
|
4377 |
-
#: defaults.php:
|
4378 |
msgid "Previous recipient"
|
4379 |
msgstr ""
|
4380 |
|
4381 |
-
#: defaults.php:
|
4382 |
msgid "Changed the status of a built in notification"
|
4383 |
msgstr ""
|
4384 |
|
4385 |
-
#: defaults.php:
|
4386 |
msgid "Changed the status of the built in notification %notification_name%."
|
4387 |
msgstr ""
|
4388 |
|
4389 |
-
#: defaults.php:
|
4390 |
msgid "Modified the recipient(s) of the built a notification"
|
4391 |
msgstr ""
|
4392 |
|
4393 |
-
#: defaults.php:
|
4394 |
msgid "Modified the recipient(s) of the built in notification %notification_name%."
|
4395 |
msgstr ""
|
4396 |
|
4397 |
-
#: defaults.php:
|
4398 |
msgid "New recipient(s)"
|
4399 |
msgstr ""
|
4400 |
|
4401 |
-
#: defaults.php:
|
4402 |
msgid "Previous recipient(s)"
|
4403 |
msgstr ""
|
4404 |
|
4405 |
-
#: defaults.php:
|
4406 |
msgid "Added a new custom notification"
|
4407 |
msgstr ""
|
4408 |
|
4409 |
-
#: defaults.php:
|
4410 |
msgid "Added a new custom notification %notification_name%."
|
4411 |
msgstr ""
|
4412 |
|
4413 |
-
#: defaults.php:
|
4414 |
msgid "Recipient(s)"
|
4415 |
msgstr ""
|
4416 |
|
4417 |
-
#: defaults.php:
|
4418 |
msgid "Modified a custom notification"
|
4419 |
msgstr ""
|
4420 |
|
4421 |
-
#: defaults.php:
|
4422 |
msgid "Modified the custom notification %notification_name%."
|
4423 |
msgstr ""
|
4424 |
|
4425 |
-
#: defaults.php:
|
4426 |
msgid "Changed the status of a custom notification"
|
4427 |
msgstr ""
|
4428 |
|
4429 |
-
#: defaults.php:
|
4430 |
msgid "Changed the status of the custom notification %notification_name%."
|
4431 |
msgstr ""
|
4432 |
|
4433 |
-
#: defaults.php:
|
4434 |
msgid "Deleted a custom notification"
|
4435 |
msgstr ""
|
4436 |
|
4437 |
-
#: defaults.php:
|
4438 |
msgid "Deleted the custom notification %notification_name%."
|
4439 |
msgstr ""
|
4440 |
|
4441 |
-
#: defaults.php:
|
4442 |
msgid "Modified a default notification template"
|
4443 |
msgstr ""
|
4444 |
|
4445 |
-
#: defaults.php:
|
4446 |
msgid "Modified the default %template_name% notification template."
|
4447 |
msgstr ""
|
4448 |
|
4449 |
-
#: defaults.php:
|
4450 |
msgid "Added a new integrations connection"
|
4451 |
msgstr ""
|
4452 |
|
4453 |
-
#: defaults.php:
|
4454 |
msgid "Added / removed the integrations connection %name%"
|
4455 |
msgstr ""
|
4456 |
|
4457 |
-
#: defaults.php:
|
4458 |
msgid "Connection type"
|
4459 |
msgstr ""
|
4460 |
|
4461 |
-
#: defaults.php:
|
4462 |
msgid "Modified an integrations connection"
|
4463 |
msgstr ""
|
4464 |
|
4465 |
-
#: defaults.php:
|
4466 |
msgid "Modified the integrations connection %name%."
|
4467 |
msgstr ""
|
4468 |
|
4469 |
-
#: defaults.php:
|
4470 |
msgid "Deleted a integrations connection"
|
4471 |
msgstr ""
|
4472 |
|
4473 |
-
#: defaults.php:
|
4474 |
msgid "Deleted the integrations connection %name%."
|
4475 |
msgstr ""
|
4476 |
|
4477 |
-
#: defaults.php:
|
4478 |
msgid "Added a new activity log mirror"
|
4479 |
msgstr ""
|
4480 |
|
4481 |
-
#: defaults.php:
|
4482 |
msgid "Added a new activity log mirror %name%."
|
4483 |
msgstr ""
|
4484 |
|
4485 |
-
#: defaults.php:
|
4486 |
msgid "Connection used by this mirror"
|
4487 |
msgstr ""
|
4488 |
|
4489 |
-
#: defaults.php:
|
4490 |
msgid "Modified an activity log mirror"
|
4491 |
msgstr ""
|
4492 |
|
4493 |
-
#: defaults.php:
|
4494 |
msgid "Modified the activity log mirror %name%."
|
4495 |
msgstr ""
|
4496 |
|
4497 |
-
#: defaults.php:
|
4498 |
msgid "Changed the status of an activity log mirror"
|
4499 |
msgstr ""
|
4500 |
|
4501 |
-
#: defaults.php:
|
4502 |
msgid "Changed the status of the activity log mirror %name%."
|
4503 |
msgstr ""
|
4504 |
|
4505 |
-
#: defaults.php:
|
4506 |
msgid "Deleted an activity log mirror"
|
4507 |
msgstr ""
|
4508 |
|
4509 |
-
#: defaults.php:
|
4510 |
msgid "Deleted the activity log mirror %name%."
|
4511 |
msgstr ""
|
4512 |
|
4513 |
-
#: defaults.php:
|
4514 |
msgid "Changed the status of Logging of events to the database"
|
4515 |
msgstr ""
|
4516 |
|
4517 |
-
#: defaults.php:
|
4518 |
msgid "Changed the status of <strong>Logging of events to the database</strong>."
|
4519 |
msgstr ""
|
4520 |
|
4521 |
-
#: defaults.php:
|
4522 |
msgid "WordPress Site Settings"
|
4523 |
msgstr ""
|
4524 |
|
4525 |
-
#: defaults.php:
|
4526 |
msgid "Option Anyone Can Register in WordPress settings changed"
|
4527 |
msgstr ""
|
4528 |
|
4529 |
-
#: defaults.php:
|
4530 |
msgid "The <strong>Membership</strong> setting <strong>Anyone can register</strong>."
|
4531 |
msgstr ""
|
4532 |
|
4533 |
-
#: defaults.php:
|
4534 |
msgid "New User Default Role changed"
|
4535 |
msgstr ""
|
4536 |
|
4537 |
-
#: defaults.php:
|
4538 |
msgid "Changed the <strong>New user default role</strong> WordPress setting."
|
4539 |
msgstr ""
|
4540 |
|
4541 |
-
#: defaults.php:
|
4542 |
msgid "New role"
|
4543 |
msgstr ""
|
4544 |
|
4545 |
-
#: defaults.php:
|
4546 |
msgid "WordPress Administrator Notification email changed"
|
4547 |
msgstr ""
|
4548 |
|
4549 |
-
#: defaults.php:
|
4550 |
msgid "Change the <strong>Administrator email address</strong> in the WordPress settings."
|
4551 |
msgstr ""
|
4552 |
|
4553 |
-
#: defaults.php:
|
4554 |
msgid "Previous address"
|
4555 |
msgstr ""
|
4556 |
|
4557 |
-
#: defaults.php:
|
4558 |
msgid "New address"
|
4559 |
msgstr ""
|
4560 |
|
4561 |
-
#: defaults.php:
|
4562 |
msgid "User changes the WordPress Permalinks"
|
4563 |
msgstr ""
|
4564 |
|
4565 |
-
#: defaults.php:
|
4566 |
msgid "Changed the <strong>WordPress permalinks</strong>."
|
4567 |
msgstr ""
|
4568 |
|
4569 |
-
#: defaults.php:
|
4570 |
msgid "Previous permalinks"
|
4571 |
msgstr ""
|
4572 |
|
4573 |
-
#: defaults.php:
|
4574 |
msgid "New permalinks"
|
4575 |
msgstr ""
|
4576 |
|
4577 |
-
#: defaults.php:
|
4578 |
msgid "Enabled/Disabled the option Discourage search engines from indexing this site"
|
4579 |
msgstr ""
|
4580 |
|
4581 |
-
#: defaults.php:
|
4582 |
msgid "Changed the status of the WordPress setting <strong>Search engine visibility</strong> (Discourage search engines from indexing this site)"
|
4583 |
msgstr ""
|
4584 |
|
4585 |
-
#: defaults.php:
|
4586 |
msgid "Enabled/Disabled comments on all the website"
|
4587 |
msgstr ""
|
4588 |
|
4589 |
-
#: defaults.php:
|
4590 |
msgid "Changed the status of the WordPress setting <strong>Allow people to submit comments on new posts</strong>."
|
4591 |
msgstr ""
|
4592 |
|
4593 |
-
#: defaults.php:
|
4594 |
msgid "Enabled/Disabled the option Comment author must fill out name and email"
|
4595 |
msgstr ""
|
4596 |
|
4597 |
-
#: defaults.php:
|
4598 |
msgid "Changed the status of the WordPress setting <strong>.Comment author must fill out name and email</strong>."
|
4599 |
msgstr ""
|
4600 |
|
4601 |
-
#: defaults.php:
|
4602 |
msgid "Enabled/Disabled the option Users must be logged in and registered to comment"
|
4603 |
msgstr ""
|
4604 |
|
4605 |
-
#: defaults.php:
|
4606 |
msgid "Changed the status of the WordPress setting <strong>Users must be registered and logged in to comment</strong>."
|
4607 |
msgstr ""
|
4608 |
|
4609 |
-
#: defaults.php:
|
4610 |
msgid "Enabled/Disabled the option to automatically close comments"
|
4611 |
msgstr ""
|
4612 |
|
4613 |
-
#: defaults.php:
|
4614 |
msgid "Changed the status of the WordPress setting <strong>Automatically close comments after %Value% days</strong>."
|
4615 |
msgstr ""
|
4616 |
|
4617 |
-
#: defaults.php:
|
4618 |
msgid "Changed the value of the option Automatically close comments"
|
4619 |
msgstr ""
|
4620 |
|
4621 |
-
#: defaults.php:
|
4622 |
msgid "Changed the value of the WordPress setting <strong>Automatically close comments after a number of days</strong> to %NewValue%."
|
4623 |
msgstr ""
|
4624 |
|
4625 |
-
#: defaults.php:
|
4626 |
msgid "Enabled/Disabled the option for comments to be manually approved"
|
4627 |
msgstr ""
|
4628 |
|
4629 |
-
#: defaults.php:
|
4630 |
msgid "Changed the value of the WordPress setting <strong>Comments must be manualy approved</strong>."
|
4631 |
msgstr ""
|
4632 |
|
4633 |
-
#: defaults.php:
|
4634 |
msgid "Enabled/Disabled the option for an author to have previously approved comments for the comments to appear"
|
4635 |
msgstr ""
|
4636 |
|
4637 |
-
#: defaults.php:
|
4638 |
msgid "Changed the value of the WordPress setting <strong>Comment author must have a previously approved comment</strong>."
|
4639 |
msgstr ""
|
4640 |
|
4641 |
-
#: defaults.php:
|
4642 |
msgid "Changed the number of links that a comment must have to be held in the queue"
|
4643 |
msgstr ""
|
4644 |
|
4645 |
-
#: defaults.php:
|
4646 |
msgid "Changed the value of the WordPress setting <strong>Hold a comment in the queue if it contains links</strong> to %NewValue% links."
|
4647 |
msgstr ""
|
4648 |
|
4649 |
-
#: defaults.php:
|
4650 |
msgid "Modified the list of keywords for comments moderation"
|
4651 |
msgstr ""
|
4652 |
|
4653 |
-
#: defaults.php:
|
4654 |
-
msgid "Modified the list of keywords for comments
|
4655 |
msgstr ""
|
4656 |
|
4657 |
-
#: defaults.php:
|
4658 |
msgid "Modified the list of keywords for comments blacklisting"
|
4659 |
msgstr ""
|
4660 |
|
4661 |
-
#: defaults.php:
|
4662 |
msgid "Modified the list of <strong>Disallowed comment keys</strong> (keywords) for comments blacklisting in WordPress."
|
4663 |
msgstr ""
|
4664 |
|
4665 |
-
#: defaults.php:
|
4666 |
msgid "Option WordPress Address (URL) in WordPress settings changed"
|
4667 |
msgstr ""
|
4668 |
|
4669 |
-
#: defaults.php:
|
4670 |
msgid "Changed the <strong>WordPress address (URL)</strong> tp %new_url%."
|
4671 |
msgstr ""
|
4672 |
|
4673 |
-
#: defaults.php:
|
4674 |
msgid "Option Site Address (URL) in WordPress settings changed"
|
4675 |
msgstr ""
|
4676 |
|
4677 |
-
#: defaults.php:
|
4678 |
msgid "Changed the <strong>Site address (URL)</strong> to %new_url%."
|
4679 |
msgstr ""
|
4680 |
|
4681 |
-
#: defaults.php:
|
4682 |
msgid "Option Your homepage displays in WordPress settings changed"
|
4683 |
msgstr ""
|
4684 |
|
4685 |
-
#: defaults.php:
|
4686 |
msgid "Changed the <strong>Your homepage displays</strong> WordPress setting to %new_homepage%."
|
4687 |
msgstr ""
|
4688 |
|
4689 |
-
#: defaults.php:
|
4690 |
msgid "Option homepage in WordPress settings changed"
|
4691 |
msgstr ""
|
4692 |
|
4693 |
-
#: defaults.php:
|
4694 |
msgid "Changed the <strong>Homepage</strong> in the WordPress settings to %new_page%."
|
4695 |
msgstr ""
|
4696 |
|
4697 |
-
#: defaults.php:
|
4698 |
msgid "Previous page"
|
4699 |
msgstr ""
|
4700 |
|
4701 |
-
#: defaults.php:
|
4702 |
msgid "Option posts page in WordPress settings changed"
|
4703 |
msgstr ""
|
4704 |
|
4705 |
-
#: defaults.php:
|
4706 |
msgid "Changed the <strong> Posts</strong> page in the WordPress settings to %new_page%."
|
4707 |
msgstr ""
|
4708 |
|
4709 |
-
#: defaults.php:
|
4710 |
msgid "Option Timezone in WordPress settings changed"
|
4711 |
msgstr ""
|
4712 |
|
4713 |
-
#: defaults.php:
|
4714 |
msgid "Changed the <strong>Timezone</strong> in the WordPress settings to %new_timezone%."
|
4715 |
msgstr ""
|
4716 |
|
4717 |
-
#: defaults.php:
|
4718 |
msgid "Previous timezone"
|
4719 |
msgstr ""
|
4720 |
|
4721 |
-
#: defaults.php:
|
4722 |
msgid "Option Date format in WordPress settings changed"
|
4723 |
msgstr ""
|
4724 |
|
4725 |
-
#: defaults.php:
|
4726 |
msgid "Changed the <strong>Date format</strong> in the WordPress settings to %new_date_format%."
|
4727 |
msgstr ""
|
4728 |
|
4729 |
-
#: defaults.php:
|
4730 |
msgid "Previous format"
|
4731 |
msgstr ""
|
4732 |
|
4733 |
-
#: defaults.php:
|
4734 |
msgid "Option Time format in WordPress settings changed"
|
4735 |
msgstr ""
|
4736 |
|
4737 |
-
#: defaults.php:
|
4738 |
msgid "Changed the <strong>Time format</strong> in the WordPress settings to %new_time_format%."
|
4739 |
msgstr ""
|
4740 |
|
4741 |
-
#: defaults.php:
|
4742 |
msgid "Option Automatic updates setting changed"
|
4743 |
msgstr ""
|
4744 |
|
4745 |
-
#: defaults.php:
|
4746 |
msgid "Changed the <strong>Automatic updates</strong> setting."
|
4747 |
msgstr ""
|
4748 |
|
4749 |
-
#: defaults.php:
|
4750 |
msgid "New setting status"
|
4751 |
msgstr ""
|
4752 |
|
4753 |
-
#: defaults.php:
|
4754 |
msgid "Option Site Language setting changed"
|
4755 |
msgstr ""
|
4756 |
|
4757 |
-
#: defaults.php:
|
4758 |
msgid "Changed the <strong>Site Language</strong> to %new_value%."
|
4759 |
msgstr ""
|
4760 |
|
4761 |
-
#: defaults.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4762 |
msgid "Database Events"
|
4763 |
msgstr ""
|
4764 |
|
4765 |
-
#: defaults.php:
|
4766 |
msgid "Plugin created table"
|
4767 |
msgstr ""
|
4768 |
|
4769 |
-
#: defaults.php:
|
4770 |
msgid "The plugin %Plugin->Name% created this table in the database."
|
4771 |
msgstr ""
|
4772 |
|
4773 |
-
#: defaults.php:
|
4774 |
-
#: defaults.php:
|
4775 |
msgid "Table"
|
4776 |
msgstr ""
|
4777 |
|
4778 |
-
#: defaults.php:
|
4779 |
msgid "Plugin modified table structure"
|
4780 |
msgstr ""
|
4781 |
|
4782 |
-
#: defaults.php:
|
4783 |
msgid "The plugin %Plugin->Name% modified the structure of a database table."
|
4784 |
msgstr ""
|
4785 |
|
4786 |
-
#: defaults.php:
|
4787 |
msgid "Plugin deleted table"
|
4788 |
msgstr ""
|
4789 |
|
4790 |
-
#: defaults.php:
|
4791 |
msgid "The plugin %Plugin->Name% deleted this table from the database."
|
4792 |
msgstr ""
|
4793 |
|
4794 |
-
#: defaults.php:
|
4795 |
msgid "Theme created tables"
|
4796 |
msgstr ""
|
4797 |
|
4798 |
-
#: defaults.php:
|
4799 |
msgid "The theme %Theme->Name% created this tables in the database."
|
4800 |
msgstr ""
|
4801 |
|
4802 |
-
#: defaults.php:
|
4803 |
msgid "Theme modified tables structure"
|
4804 |
msgstr ""
|
4805 |
|
4806 |
-
#: defaults.php:
|
4807 |
msgid "The theme %Theme->Name% modified the structure of this database table"
|
4808 |
msgstr ""
|
4809 |
|
4810 |
-
#: defaults.php:
|
4811 |
msgid "Theme deleted tables"
|
4812 |
msgstr ""
|
4813 |
|
4814 |
-
#: defaults.php:
|
4815 |
msgid "The theme %Theme->Name% deleted this table from the database."
|
4816 |
msgstr ""
|
4817 |
|
4818 |
-
#: defaults.php:
|
4819 |
-
#: defaults.php:
|
4820 |
msgid "Tables"
|
4821 |
msgstr ""
|
4822 |
|
4823 |
-
#: defaults.php:
|
4824 |
msgid "Unknown component created tables"
|
4825 |
msgstr ""
|
4826 |
|
4827 |
-
#: defaults.php:
|
4828 |
msgid "An unknown component created these tables in the database."
|
4829 |
msgstr ""
|
4830 |
|
4831 |
-
#: defaults.php:
|
4832 |
msgid "Unknown component modified tables structure"
|
4833 |
msgstr ""
|
4834 |
|
4835 |
-
#: defaults.php:
|
4836 |
msgid "An unknown component modified the structure of these database tables."
|
4837 |
msgstr ""
|
4838 |
|
4839 |
-
#: defaults.php:
|
4840 |
msgid "Unknown component deleted tables"
|
4841 |
msgstr ""
|
4842 |
|
4843 |
-
#: defaults.php:
|
4844 |
msgid "An unknown component deleted these tables from the database."
|
4845 |
msgstr ""
|
4846 |
|
4847 |
-
#: defaults.php:
|
4848 |
msgid "WordPress created tables"
|
4849 |
msgstr ""
|
4850 |
|
4851 |
-
#: defaults.php:
|
4852 |
msgid "WordPress has created these tables in the database."
|
4853 |
msgstr ""
|
4854 |
|
4855 |
-
#: defaults.php:
|
4856 |
msgid "WordPress modified tables structure"
|
4857 |
msgstr ""
|
4858 |
|
4859 |
-
#: defaults.php:
|
4860 |
msgid "WordPress modified the structure of these database tables."
|
4861 |
msgstr ""
|
4862 |
|
4863 |
-
#: defaults.php:
|
4864 |
msgid "WordPress deleted tables"
|
4865 |
msgstr ""
|
4866 |
|
4867 |
-
#: defaults.php:
|
4868 |
msgid "WordPress deleted these tables from the database."
|
4869 |
msgstr ""
|
4870 |
|
4871 |
-
#: defaults.php:
|
4872 |
msgid "Multisite Network Sites"
|
4873 |
msgstr ""
|
4874 |
|
4875 |
-
#: defaults.php:
|
|
|
|
|
|
|
|
|
4876 |
msgid "New site added on the network"
|
4877 |
msgstr ""
|
4878 |
|
4879 |
-
#: defaults.php:
|
4880 |
msgid "Added the new site %SiteName% to the network."
|
4881 |
msgstr ""
|
4882 |
|
4883 |
-
#: defaults.php:
|
4884 |
msgid "Existing site archived"
|
4885 |
msgstr ""
|
4886 |
|
4887 |
-
#: defaults.php:
|
4888 |
msgid "Archived the site %SiteName% on the network."
|
4889 |
msgstr ""
|
4890 |
|
4891 |
-
#: defaults.php:
|
4892 |
msgid "Archived site has been unarchived"
|
4893 |
msgstr ""
|
4894 |
|
4895 |
-
#: defaults.php:
|
4896 |
msgid "Unarchived the site %SiteName%."
|
4897 |
msgstr ""
|
4898 |
|
4899 |
-
#: defaults.php:
|
4900 |
msgid "Deactivated site has been activated"
|
4901 |
msgstr ""
|
4902 |
|
4903 |
-
#: defaults.php:
|
4904 |
msgid "Activated the site %SiteName% on the network."
|
4905 |
msgstr ""
|
4906 |
|
4907 |
-
#: defaults.php:
|
4908 |
msgid "Site has been deactivated"
|
4909 |
msgstr ""
|
4910 |
|
4911 |
-
#: defaults.php:
|
4912 |
msgid "Deactiveated the site %SiteName% on the network."
|
4913 |
msgstr ""
|
4914 |
|
4915 |
-
#: defaults.php:
|
4916 |
msgid "Existing site deleted from network"
|
4917 |
msgstr ""
|
4918 |
|
4919 |
-
#: defaults.php:
|
4920 |
msgid "The site: %SiteName%."
|
4921 |
msgstr ""
|
4922 |
|
4923 |
-
#: defaults.php:
|
4924 |
msgid "Allow site administrators to add new users to their sites settings changed"
|
4925 |
msgstr ""
|
4926 |
|
4927 |
-
#: defaults.php:
|
4928 |
msgid "Changed the status of the network setting <strong>Allow site administrators to add new users to their sites</strong>."
|
4929 |
msgstr ""
|
4930 |
|
4931 |
-
#: defaults.php:
|
4932 |
msgid "Site upload space settings changed"
|
4933 |
msgstr ""
|
4934 |
|
4935 |
-
#: defaults.php:
|
4936 |
msgid "Changed the status of the network setting <strong>Site upload space</strong> (to limit space allocated for each site's upload directory)."
|
4937 |
msgstr ""
|
4938 |
|
4939 |
-
#: defaults.php:
|
4940 |
msgid "Site upload space file size settings changed"
|
4941 |
msgstr ""
|
4942 |
|
4943 |
-
#: defaults.php:
|
4944 |
msgid "Changed the file size in the <strong>Site upload space</strong> network setting to %new_value%."
|
4945 |
msgstr ""
|
4946 |
|
4947 |
-
#: defaults.php:
|
4948 |
msgid "Previous size (MB)"
|
4949 |
msgstr ""
|
4950 |
|
4951 |
-
#: defaults.php:
|
4952 |
msgid "Site Upload file types settings changed"
|
4953 |
msgstr ""
|
4954 |
|
4955 |
-
#: defaults.php:
|
4956 |
msgid "Changed the network setting <strong>Upload file types (list of allowed file types)</strong>."
|
4957 |
msgstr ""
|
4958 |
|
4959 |
-
#: defaults.php:
|
4960 |
msgid "Site Max upload file size settings changed"
|
4961 |
msgstr ""
|
4962 |
|
4963 |
-
#: defaults.php:
|
4964 |
msgid "Changed the <strong>Max upload file size</strong> network setting to %new_value%."
|
4965 |
msgstr ""
|
4966 |
|
4967 |
-
#: defaults.php:
|
4968 |
msgid "Previous size (KB)"
|
4969 |
msgstr ""
|
4970 |
|
4971 |
-
#: defaults.php:
|
4972 |
msgid "Allow new registrations settings changed"
|
4973 |
msgstr ""
|
4974 |
|
4975 |
-
#: defaults.php:
|
4976 |
msgid "Changed the <strong>Allow new registrations</strong> setting to %new_setting%."
|
4977 |
msgstr ""
|
4978 |
|
4979 |
-
#: defaults.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4980 |
msgid "Dummy"
|
4981 |
msgstr ""
|
4982 |
|
4983 |
-
#: wp-
|
|
|
|
|
|
|
|
|
|
|
4984 |
#, php-format
|
4985 |
msgid "Hey %s"
|
4986 |
msgstr ""
|
4987 |
|
4988 |
-
#: wp-security-audit-log.php:
|
4989 |
msgid "Never miss an important update! Opt-in to our security and feature updates notifications, and non-sensitive diagnostic tracking with freemius.com."
|
4990 |
msgstr ""
|
4991 |
|
4992 |
-
#: wp-security-audit-log.php:
|
4993 |
msgid "Note: "
|
4994 |
msgstr ""
|
4995 |
|
4996 |
-
#: wp-security-audit-log.php:
|
4997 |
msgid "NO ACTIVITY LOG ACTIVITY & DATA IS SENT BACK TO OUR SERVERS."
|
4998 |
msgstr ""
|
4999 |
|
5000 |
-
#: wp-security-audit-log.php:
|
5001 |
#, php-format
|
5002 |
msgid "Please help us improve %1$s! If you opt-in, some non-sensitive data about your usage of %2$s will be sent to %3$s, a diagnostic tracking service we use. If you skip this, that's okay! %2$s will still work just fine."
|
5003 |
msgstr ""
|
5004 |
|
5005 |
-
#: wp-security-audit-log.php:
|
5006 |
#, php-format
|
5007 |
msgid "You need to activate the licence key to use WP Activity Log Premium. %2$s"
|
5008 |
msgstr ""
|
5009 |
|
5010 |
-
#: wp-security-audit-log.php:
|
5011 |
msgid "Activate the licence key now"
|
5012 |
msgstr ""
|
5013 |
|
5014 |
-
#: wp-security-audit-log.php:
|
5015 |
#, php-format
|
5016 |
msgid "%s You need to renew your license to continue using premium features."
|
5017 |
msgstr ""
|
5018 |
|
5019 |
-
#: wp-security-audit-log.php:
|
5020 |
#, php-format
|
5021 |
msgid "The license is limited to %s sub-sites. You need to upgrade your license to cover all the sub-sites on this network."
|
5022 |
msgstr ""
|
5023 |
|
5024 |
-
#: wp-security-audit-log.php:
|
5025 |
msgid "Error: You do not have sufficient permissions to disable this custom field."
|
5026 |
msgstr ""
|
5027 |
|
5028 |
-
#: wp-security-audit-log.php:
|
5029 |
#, php-format
|
5030 |
msgid "Custom field %s is no longer being monitored."
|
5031 |
msgstr ""
|
5032 |
|
5033 |
-
#: wp-security-audit-log.php:
|
5034 |
#, php-format
|
5035 |
msgid "Enable the monitoring of this custom field again from the %s tab in the plugin settings."
|
5036 |
msgstr ""
|
5037 |
|
5038 |
-
#: wp-security-audit-log.php:
|
5039 |
msgid "Excluded Objects"
|
5040 |
msgstr ""
|
5041 |
|
5042 |
-
#: wp-security-audit-log.php:
|
5043 |
msgid "Error: You do not have sufficient permissions to disable this alert."
|
5044 |
msgstr ""
|
5045 |
|
5046 |
-
#: wp-security-audit-log.php:
|
5047 |
#, php-format
|
5048 |
msgid "Alert %1$s is no longer being monitored.<br /> %2$s"
|
5049 |
msgstr ""
|
5050 |
|
5051 |
-
#: wp-security-audit-log.php:
|
5052 |
msgid "You can enable this alert again from the Enable/Disable Alerts node in the plugin menu."
|
5053 |
msgstr ""
|
5054 |
|
5055 |
-
#: wp-security-audit-log.php:
|
5056 |
#, php-format
|
5057 |
msgid "You are using a version of PHP that is older than %s, which is no longer supported."
|
5058 |
msgstr ""
|
5059 |
|
5060 |
-
#: wp-security-audit-log.php:
|
5061 |
msgid "Contact us on <a href=\"mailto:plugins@wpwhitesecurity.com\">plugins@wpwhitesecurity.com</a> to help you switch the version of PHP you are using."
|
5062 |
msgstr ""
|
5063 |
|
5064 |
-
#: wp-security-audit-log.php:
|
5065 |
#, php-format
|
5066 |
msgid "Please install the %s plugin on the MainWP dashboard."
|
5067 |
msgstr ""
|
5068 |
|
5069 |
-
#: wp-security-audit-log.php:
|
5070 |
msgid "Activity Log for MainWP"
|
5071 |
msgstr ""
|
5072 |
|
5073 |
-
#: wp-security-audit-log.php:
|
5074 |
#, php-format
|
5075 |
msgid "The WP Activity Log should be installed on the child sites only. Refer to the %s for more information."
|
5076 |
msgstr ""
|
5077 |
|
5078 |
-
#: wp-security-audit-log.php:
|
5079 |
msgid "getting started guide"
|
5080 |
msgstr ""
|
5081 |
|
5082 |
-
#: wp-security-audit-log.php:
|
5083 |
msgid "For security and auditing purposes, a record of all of your logged-in actions and changes within the WordPress dashboard will be recorded in an activity log with the <a href=\"https://wpactivitylog.com/\" target=\"_blank\">WP Activity Log plugin</a>. The audit log also includes the IP address where you accessed this site from."
|
5084 |
msgstr ""
|
5085 |
|
5086 |
-
#: wp-security-audit-log.php:
|
5087 |
msgid "Every 6 hours"
|
5088 |
msgstr ""
|
5089 |
|
5090 |
-
#: wp-security-audit-log.php:
|
5091 |
msgid "Every 45 minutes"
|
5092 |
msgstr ""
|
5093 |
|
5094 |
-
#: wp-security-audit-log.php:
|
5095 |
msgid "Every 30 minutes"
|
5096 |
msgstr ""
|
5097 |
|
5098 |
-
#: wp-security-audit-log.php:
|
5099 |
msgid "Every 15 minutes"
|
5100 |
msgstr ""
|
5101 |
|
5102 |
-
#: wp-security-audit-log.php:
|
5103 |
msgid "Every 10 minutes"
|
5104 |
msgstr ""
|
5105 |
|
5106 |
-
#: wp-security-audit-log.php:
|
5107 |
msgid "Every 1 minute"
|
5108 |
msgstr ""
|
5109 |
|
5110 |
-
#: wp-security-audit-log.php:
|
5111 |
#, php-format
|
5112 |
msgid "Method %1$s is deprecated since version %2$s!"
|
5113 |
msgstr ""
|
27 |
msgid "Exclude custom field from the monitoring"
|
28 |
msgstr ""
|
29 |
|
30 |
+
#: classes/AlertFormatter.php:104
|
31 |
msgid "unknown"
|
32 |
msgstr ""
|
33 |
|
34 |
+
#: classes/AlertFormatter.php:151
|
35 |
msgid "Download the log file."
|
36 |
msgstr ""
|
37 |
|
38 |
+
#: classes/AlertFormatter.php:159
|
39 |
msgid "published"
|
40 |
msgstr ""
|
41 |
|
42 |
+
#: classes/AlertManager.php:362
|
43 |
#, php-format
|
44 |
msgid "Event with code %d has not be registered."
|
45 |
msgstr ""
|
46 |
|
47 |
+
#: classes/AlertManager.php:445
|
48 |
#, php-format
|
49 |
msgid "Event %s already registered with WP Activity Log."
|
50 |
msgstr ""
|
51 |
|
52 |
+
#: classes/AlertManager.php:490
|
53 |
msgid "You have custom events that are using the same ID or IDs which are already registered in the plugin, so they have been disabled."
|
54 |
msgstr ""
|
55 |
|
56 |
+
#: classes/AlertManager.php:493
|
57 |
#, php-format
|
58 |
msgid "%4$s to help you solve this issue."
|
59 |
msgstr ""
|
60 |
|
61 |
+
#: classes/AlertManager.php:495
|
62 |
msgid "ERROR:"
|
63 |
msgstr ""
|
64 |
|
65 |
+
#: classes/AlertManager.php:497
|
66 |
msgid "Contact us"
|
67 |
msgstr ""
|
68 |
|
69 |
+
#: classes/AlertManager.php:1006 classes/AuditLogListView.php:272
|
70 |
#: classes/AuditLogListView.php:306 classes/Views/Settings.php:1086
|
71 |
#: classes/WidgetManager.php:76 defaults.php:1706
|
72 |
msgid "User"
|
73 |
msgstr ""
|
74 |
|
75 |
+
#: classes/AlertManager.php:1007 classes/AlertManager.php:1373
|
76 |
+
#: classes/AuditLogGridView.php:435 classes/AuditLogListView.php:442
|
77 |
+
#: defaults.php:2336
|
78 |
msgid "System"
|
79 |
msgstr ""
|
80 |
|
81 |
+
#: classes/AlertManager.php:1008 classes/AuditLogGridView.php:426
|
82 |
+
#: classes/AuditLogListView.php:436 defaults.php:2180 defaults.php:2195
|
83 |
msgid "Plugin"
|
84 |
msgstr ""
|
85 |
|
86 |
+
#: classes/AlertManager.php:1009
|
87 |
msgid "Database"
|
88 |
msgstr ""
|
89 |
|
90 |
+
#: classes/AlertManager.php:1010 defaults.php:932
|
91 |
msgid "Post"
|
92 |
msgstr ""
|
93 |
|
94 |
+
#: classes/AlertManager.php:1011 classes/AlertManager.php:1015
|
95 |
msgid "File"
|
96 |
msgstr ""
|
97 |
|
98 |
+
#: classes/AlertManager.php:1012
|
99 |
msgid "Tag"
|
100 |
msgstr ""
|
101 |
|
102 |
+
#: classes/AlertManager.php:1013 defaults.php:79
|
103 |
msgid "Comment"
|
104 |
msgstr ""
|
105 |
|
106 |
+
#: classes/AlertManager.php:1014
|
107 |
msgid "Setting"
|
108 |
msgstr ""
|
109 |
|
110 |
+
#: classes/AlertManager.php:1016
|
111 |
msgid "System Setting"
|
112 |
msgstr ""
|
113 |
|
114 |
+
#: classes/AlertManager.php:1017
|
115 |
msgid "MainWP Network"
|
116 |
msgstr ""
|
117 |
|
118 |
+
#: classes/AlertManager.php:1018
|
119 |
msgid "MainWP"
|
120 |
msgstr ""
|
121 |
|
122 |
+
#: classes/AlertManager.php:1019
|
123 |
msgid "Category"
|
124 |
msgstr ""
|
125 |
|
126 |
+
#: classes/AlertManager.php:1020
|
127 |
msgid "Custom Field"
|
128 |
msgstr ""
|
129 |
|
130 |
+
#: classes/AlertManager.php:1021
|
131 |
msgid "Widget"
|
132 |
msgstr ""
|
133 |
|
134 |
+
#: classes/AlertManager.php:1022
|
135 |
msgid "Menu"
|
136 |
msgstr ""
|
137 |
|
138 |
+
#: classes/AlertManager.php:1023
|
139 |
msgid "Theme"
|
140 |
msgstr ""
|
141 |
|
142 |
+
#: classes/AlertManager.php:1024
|
143 |
msgid "Activity log"
|
144 |
msgstr ""
|
145 |
|
146 |
+
#: classes/AlertManager.php:1025
|
147 |
msgid "WP Activity Log"
|
148 |
msgstr ""
|
149 |
|
150 |
+
#: classes/AlertManager.php:1026
|
151 |
msgid "Multisite Network"
|
152 |
msgstr ""
|
153 |
|
154 |
+
#: classes/AlertManager.php:1027
|
155 |
msgid "IP Address"
|
156 |
msgstr ""
|
157 |
|
158 |
+
#: classes/AlertManager.php:1043
|
159 |
msgid "unknown object"
|
160 |
msgstr ""
|
161 |
|
162 |
+
#: classes/AlertManager.php:1080
|
163 |
msgid "Login"
|
164 |
msgstr ""
|
165 |
|
166 |
+
#: classes/AlertManager.php:1081
|
167 |
msgid "Logout"
|
168 |
msgstr ""
|
169 |
|
170 |
+
#: classes/AlertManager.php:1082
|
171 |
msgid "Installed"
|
172 |
msgstr ""
|
173 |
|
174 |
+
#: classes/AlertManager.php:1083
|
175 |
msgid "Activated"
|
176 |
msgstr ""
|
177 |
|
178 |
+
#: classes/AlertManager.php:1084
|
179 |
msgid "Deactivated"
|
180 |
msgstr ""
|
181 |
|
182 |
+
#: classes/AlertManager.php:1085
|
183 |
msgid "Uninstalled"
|
184 |
msgstr ""
|
185 |
|
186 |
+
#: classes/AlertManager.php:1086
|
187 |
msgid "Updated"
|
188 |
msgstr ""
|
189 |
|
190 |
+
#: classes/AlertManager.php:1087
|
191 |
msgid "Created"
|
192 |
msgstr ""
|
193 |
|
194 |
+
#: classes/AlertManager.php:1088
|
195 |
msgid "Modified"
|
196 |
msgstr ""
|
197 |
|
198 |
+
#: classes/AlertManager.php:1089
|
199 |
msgid "Deleted"
|
200 |
msgstr ""
|
201 |
|
202 |
+
#: classes/AlertManager.php:1090
|
203 |
msgid "Published"
|
204 |
msgstr ""
|
205 |
|
206 |
+
#: classes/AlertManager.php:1091
|
207 |
msgid "Approved"
|
208 |
msgstr ""
|
209 |
|
210 |
+
#: classes/AlertManager.php:1092
|
211 |
msgid "Unapproved"
|
212 |
msgstr ""
|
213 |
|
214 |
+
#: classes/AlertManager.php:1093
|
215 |
msgid "Enabled"
|
216 |
msgstr ""
|
217 |
|
218 |
+
#: classes/AlertManager.php:1094
|
219 |
msgid "Disabled"
|
220 |
msgstr ""
|
221 |
|
222 |
+
#: classes/AlertManager.php:1095
|
223 |
msgid "Added"
|
224 |
msgstr ""
|
225 |
|
226 |
+
#: classes/AlertManager.php:1096
|
227 |
msgid "Failed Login"
|
228 |
msgstr ""
|
229 |
|
230 |
+
#: classes/AlertManager.php:1097
|
231 |
msgid "Blocked"
|
232 |
msgstr ""
|
233 |
|
234 |
+
#: classes/AlertManager.php:1098
|
235 |
msgid "Uploaded"
|
236 |
msgstr ""
|
237 |
|
238 |
+
#: classes/AlertManager.php:1099
|
239 |
msgid "Restored"
|
240 |
msgstr ""
|
241 |
|
242 |
+
#: classes/AlertManager.php:1100
|
243 |
msgid "Opened"
|
244 |
msgstr ""
|
245 |
|
246 |
+
#: classes/AlertManager.php:1101
|
247 |
msgid "Viewed"
|
248 |
msgstr ""
|
249 |
|
250 |
+
#: classes/AlertManager.php:1102
|
251 |
msgid "Started"
|
252 |
msgstr ""
|
253 |
|
254 |
+
#: classes/AlertManager.php:1103
|
255 |
msgid "Stopped"
|
256 |
msgstr ""
|
257 |
|
258 |
+
#: classes/AlertManager.php:1104
|
259 |
msgid "Removed"
|
260 |
msgstr ""
|
261 |
|
262 |
+
#: classes/AlertManager.php:1105
|
263 |
msgid "Unblocked"
|
264 |
msgstr ""
|
265 |
|
266 |
+
#: classes/AlertManager.php:1106
|
267 |
msgid "Renamed"
|
268 |
msgstr ""
|
269 |
|
270 |
+
#: classes/AlertManager.php:1107
|
271 |
msgid "Duplicated"
|
272 |
msgstr ""
|
273 |
|
274 |
+
#: classes/AlertManager.php:1108
|
275 |
msgid "Submitted"
|
276 |
msgstr ""
|
277 |
|
278 |
+
#: classes/AlertManager.php:1109
|
279 |
msgid "Revoked"
|
280 |
msgstr ""
|
281 |
|
282 |
+
#: classes/AlertManager.php:1126
|
283 |
msgid "unknown type"
|
284 |
msgstr ""
|
285 |
|
286 |
+
#: classes/AlertManager.php:1176 classes/Views/ToggleAlerts.php:282
|
287 |
+
#: defaults.php:1508
|
288 |
msgid "Pages"
|
289 |
msgstr ""
|
290 |
|
291 |
+
#: classes/AlertManager.php:1176 classes/Views/ToggleAlerts.php:282
|
292 |
+
#: defaults.php:1323
|
293 |
msgid "Custom Post Types"
|
294 |
msgstr ""
|
295 |
|
296 |
+
#: classes/AlertManager.php:1273
|
297 |
msgid "System Activity"
|
298 |
msgstr ""
|
299 |
|
300 |
+
#: classes/AlertManager.php:1346 classes/ConstantManager.php:147
|
301 |
msgid "Unknown error code."
|
302 |
msgstr ""
|
303 |
|
304 |
+
#: classes/AlertManager.php:1417 classes/AlertManager.php:1429
|
305 |
msgid "Unknown Site"
|
306 |
msgstr ""
|
307 |
|
330 |
msgstr ""
|
331 |
|
332 |
#: classes/AuditLogGridView.php:211 classes/AuditLogListView.php:209
|
333 |
+
#: classes/Views/AuditLog.php:593
|
334 |
msgid "All Sites"
|
335 |
msgstr ""
|
336 |
|
342 |
|
343 |
#: classes/AuditLogGridView.php:272 classes/AuditLogGridView.php:298
|
344 |
#: classes/AuditLogListView.php:270 classes/AuditLogListView.php:300
|
345 |
+
#: classes/Views/Settings.php:1082 classes/Views/ToggleAlerts.php:216
|
346 |
+
#: classes/Views/ToggleAlerts.php:256
|
347 |
msgid "Severity"
|
348 |
msgstr ""
|
349 |
|
374 |
msgstr ""
|
375 |
|
376 |
#: classes/AuditLogGridView.php:401 classes/AuditLogGridView.php:405
|
377 |
+
#: classes/AuditLogListView.php:413 classes/Utilities/UserUtils.php:170
|
378 |
msgid "Unknown"
|
379 |
msgstr ""
|
380 |
|
381 |
+
#: classes/AuditLogGridView.php:429 classes/AuditLogListView.php:438
|
382 |
+
#: defaults.php:2105
|
383 |
msgid "Plugins"
|
384 |
msgstr ""
|
385 |
|
386 |
+
#: classes/AuditLogGridView.php:432 classes/AuditLogListView.php:440
|
387 |
msgid "Unregistered user"
|
388 |
msgstr ""
|
389 |
|
390 |
+
#: classes/AuditLogGridView.php:469 classes/AuditLogGridView.php:482
|
391 |
#: classes/AuditLogListView.php:473 classes/AuditLogListView.php:486
|
392 |
msgid "Show me all activity originating from this IP Address"
|
393 |
msgstr ""
|
394 |
|
395 |
+
#: classes/AuditLogGridView.php:511
|
396 |
msgid "Date:"
|
397 |
msgstr ""
|
398 |
|
399 |
+
#: classes/AuditLogGridView.php:515
|
400 |
msgid "Time:"
|
401 |
msgstr ""
|
402 |
|
403 |
+
#: classes/AuditLogGridView.php:519
|
404 |
msgid "User:"
|
405 |
msgstr ""
|
406 |
|
407 |
+
#: classes/AuditLogGridView.php:523
|
408 |
msgid "IP:"
|
409 |
msgstr ""
|
410 |
|
411 |
+
#: classes/AuditLogGridView.php:527
|
412 |
msgid "Object:"
|
413 |
msgstr ""
|
414 |
|
415 |
+
#: classes/AuditLogGridView.php:531
|
416 |
msgid "Event Type:"
|
417 |
msgstr ""
|
418 |
|
419 |
+
#: classes/AuditLogGridView.php:539 classes/AuditLogListView.php:518
|
420 |
msgid "View all details of this change"
|
421 |
msgstr ""
|
422 |
|
423 |
+
#: classes/AuditLogGridView.php:540 classes/AuditLogListView.php:519
|
424 |
msgid "Alert Data Inspector"
|
425 |
msgstr ""
|
426 |
|
427 |
+
#: classes/AuditLogGridView.php:700 classes/AuditLogListView.php:683
|
428 |
msgid "Select All"
|
429 |
msgstr ""
|
430 |
|
446 |
msgid "Event Type"
|
447 |
msgstr ""
|
448 |
|
449 |
+
#: classes/AuditLogListView.php:382 classes/Models/Occurrence.php:185
|
450 |
msgid "Alert message not found."
|
451 |
msgstr ""
|
452 |
|
453 |
+
#: classes/AuditLogListView.php:383 classes/Models/Occurrence.php:186
|
454 |
msgid "Alert description not found."
|
455 |
msgstr ""
|
456 |
|
464 |
msgstr ""
|
465 |
|
466 |
#: classes/ConstantManager.php:159 classes/ConstantManager.php:165
|
467 |
+
#: classes/Views/ToggleAlerts.php:352 classes/Views/ToggleAlerts.php:358
|
468 |
msgid "Critical"
|
469 |
msgstr ""
|
470 |
|
471 |
+
#: classes/ConstantManager.php:161 classes/Views/ToggleAlerts.php:354
|
472 |
msgid "Warning"
|
473 |
msgstr ""
|
474 |
|
475 |
+
#: classes/ConstantManager.php:163 classes/Views/ToggleAlerts.php:356
|
476 |
+
#: classes/Views/ToggleAlerts.php:368
|
477 |
msgid "Notification"
|
478 |
msgstr ""
|
479 |
|
480 |
+
#: classes/ConstantManager.php:167 classes/Views/ToggleAlerts.php:360
|
481 |
msgid "High"
|
482 |
msgstr ""
|
483 |
|
484 |
+
#: classes/ConstantManager.php:169 classes/Views/ToggleAlerts.php:362
|
485 |
msgid "Medium"
|
486 |
msgstr ""
|
487 |
|
488 |
+
#: classes/ConstantManager.php:171 classes/Views/ToggleAlerts.php:364
|
489 |
msgid "Low"
|
490 |
msgstr ""
|
491 |
|
492 |
+
#: classes/ConstantManager.php:173 classes/Views/ToggleAlerts.php:366
|
493 |
msgid "Informational"
|
494 |
msgstr ""
|
495 |
|
496 |
+
#: classes/Models/Occurrence.php:350
|
|
|
|
|
|
|
|
|
497 |
#, php-format
|
498 |
msgid "This type of activity / change is no longer monitored. You can create your own custom event IDs to keep a log of such change. Read more about custom events %1$shere%2$s."
|
499 |
msgstr ""
|
500 |
|
501 |
+
#: classes/Sensors/Content.php:755
|
502 |
msgid "Default template"
|
503 |
msgstr ""
|
504 |
|
505 |
+
#: classes/Sensors/Content.php:756
|
506 |
msgid "Default"
|
507 |
msgstr ""
|
508 |
|
509 |
+
#: classes/Sensors/Content.php:797
|
510 |
msgid "No previous image"
|
511 |
msgstr ""
|
512 |
|
513 |
+
#: classes/Sensors/Content.php:798
|
514 |
msgid "No image"
|
515 |
msgstr ""
|
516 |
|
517 |
+
#: classes/Sensors/Content.php:1152 classes/Sensors/Content.php:1160
|
518 |
msgid "Password Protected"
|
519 |
msgstr ""
|
520 |
|
521 |
+
#: classes/Sensors/Content.php:1154 classes/Sensors/Content.php:1162
|
522 |
msgid "Private"
|
523 |
msgstr ""
|
524 |
|
525 |
+
#: classes/Sensors/Content.php:1156 classes/Sensors/Content.php:1164
|
526 |
msgid "Public"
|
527 |
msgstr ""
|
528 |
|
529 |
+
#: classes/Sensors/Content.php:1327
|
530 |
msgid "no tags"
|
531 |
msgstr ""
|
532 |
|
533 |
+
#: classes/Sensors/Multisite.php:81
|
534 |
msgid "disabled"
|
535 |
msgstr ""
|
536 |
|
537 |
+
#: classes/Sensors/Multisite.php:82
|
538 |
msgid "user accounts only"
|
539 |
msgstr ""
|
540 |
|
541 |
+
#: classes/Sensors/Multisite.php:83
|
542 |
msgid "users can register new sites"
|
543 |
msgstr ""
|
544 |
|
545 |
+
#: classes/Sensors/Multisite.php:84
|
546 |
msgid "sites & users can be registered"
|
547 |
msgstr ""
|
548 |
|
566 |
msgid "This function is deprecated"
|
567 |
msgstr ""
|
568 |
|
569 |
+
#: classes/Settings.php:1919
|
570 |
msgid "Root directory of WordPress (excluding sub directories)"
|
571 |
msgstr ""
|
572 |
|
573 |
+
#: classes/Settings.php:1920
|
574 |
msgid "WP Admin directory (/wp-admin/)"
|
575 |
msgstr ""
|
576 |
|
577 |
+
#: classes/Settings.php:1921
|
578 |
msgid "WP Includes directory (/wp-includes/)"
|
579 |
msgstr ""
|
580 |
|
581 |
+
#: classes/Settings.php:1922
|
582 |
msgid "/wp-content/ directory (excluding plugins, themes & uploads directories)"
|
583 |
msgstr ""
|
584 |
|
585 |
+
#: classes/Settings.php:1923
|
586 |
msgid "Themes directory (/wp-content/themes/)"
|
587 |
msgstr ""
|
588 |
|
589 |
+
#: classes/Settings.php:1924
|
590 |
msgid "Plugins directory (/wp-content/plugins/)"
|
591 |
msgstr ""
|
592 |
|
593 |
+
#: classes/Settings.php:1925
|
594 |
msgid "Uploads directory (/wp-content/uploads/)"
|
595 |
msgstr ""
|
596 |
|
597 |
+
#: classes/Settings.php:1930
|
598 |
msgid "Uploads directory of all sub sites on this network (/wp-content/sites/*)"
|
599 |
msgstr ""
|
600 |
|
601 |
+
#: classes/Settings.php:2082
|
602 |
msgid "None provided"
|
603 |
msgstr ""
|
604 |
|
606 |
msgid "Keep a record of when someone adds, modifies or deletes forms, entries and more in the Gravity Forms plugin."
|
607 |
msgstr ""
|
608 |
|
609 |
+
#: classes/Upgrade/MetadataMigration.php:65
|
610 |
+
msgid "Activity log database update in progress."
|
611 |
+
msgstr ""
|
612 |
+
|
613 |
+
#: classes/Upgrade/MetadataMigration.php:67
|
614 |
+
msgid "WP Activity Log is updating the database tables where it stores the activity log. This is needed to upgrade the activity log tables to the new database schema, so the logs can be stored and read more efficiently. The duration of this process varies, depending on the number of events in the activity log. This process runs in the background and won't affect your website. During the upgrade, you might notice some \"null\" values in the activity log. This is temporary until the process is complete."
|
615 |
+
msgstr ""
|
616 |
+
|
617 |
#: classes/Utilities/Emailer.php:54
|
618 |
#, php-format
|
619 |
msgid "WP Activity Log plugin disabled on %s"
|
633 |
msgstr ""
|
634 |
|
635 |
#: classes/Utilities/PluginInstallAndActivate.php:101
|
636 |
+
#: classes/Views/SetupWizard.php:835
|
637 |
msgid "Extension for "
|
638 |
msgstr ""
|
639 |
|
640 |
#: classes/Utilities/PluginInstallAndActivate.php:106
|
641 |
+
#: classes/Views/SetupWizard.php:840
|
642 |
msgid "Extension installed, activate now?"
|
643 |
msgstr ""
|
644 |
|
645 |
#: classes/Utilities/PluginInstallAndActivate.php:108
|
646 |
+
#: classes/Views/SetupWizard.php:272 classes/Views/SetupWizard.php:842
|
647 |
+
#: wp-security-audit-log.php:1195
|
648 |
msgid "Extension installed"
|
649 |
msgstr ""
|
650 |
|
651 |
#: classes/Utilities/PluginInstallAndActivate.php:110
|
652 |
+
#: classes/Views/SetupWizard.php:844
|
653 |
msgid "Install Extension"
|
654 |
msgstr ""
|
655 |
|
656 |
+
#: classes/Utilities/PluginInstallerAction.php:86
|
657 |
msgid "Tried to install a zip or slug that was not in the allowed list"
|
658 |
msgstr ""
|
659 |
|
660 |
+
#: classes/Utilities/UserUtils.php:98
|
661 |
msgid "Username: "
|
662 |
msgstr ""
|
663 |
|
664 |
+
#: classes/Utilities/UserUtils.php:99
|
665 |
msgid "First name: "
|
666 |
msgstr ""
|
667 |
|
668 |
+
#: classes/Utilities/UserUtils.php:100
|
669 |
msgid "Last Name: "
|
670 |
msgstr ""
|
671 |
|
672 |
+
#: classes/Utilities/UserUtils.php:101
|
673 |
msgid "Email: "
|
674 |
msgstr ""
|
675 |
|
676 |
+
#: classes/Utilities/UserUtils.php:102
|
677 |
msgid "Nickname: "
|
678 |
msgstr ""
|
679 |
|
680 |
+
#: classes/ViewManager.php:138
|
681 |
msgid "WP Activity Log requires Website File Changes Monitor 1.6.0. Please upgrade that plugin."
|
682 |
msgstr ""
|
683 |
|
684 |
+
#: classes/ViewManager.php:280
|
685 |
msgid "Free Premium Trial"
|
686 |
msgstr ""
|
687 |
|
688 |
+
#: classes/Views/AuditLog.php:99
|
689 |
msgid "Get email notifications about website changes, view logged-in users, do granular log searches, create detailed reports, and more."
|
690 |
msgstr ""
|
691 |
|
692 |
+
#: classes/Views/AuditLog.php:100
|
693 |
msgid "Upgrade to premium today and get more out of your activity logs!"
|
694 |
msgstr ""
|
695 |
|
696 |
+
#: classes/Views/AuditLog.php:103
|
697 |
msgid "Instant SMS & email alerts, search & filters, reports, users sessions management and much more!"
|
698 |
msgstr ""
|
699 |
|
700 |
+
#: classes/Views/AuditLog.php:104
|
701 |
msgid "Upgrade to premium to get more out of your activity logs!"
|
702 |
msgstr ""
|
703 |
|
704 |
+
#: classes/Views/AuditLog.php:107
|
705 |
msgid "See who logged in on your site in real-time, generate reports, get SMS & email alerts of critical changes and more!"
|
706 |
msgstr ""
|
707 |
|
708 |
+
#: classes/Views/AuditLog.php:108
|
709 |
msgid "Unlock these and other powerful features with WP Activity Log Premium."
|
710 |
msgstr ""
|
711 |
|
712 |
+
#: classes/Views/AuditLog.php:159
|
713 |
msgid "Learn more"
|
714 |
msgstr ""
|
715 |
|
749 |
msgid "No, thank you"
|
750 |
msgstr ""
|
751 |
|
752 |
+
#: classes/Views/AuditLog.php:276
|
753 |
msgid "We noticed you have"
|
754 |
msgstr ""
|
755 |
|
756 |
+
#: classes/Views/AuditLog.php:278
|
757 |
msgid "installed."
|
758 |
msgstr ""
|
759 |
|
760 |
+
#: classes/Views/AuditLog.php:280
|
761 |
msgid "Install extension"
|
762 |
msgstr ""
|
763 |
|
764 |
+
#: classes/Views/AuditLog.php:325
|
765 |
msgid "Activity Log Viewer"
|
766 |
msgstr ""
|
767 |
|
768 |
+
#: classes/Views/AuditLog.php:352
|
769 |
msgid "Log Viewer"
|
770 |
msgstr ""
|
771 |
|
772 |
+
#: classes/Views/AuditLog.php:509 classes/Views/Settings.php:324
|
773 |
+
#: classes/Views/ToggleAlerts.php:112
|
774 |
msgid "You do not have sufficient permissions to access this page."
|
775 |
msgstr ""
|
776 |
|
777 |
+
#: classes/Views/AuditLog.php:558
|
778 |
msgid "Thank you for installing WP Activity Log. Do you want to run the wizard to configure the basic plugin settings?"
|
779 |
msgstr ""
|
780 |
|
781 |
+
#: classes/Views/AuditLog.php:560 classes/Views/Settings.php:532
|
782 |
#: classes/Views/Settings.php:559 classes/Views/Settings.php:625
|
783 |
#: classes/Views/Settings.php:683 classes/Views/Settings.php:1118
|
784 |
+
#: classes/Views/Settings.php:1402 classes/Views/Settings.php:1446
|
785 |
+
#: classes/Views/Settings.php:1467 classes/Views/Settings.php:1477
|
786 |
+
#: classes/Views/SetupWizard.php:563
|
787 |
msgid "Yes"
|
788 |
msgstr ""
|
789 |
|
790 |
+
#: classes/Views/AuditLog.php:561 classes/Views/Settings.php:537
|
791 |
#: classes/Views/Settings.php:564 classes/Views/Settings.php:655
|
792 |
#: classes/Views/Settings.php:693 classes/Views/Settings.php:1123
|
793 |
+
#: classes/Views/Settings.php:1409 classes/Views/Settings.php:1453
|
794 |
+
#: classes/Views/Settings.php:1468 classes/Views/Settings.php:1478
|
795 |
+
#: classes/Views/SetupWizard.php:568
|
796 |
msgid "No"
|
797 |
msgstr ""
|
798 |
|
799 |
+
#: classes/Views/AuditLog.php:592
|
800 |
msgid "Please enter the number of alerts you would like to see on one page:"
|
801 |
msgstr ""
|
802 |
|
803 |
+
#: classes/Views/AuditLog.php:594
|
804 |
msgid "No Results"
|
805 |
msgstr ""
|
806 |
|
807 |
+
#: classes/Views/AuditLog.php:731 classes/Views/AuditLog.php:774
|
808 |
+
#: classes/Views/AuditLog.php:1052 classes/Views/AuditLog.php:1114
|
809 |
+
#: classes/Views/AuditLog.php:1167 classes/Views/Settings.php:239
|
810 |
+
#: classes/Views/Settings.php:1778 classes/Views/SetupWizard.php:96
|
811 |
msgid "Nonce verification failed."
|
812 |
msgstr ""
|
813 |
|
814 |
+
#: classes/Views/AuditLog.php:749
|
815 |
msgid "No users found."
|
816 |
msgstr ""
|
817 |
|
818 |
+
#: classes/Views/AuditLog.php:814
|
819 |
msgid "Freemius opt choice selected."
|
820 |
msgstr ""
|
821 |
|
822 |
+
#: classes/Views/AuditLog.php:821
|
823 |
msgid "Freemius opt choice not found."
|
824 |
msgstr ""
|
825 |
|
826 |
+
#: classes/Views/AuditLog.php:917
|
827 |
#, php-format
|
828 |
msgid "<br>An error occurred when trying to install and activate the plugin. Please try install it again from the %1$sevent settings%2$s page."
|
829 |
msgstr ""
|
830 |
|
831 |
+
#: classes/Views/AuditLog.php:1016
|
832 |
msgid "WordPress Activity Log"
|
833 |
msgstr ""
|
834 |
|
835 |
+
#: classes/Views/AuditLog.php:1017
|
836 |
msgid "When a user makes a change on your website the plugin will keep a record of that event here. Right now there is nothing because this is a new install."
|
837 |
msgstr ""
|
838 |
|
839 |
+
#: classes/Views/AuditLog.php:1018
|
840 |
msgid "Thank you for using WP Activity Log"
|
841 |
msgstr ""
|
842 |
|
843 |
+
#: classes/Views/AuditLog.php:1041 classes/Views/AuditLog.php:1151
|
844 |
msgid "You do not have sufficient permissions to dismiss this notice."
|
845 |
msgstr ""
|
846 |
|
847 |
+
#: classes/Views/AuditLog.php:1109
|
848 |
msgid "Access Denied"
|
849 |
msgstr ""
|
850 |
|
851 |
+
#: classes/Views/AuditLog.php:1215
|
852 |
#, php-format
|
853 |
msgid "Install the activity log extension for %1$s for more detailed logging of changes done in %2$s."
|
854 |
msgstr ""
|
858 |
msgstr ""
|
859 |
|
860 |
#: classes/Views/EmailNotifications.php:35
|
861 |
+
msgid "Email Notifications ⇪"
|
862 |
msgstr ""
|
863 |
|
864 |
#: classes/Views/EmailNotifications.php:49
|
1054 |
msgstr ""
|
1055 |
|
1056 |
#: classes/Views/Help.php:282
|
1057 |
+
msgid "Add an extra layer of security to your login pages with 2FA & require your users to use it."
|
1058 |
msgstr ""
|
1059 |
|
1060 |
#: classes/Views/Help.php:288
|
1061 |
+
msgid "Protect website forms & login pages from spambots & automated attacks."
|
1062 |
msgstr ""
|
1063 |
|
1064 |
#: classes/Views/Help.php:294
|
1065 |
+
msgid "Enforce strong password policies on WordPress"
|
1066 |
msgstr ""
|
1067 |
|
1068 |
#: classes/Views/Help.php:300
|
1069 |
+
msgid "Automatically identify unauthorized file changes on WordPress"
|
1070 |
msgstr ""
|
1071 |
|
1072 |
#: classes/Views/Help.php:306
|
1073 |
+
msgid "See the child sites activity logs from the central MainWP dashboard"
|
1074 |
+
msgstr ""
|
1075 |
+
|
1076 |
+
#: classes/Views/Help.php:312
|
1077 |
msgid "Our other WordPress plugins"
|
1078 |
msgstr ""
|
1079 |
|
1080 |
+
#: classes/Views/Help.php:323
|
1081 |
msgid "LEARN MORE"
|
1082 |
msgstr ""
|
1083 |
|
1134 |
msgstr ""
|
1135 |
|
1136 |
#: classes/Views/Reports.php:35
|
1137 |
+
msgid "Create Reports ⇪"
|
1138 |
msgstr ""
|
1139 |
|
1140 |
#: classes/Views/Reports.php:49
|
1182 |
msgstr ""
|
1183 |
|
1184 |
#: classes/Views/Search.php:35
|
1185 |
+
msgid "Log Search ⇪"
|
1186 |
msgstr ""
|
1187 |
|
1188 |
#: classes/Views/Search.php:49
|
1257 |
msgid "Unknown settings tab."
|
1258 |
msgstr ""
|
1259 |
|
1260 |
+
#: classes/Views/Settings.php:224 classes/Views/Settings.php:1788
|
1261 |
+
#: classes/Views/Settings.php:1811 classes/Views/SetupWizard.php:83
|
1262 |
msgid "Access Denied."
|
1263 |
msgstr ""
|
1264 |
|
1270 |
msgid "Message sent successfully."
|
1271 |
msgstr ""
|
1272 |
|
1273 |
+
#: classes/Views/Settings.php:340 classes/Views/ToggleAlerts.php:124
|
1274 |
msgid "Settings have been saved."
|
1275 |
msgstr ""
|
1276 |
|
1277 |
+
#: classes/Views/Settings.php:346 classes/Views/ToggleAlerts.php:130
|
1278 |
msgid "Error: "
|
1279 |
msgstr ""
|
1280 |
|
1492 |
#: classes/Views/Settings.php:834 classes/Views/Settings.php:1217
|
1493 |
#: classes/Views/Settings.php:1238 classes/Views/Settings.php:1259
|
1494 |
#: classes/Views/Settings.php:1281 classes/Views/Settings.php:1329
|
1495 |
+
#: classes/Views/Settings.php:1586
|
1496 |
msgid "Remove"
|
1497 |
msgstr ""
|
1498 |
|
1648 |
msgid "Enable Events for WordPress Background Activity"
|
1649 |
msgstr ""
|
1650 |
|
1651 |
+
#: classes/Views/Settings.php:1172
|
1652 |
msgid "Website File Changes Monitor"
|
1653 |
msgstr ""
|
1654 |
|
1655 |
+
#: classes/Views/Settings.php:1173
|
1656 |
msgid "To keep a log of file changes please install Website File Changes Monitor, a plugin which is also developed by us."
|
1657 |
msgstr ""
|
1658 |
|
1659 |
+
#: classes/Views/Settings.php:1174
|
1660 |
msgid "Install plugin now"
|
1661 |
msgstr ""
|
1662 |
|
1663 |
+
#: classes/Views/Settings.php:1174
|
1664 |
msgid "Learn More"
|
1665 |
msgstr ""
|
1666 |
|
1764 |
msgid "Enable MainWP Child Site Stealth Mode"
|
1765 |
msgstr ""
|
1766 |
|
1767 |
+
#: classes/Views/Settings.php:1418
|
1768 |
msgid "Admin blocking plugins support"
|
1769 |
msgstr ""
|
1770 |
|
1771 |
+
#: classes/Views/Settings.php:1425
|
1772 |
msgid "Enable early plugin loading on sites that use admin blocking plugins"
|
1773 |
msgstr ""
|
1774 |
|
1775 |
+
#: classes/Views/Settings.php:1434
|
1776 |
msgid "Do you want to delete the plugin data from the database upon uninstall?"
|
1777 |
msgstr ""
|
1778 |
|
1779 |
+
#: classes/Views/Settings.php:1435
|
1780 |
msgid "The plugin saves the activity log data and settings in the WordPress database. By default upon uninstalling the plugin the data is kept in the database so if it is installed again, you can still access the data. If the data is deleted it is not possible to recover it so you won't be able to access it again even when you reinstall the plugin."
|
1781 |
msgstr ""
|
1782 |
|
1783 |
+
#: classes/Views/Settings.php:1439
|
1784 |
msgid "Remove Data on Uninstall"
|
1785 |
msgstr ""
|
1786 |
|
1787 |
+
#: classes/Views/Settings.php:1464
|
1788 |
msgid "Are you sure you want to reset all the plugin settings to default? This action cannot be undone."
|
1789 |
msgstr ""
|
1790 |
|
1791 |
+
#: classes/Views/Settings.php:1474
|
1792 |
msgid "Are you sure you want to purge all the activity log data?"
|
1793 |
msgstr ""
|
1794 |
|
1795 |
+
#: classes/Views/Settings.php:1498
|
1796 |
msgid "MainWP Child plugin is not active on this website."
|
1797 |
msgstr ""
|
1798 |
|
1799 |
+
#: classes/Views/Settings.php:1579
|
1800 |
msgid "The specified value is not a valid URL!"
|
1801 |
msgstr ""
|
1802 |
|
1803 |
+
#: classes/Views/Settings.php:1580
|
1804 |
msgid "The specified value is not a valid post type!"
|
1805 |
msgstr ""
|
1806 |
|
1807 |
+
#: classes/Views/Settings.php:1581
|
1808 |
msgid "The specified value is not a valid IP address!"
|
1809 |
msgstr ""
|
1810 |
|
1811 |
+
#: classes/Views/Settings.php:1582
|
1812 |
msgid "The specified value is not a user nor a role!"
|
1813 |
msgstr ""
|
1814 |
|
1815 |
+
#: classes/Views/Settings.php:1583
|
1816 |
msgid "Filename cannot be added because it contains invalid characters."
|
1817 |
msgstr ""
|
1818 |
|
1819 |
+
#: classes/Views/Settings.php:1584
|
1820 |
msgid "File extension cannot be added because it contains invalid characters."
|
1821 |
msgstr ""
|
1822 |
|
1823 |
+
#: classes/Views/Settings.php:1585
|
1824 |
msgid "Directory cannot be added because it contains invalid characters."
|
1825 |
msgstr ""
|
1826 |
|
1827 |
+
#: classes/Views/Settings.php:1587
|
1828 |
msgid "Please save any changes before switching tabs."
|
1829 |
msgstr ""
|
1830 |
|
1831 |
+
#: classes/Views/Settings.php:1794 classes/Views/Settings.php:1817
|
1832 |
msgid "Nonce Verification Failed."
|
1833 |
msgstr ""
|
1834 |
|
1835 |
+
#: classes/Views/Settings.php:1802
|
1836 |
msgid "Plugin settings have been reset."
|
1837 |
msgstr ""
|
1838 |
|
1839 |
+
#: classes/Views/Settings.php:1826
|
1840 |
msgid "Tables has been reset."
|
1841 |
msgstr ""
|
1842 |
|
1843 |
+
#: classes/Views/Settings.php:1828
|
1844 |
msgid "Reset query failed."
|
1845 |
msgstr ""
|
1846 |
|
1847 |
+
#: classes/Views/Settings.php:1841
|
1848 |
msgid "Activity log retention"
|
1849 |
msgstr ""
|
1850 |
|
1851 |
+
#: classes/Views/Settings.php:1847
|
1852 |
msgid "Keep all data"
|
1853 |
msgstr ""
|
1854 |
|
1855 |
+
#: classes/Views/Settings.php:1863
|
1856 |
msgid "Days"
|
1857 |
msgstr ""
|
1858 |
|
1859 |
+
#: classes/Views/Settings.php:1864
|
1860 |
msgid "Months"
|
1861 |
msgstr ""
|
1862 |
|
1863 |
+
#: classes/Views/Settings.php:1865
|
1864 |
msgid "Years"
|
1865 |
msgstr ""
|
1866 |
|
1867 |
+
#: classes/Views/Settings.php:1880
|
1868 |
msgid "Delete events older than"
|
1869 |
msgstr ""
|
1870 |
|
1871 |
+
#: classes/Views/Settings.php:1898
|
1872 |
msgid "The next scheduled purging of activity log data that is older than "
|
1873 |
msgstr ""
|
1874 |
|
1875 |
+
#: classes/Views/Settings.php:1905
|
1876 |
msgid "You can run the purging process now by clicking the button below."
|
1877 |
msgstr ""
|
1878 |
|
1879 |
+
#: classes/Views/Settings.php:1909
|
1880 |
msgid "Purge Old Data"
|
1881 |
msgstr ""
|
1882 |
|
1900 |
msgid "Log Retention"
|
1901 |
msgstr ""
|
1902 |
|
1903 |
+
#: classes/Views/SetupWizard.php:202 classes/Views/SetupWizard.php:742
|
1904 |
+
#: classes/Views/SetupWizard.php:743
|
1905 |
msgid "Finish"
|
1906 |
msgstr ""
|
1907 |
|
1917 |
msgid "Specified value in not an IP address."
|
1918 |
msgstr ""
|
1919 |
|
1920 |
+
#: classes/Views/SetupWizard.php:270 wp-security-audit-log.php:1193
|
1921 |
msgid "Installing, please wait"
|
1922 |
msgstr ""
|
1923 |
|
1924 |
+
#: classes/Views/SetupWizard.php:271 wp-security-audit-log.php:1194
|
1925 |
msgid "Already installed"
|
1926 |
msgstr ""
|
1927 |
|
1928 |
+
#: classes/Views/SetupWizard.php:273 wp-security-audit-log.php:1196
|
1929 |
msgid "Extension activated"
|
1930 |
msgstr ""
|
1931 |
|
1932 |
+
#: classes/Views/SetupWizard.php:274 wp-security-audit-log.php:1197
|
1933 |
msgid "Install failed"
|
1934 |
msgstr ""
|
1935 |
|
1936 |
+
#: classes/Views/SetupWizard.php:275 wp-security-audit-log.php:1198
|
1937 |
+
msgid "Reloading page"
|
1938 |
+
msgstr ""
|
1939 |
+
|
1940 |
+
#: classes/Views/SetupWizard.php:305
|
1941 |
msgid "WP Activity Log › Setup Wizard"
|
1942 |
msgstr ""
|
1943 |
|
1944 |
+
#: classes/Views/SetupWizard.php:323
|
1945 |
msgid "Close Wizard"
|
1946 |
msgstr ""
|
1947 |
|
1948 |
+
#: classes/Views/SetupWizard.php:416
|
1949 |
#, php-format
|
1950 |
msgid "You have reached an invaild step - %1$sreturn to the start of the wizard%2$s."
|
1951 |
msgstr ""
|
1952 |
|
1953 |
+
#: classes/Views/SetupWizard.php:433
|
1954 |
msgid "This wizard helps you configure the basic plugin settings. All these settings can be changed at a later stage from the plugin settings."
|
1955 |
msgstr ""
|
1956 |
|
1957 |
+
#: classes/Views/SetupWizard.php:438
|
1958 |
msgid "Start Configuring the Plugin"
|
1959 |
msgstr ""
|
1960 |
|
1961 |
+
#: classes/Views/SetupWizard.php:442
|
1962 |
msgid "Exit Wizard"
|
1963 |
msgstr ""
|
1964 |
|
1965 |
+
#: classes/Views/SetupWizard.php:455
|
1966 |
msgid "Please select the level of detail for your WordPress activity logs:"
|
1967 |
msgstr ""
|
1968 |
|
1969 |
+
#: classes/Views/SetupWizard.php:459
|
1970 |
msgid "Basic (I want a high level overview and I am not interested in the detail)"
|
1971 |
msgstr ""
|
1972 |
|
1973 |
+
#: classes/Views/SetupWizard.php:464
|
1974 |
msgid "Geek (I want to know everything that is happening on my WordPress)"
|
1975 |
msgstr ""
|
1976 |
|
1977 |
+
#: classes/Views/SetupWizard.php:466
|
1978 |
msgid "Note: You can change the WordPress logging level from the plugin’s settings anytime."
|
1979 |
msgstr ""
|
1980 |
|
1981 |
+
#: classes/Views/SetupWizard.php:469 classes/Views/SetupWizard.php:526
|
1982 |
+
#: classes/Views/SetupWizard.php:575 classes/Views/SetupWizard.php:635
|
1983 |
+
#: classes/Views/SetupWizard.php:636 classes/Views/SetupWizard.php:857
|
1984 |
+
#: classes/Views/SetupWizard.php:858
|
1985 |
msgid "Next"
|
1986 |
msgstr ""
|
1987 |
|
1988 |
+
#: classes/Views/SetupWizard.php:510
|
1989 |
msgid "Do you or your users use other pages to log in to WordPress other than the default login page ( /wp-admin/ )?"
|
1990 |
msgstr ""
|
1991 |
|
1992 |
+
#: classes/Views/SetupWizard.php:514
|
1993 |
msgid "Yes, we use other pages to login to WordPress."
|
1994 |
msgstr ""
|
1995 |
|
1996 |
+
#: classes/Views/SetupWizard.php:519
|
1997 |
msgid "No, we only use the default WordPress login page."
|
1998 |
msgstr ""
|
1999 |
|
2000 |
+
#: classes/Views/SetupWizard.php:521
|
2001 |
msgid "If your website is a membership or ecommerce website most probably you have more than one area from where the users can login. If you are not sure, select Yes."
|
2002 |
msgstr ""
|
2003 |
|
2004 |
+
#: classes/Views/SetupWizard.php:524 classes/Views/SetupWizard.php:573
|
2005 |
+
#: classes/Views/SetupWizard.php:627
|
2006 |
msgid "Note: You can change the WordPress activity log retention settings at any time from the plugin settings later on."
|
2007 |
msgstr ""
|
2008 |
|
2009 |
+
#: classes/Views/SetupWizard.php:559
|
2010 |
msgid "Can visitors register as a user on your website?"
|
2011 |
msgstr ""
|
2012 |
|
2013 |
+
#: classes/Views/SetupWizard.php:570
|
2014 |
msgid "If you are not sure about this setting, check if the Membership setting in the WordPress General settings is checked or not. If it is not checked (default) select No."
|
2015 |
msgstr ""
|
2016 |
|
2017 |
+
#: classes/Views/SetupWizard.php:609
|
2018 |
msgid "How long do you want to keep the data in the WordPress activity Log?"
|
2019 |
msgstr ""
|
2020 |
|
2021 |
+
#: classes/Views/SetupWizard.php:614
|
2022 |
msgid "6 months (data older than 6 months will be deleted)"
|
2023 |
msgstr ""
|
2024 |
|
2025 |
+
#: classes/Views/SetupWizard.php:619
|
2026 |
msgid "12 months (data older than 12 months will be deleted)"
|
2027 |
msgstr ""
|
2028 |
|
2029 |
+
#: classes/Views/SetupWizard.php:624
|
2030 |
msgid "Keep all data."
|
2031 |
msgstr ""
|
2032 |
|
2033 |
+
#: classes/Views/SetupWizard.php:645
|
2034 |
msgid "The plugin stores the data in the WordPress database in a very efficient way, though the more data you keep the more hard disk space it will consume. If you need need to retain a lot of data we would recommend you to <a href=\"https://wpactivitylog.com/features/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=wizard+configuration\" target=\"_blank\">upgrade to Premium</a> and use the Database tools to store the WordPress activity log in an external database."
|
2035 |
msgstr ""
|
2036 |
|
2037 |
+
#: classes/Views/SetupWizard.php:708
|
2038 |
msgid "Your plugin is all set and it is ready to start keeping a record of everything that is happening on your WordPress in a WordPress activity log."
|
2039 |
msgstr ""
|
2040 |
|
2041 |
+
#: classes/Views/SetupWizard.php:709
|
2042 |
msgid "Below are a few useful links you might need to refer to:"
|
2043 |
msgstr ""
|
2044 |
|
2045 |
+
#: classes/Views/SetupWizard.php:714
|
2046 |
msgid "Getting started with the WP Activity Log plugin"
|
2047 |
msgstr ""
|
2048 |
|
2049 |
+
#: classes/Views/SetupWizard.php:719
|
2050 |
msgid "Knowledge Base & Support Documents"
|
2051 |
msgstr ""
|
2052 |
|
2053 |
+
#: classes/Views/SetupWizard.php:724
|
2054 |
msgid "Benefits of keeping a WordPress activity log"
|
2055 |
msgstr ""
|
2056 |
|
2057 |
+
#: classes/Views/SetupWizard.php:734
|
2058 |
msgid "We trust this plugin meets all your activity log requirements. Should you encounter any problems, have feature requests or would like to share some feedback"
|
2059 |
msgstr ""
|
2060 |
|
2061 |
+
#: classes/Views/SetupWizard.php:734
|
2062 |
msgid "please get in touch!"
|
2063 |
msgstr ""
|
2064 |
|
2065 |
+
#: classes/Views/SetupWizard.php:770
|
2066 |
msgid "Third Party Extensions"
|
2067 |
msgstr ""
|
2068 |
|
2069 |
+
#: classes/Views/SetupWizard.php:811
|
2070 |
msgid "Monitoring changes done in third party plugins"
|
2071 |
msgstr ""
|
2072 |
|
2073 |
+
#: classes/Views/SetupWizard.php:812
|
2074 |
msgid "We noticed that the below plugins are installed on this website. You can install our extensions to also keep a log of changes users do on these plugins."
|
2075 |
msgstr ""
|
2076 |
|
2078 |
msgid "Enable/Disable Events"
|
2079 |
msgstr ""
|
2080 |
|
2081 |
+
#: classes/Views/ToggleAlerts.php:161
|
2082 |
msgid "Basic"
|
2083 |
msgstr ""
|
2084 |
|
2085 |
+
#: classes/Views/ToggleAlerts.php:162
|
2086 |
msgid "Geek"
|
2087 |
msgstr ""
|
2088 |
|
2089 |
+
#: classes/Views/ToggleAlerts.php:163
|
2090 |
msgid "Custom"
|
2091 |
msgstr ""
|
2092 |
|
2093 |
+
#: classes/Views/ToggleAlerts.php:181
|
2094 |
+
msgid "Enable/Disable alerts"
|
2095 |
msgstr ""
|
2096 |
|
2097 |
+
#: classes/Views/ToggleAlerts.php:183
|
|
|
|
|
|
|
|
|
2098 |
msgid "Third party plugins"
|
2099 |
msgstr ""
|
2100 |
|
2101 |
+
#: classes/Views/ToggleAlerts.php:194
|
2102 |
+
msgid "Log Level: "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2103 |
msgstr ""
|
2104 |
|
2105 |
+
#: classes/Views/ToggleAlerts.php:201
|
2106 |
+
msgid "Use the Log level drop down menu above to use one of our preset log levels. Alternatively you can enable or disable any of the individual events from the below tabs. Refer to <a href=\"https://wpactivitylog.com/support/kb/list-wordpress-activity-log-event-ids/\" target=\"_blank\">the complete list of WordPress activity log event IDs</a> for reference on all the events the plugin can keep a log of."
|
2107 |
msgstr ""
|
2108 |
|
2109 |
+
#: classes/Views/ToggleAlerts.php:213
|
2110 |
+
msgid "Choose your query and enter your search term"
|
2111 |
msgstr ""
|
2112 |
|
2113 |
+
#: classes/Views/ToggleAlerts.php:215
|
2114 |
+
msgid "Event code"
|
2115 |
msgstr ""
|
2116 |
|
2117 |
+
#: classes/Views/ToggleAlerts.php:217 classes/Views/ToggleAlerts.php:257
|
2118 |
+
#: classes/WidgetManager.php:79
|
2119 |
+
msgid "Description"
|
2120 |
msgstr ""
|
2121 |
|
2122 |
+
#: classes/Views/ToggleAlerts.php:221
|
2123 |
+
msgid "OR"
|
2124 |
msgstr ""
|
2125 |
|
2126 |
+
#: classes/Views/ToggleAlerts.php:223
|
2127 |
+
msgid "Choose a category"
|
2128 |
msgstr ""
|
2129 |
|
2130 |
+
#: classes/Views/ToggleAlerts.php:225
|
2131 |
+
msgid "All categories"
|
|
|
2132 |
msgstr ""
|
2133 |
|
2134 |
+
#: classes/Views/ToggleAlerts.php:255
|
2135 |
+
msgid "Code"
|
2136 |
msgstr ""
|
2137 |
|
2138 |
+
#: classes/Views/ToggleAlerts.php:306
|
2139 |
+
msgid "Please activate WooCommerce to enable this alert"
|
2140 |
msgstr ""
|
2141 |
|
2142 |
+
#: classes/Views/ToggleAlerts.php:314
|
2143 |
+
msgid "Please activate the Yoast SEO Plugin"
|
2144 |
msgstr ""
|
2145 |
|
2146 |
+
#: classes/Views/ToggleAlerts.php:322
|
2147 |
+
msgid "Your website is a single site so the multisite events have been disabled."
|
2148 |
msgstr ""
|
2149 |
|
2150 |
#: classes/Views/ToggleAlerts.php:388
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2151 |
msgid "Keep a log when a visitor registers a user on the website. Only enable this if you allow visitors to register as users on your website. User registration is disabled by default in WordPress."
|
2152 |
msgstr ""
|
2153 |
|
2154 |
+
#: classes/Views/ToggleAlerts.php:402 classes/Views/ToggleAlerts.php:415
|
2155 |
msgid "Number of login attempts to log. Enter 0 to log all failed login attempts. (By default the plugin only logs up to 10 failed login because the process can be very resource intensive in case of a brute force attack)"
|
2156 |
msgstr ""
|
2157 |
|
2158 |
+
#: classes/Views/ToggleAlerts.php:428
|
2159 |
msgid "Keep a log of user log in activity on custom login forms (such as WooCommerce & membership plugins)"
|
2160 |
msgstr ""
|
2161 |
|
2162 |
+
#: classes/Views/ToggleAlerts.php:443
|
2163 |
msgid "Save Changes"
|
2164 |
msgstr ""
|
2165 |
|
2166 |
+
#: classes/Views/ToggleAlerts.php:458
|
2167 |
msgid "Log Level Updated"
|
2168 |
msgstr ""
|
2169 |
|
2170 |
+
#: classes/Views/ToggleAlerts.php:462
|
2171 |
#, php-format
|
2172 |
msgid "The %s log level has been successfully loaded and applied."
|
2173 |
msgstr ""
|
2174 |
|
2175 |
+
#: classes/Views/ToggleAlerts.php:466
|
2176 |
msgid "OK"
|
2177 |
msgstr ""
|
2178 |
|
2179 |
+
#: classes/Views/ToggleAlerts.php:481
|
2180 |
msgid "Enable File Integrity Scanner"
|
2181 |
msgstr ""
|
2182 |
|
2183 |
+
#: classes/Views/ToggleAlerts.php:483
|
2184 |
msgid "The file integrity scanner is switched off. To enable this event it has to be switched on."
|
2185 |
msgstr ""
|
2186 |
|
2187 |
+
#: classes/Views/ToggleAlerts.php:487
|
2188 |
msgid "SWITCH ON"
|
2189 |
msgstr ""
|
2190 |
|
2191 |
+
#: classes/Views/ToggleAlerts.php:488
|
2192 |
msgid "DISABLE EVENT"
|
2193 |
msgstr ""
|
2194 |
|
2195 |
+
#: classes/Views/addons/html-view.php:97 classes/Views/addons/html-view.php:122
|
2196 |
msgid "Upgrade to Premium"
|
2197 |
msgstr ""
|
2198 |
|
2199 |
+
#: classes/Views/addons/html-view.php:98
|
2200 |
msgid "More Information"
|
2201 |
msgstr ""
|
2202 |
|
2203 |
+
#: classes/Views/addons/html-view.php:106
|
2204 |
msgid "Screenshots"
|
2205 |
msgstr ""
|
2206 |
|
2207 |
+
#: classes/Views/addons/html-view.php:123
|
2208 |
msgid "Start Free 14-Day Premium Trial"
|
2209 |
msgstr ""
|
2210 |
|
2248 |
msgid "View menu"
|
2249 |
msgstr ""
|
2250 |
|
2251 |
+
#: defaults.php:117 defaults.php:126 defaults.php:3273 defaults.php:3285
|
2252 |
+
#: defaults.php:3297 defaults.php:3309 defaults.php:3321 defaults.php:3333
|
2253 |
msgid "URL"
|
2254 |
msgstr ""
|
2255 |
|
2365 |
#: defaults.php:1746 defaults.php:1760 defaults.php:1774 defaults.php:1789
|
2366 |
#: defaults.php:1804 defaults.php:1818 defaults.php:1832 defaults.php:1848
|
2367 |
#: defaults.php:1863 defaults.php:1877 defaults.php:1891 defaults.php:1906
|
2368 |
+
#: defaults.php:1921 defaults.php:1938 defaults.php:1952 defaults.php:1967
|
2369 |
+
#: defaults.php:1981 defaults.php:1995 defaults.php:2012 defaults.php:2026
|
2370 |
+
#: defaults.php:2040 defaults.php:2081 defaults.php:2439
|
2371 |
msgid "Role"
|
2372 |
msgstr ""
|
2373 |
|
2423 |
msgid "Content & Comments"
|
2424 |
msgstr ""
|
2425 |
|
2426 |
+
#: defaults.php:342
|
2427 |
+
msgid "Content"
|
2428 |
+
msgstr ""
|
2429 |
+
|
2430 |
#: defaults.php:346
|
2431 |
msgid "User created a new post and saved it as draft"
|
2432 |
msgstr ""
|
2445 |
#: defaults.php:918 defaults.php:933 defaults.php:950 defaults.php:965
|
2446 |
#: defaults.php:986 defaults.php:1001 defaults.php:1016 defaults.php:1031
|
2447 |
#: defaults.php:1046 defaults.php:1061 defaults.php:1076 defaults.php:1091
|
2448 |
+
#: defaults.php:1106 defaults.php:1121 defaults.php:1140 defaults.php:2177
|
2449 |
+
#: defaults.php:2192
|
2450 |
msgid "Post ID"
|
2451 |
msgstr ""
|
2452 |
|
2460 |
#: defaults.php:919 defaults.php:934 defaults.php:951 defaults.php:966
|
2461 |
#: defaults.php:987 defaults.php:1002 defaults.php:1017 defaults.php:1032
|
2462 |
#: defaults.php:1047 defaults.php:1062 defaults.php:1077 defaults.php:1092
|
2463 |
+
#: defaults.php:1107 defaults.php:1122 defaults.php:1141 defaults.php:2178
|
2464 |
+
#: defaults.php:2193
|
2465 |
msgid "Post type"
|
2466 |
msgstr ""
|
2467 |
|
2475 |
#: defaults.php:935 defaults.php:952 defaults.php:967 defaults.php:988
|
2476 |
#: defaults.php:1003 defaults.php:1018 defaults.php:1033 defaults.php:1048
|
2477 |
#: defaults.php:1063 defaults.php:1078 defaults.php:1093 defaults.php:1108
|
2478 |
+
#: defaults.php:1123 defaults.php:1142 defaults.php:2179 defaults.php:2194
|
2479 |
msgid "Post status"
|
2480 |
msgstr ""
|
2481 |
|
2527 |
msgid "Changed the URL of the post %PostTitle%."
|
2528 |
msgstr ""
|
2529 |
|
2530 |
+
#: defaults.php:436 defaults.php:2985 defaults.php:2997
|
2531 |
msgid "Previous URL"
|
2532 |
msgstr ""
|
2533 |
|
3681 |
#: defaults.php:1719 defaults.php:1733 defaults.php:1747 defaults.php:1761
|
3682 |
#: defaults.php:1775 defaults.php:1790 defaults.php:1805 defaults.php:1819
|
3683 |
#: defaults.php:1833 defaults.php:1849 defaults.php:1878 defaults.php:1892
|
3684 |
+
#: defaults.php:1907 defaults.php:1922 defaults.php:1939 defaults.php:1953
|
3685 |
+
#: defaults.php:1968 defaults.php:1982 defaults.php:1996 defaults.php:2013
|
3686 |
+
#: defaults.php:2027 defaults.php:2041 defaults.php:2055 defaults.php:2068
|
3687 |
+
#: defaults.php:2082 defaults.php:2440
|
3688 |
msgid "First name"
|
3689 |
msgstr ""
|
3690 |
|
3691 |
#: defaults.php:1720 defaults.php:1734 defaults.php:1748 defaults.php:1762
|
3692 |
#: defaults.php:1776 defaults.php:1791 defaults.php:1806 defaults.php:1820
|
3693 |
#: defaults.php:1834 defaults.php:1850 defaults.php:1865 defaults.php:1893
|
3694 |
+
#: defaults.php:1908 defaults.php:1923 defaults.php:1940 defaults.php:1954
|
3695 |
+
#: defaults.php:1969 defaults.php:1983 defaults.php:1997 defaults.php:2014
|
3696 |
+
#: defaults.php:2028 defaults.php:2042 defaults.php:2056 defaults.php:2069
|
3697 |
+
#: defaults.php:2083 defaults.php:2441
|
3698 |
msgid "Last name"
|
3699 |
msgstr ""
|
3700 |
|
3706 |
msgid "Changed the role of user %TargetUsername% to %NewRole%."
|
3707 |
msgstr ""
|
3708 |
|
3709 |
+
#: defaults.php:1732 defaults.php:2831
|
3710 |
msgid "Previous role"
|
3711 |
msgstr ""
|
3712 |
|
3770 |
msgid "Changed the value of the custom field %custom_field_name% in the user profile %TargetUsername%."
|
3771 |
msgstr ""
|
3772 |
|
3773 |
+
#: defaults.php:1835 defaults.php:2921 defaults.php:2953 defaults.php:3377
|
3774 |
msgid "Previous value"
|
3775 |
msgstr ""
|
3776 |
|
3777 |
+
#: defaults.php:1836 defaults.php:3378
|
3778 |
msgid "New value"
|
3779 |
msgstr ""
|
3780 |
|
3834 |
msgid "Previous display name"
|
3835 |
msgstr ""
|
3836 |
|
3837 |
+
#: defaults.php:1918
|
3838 |
+
msgid "User's website URL was modified"
|
3839 |
+
msgstr ""
|
3840 |
+
|
3841 |
+
#: defaults.php:1919
|
3842 |
+
msgid "Changed the website URL of the user %TargetUsername% to %new_url%."
|
3843 |
+
msgstr ""
|
3844 |
+
|
3845 |
+
#: defaults.php:1924
|
3846 |
+
msgid "Previous website URL"
|
3847 |
+
msgstr ""
|
3848 |
+
|
3849 |
+
#: defaults.php:1935 defaults.php:1949
|
3850 |
msgid "User created an application password"
|
3851 |
msgstr ""
|
3852 |
|
3853 |
+
#: defaults.php:1936
|
3854 |
msgid "The application password %friendly_name%."
|
3855 |
msgstr ""
|
3856 |
|
3857 |
+
#: defaults.php:1950
|
3858 |
msgid "The application password %friendly_name% for the user %login%."
|
3859 |
msgstr ""
|
3860 |
|
3861 |
+
#: defaults.php:1964
|
3862 |
msgid "User revoked all application passwords"
|
3863 |
msgstr ""
|
3864 |
|
3865 |
+
#: defaults.php:1965
|
3866 |
msgid "All application passwords."
|
3867 |
msgstr ""
|
3868 |
|
3869 |
+
#: defaults.php:1978
|
3870 |
msgid "User revoked all application passwords for a user"
|
3871 |
msgstr ""
|
3872 |
|
3873 |
+
#: defaults.php:1979
|
3874 |
msgid "All application passwords from the user %login%."
|
3875 |
msgstr ""
|
3876 |
|
3877 |
+
#: defaults.php:1992
|
3878 |
msgid "Admin sent a password reset request to a user"
|
3879 |
msgstr ""
|
3880 |
|
3881 |
+
#: defaults.php:1993
|
3882 |
msgid "Sent a password reset request to the user %login%."
|
3883 |
msgstr ""
|
3884 |
|
3885 |
+
#: defaults.php:2005
|
3886 |
msgid "Multisite User Profiles"
|
3887 |
msgstr ""
|
3888 |
|
3889 |
+
#: defaults.php:2009
|
3890 |
msgid "User granted Super Admin privileges"
|
3891 |
msgstr ""
|
3892 |
|
3893 |
+
#: defaults.php:2010
|
3894 |
msgid "Granted Super Admin privileges to the user %TargetUsername%."
|
3895 |
msgstr ""
|
3896 |
|
3897 |
+
#: defaults.php:2023
|
3898 |
msgid "User revoked from Super Admin privileges"
|
3899 |
msgstr ""
|
3900 |
|
3901 |
+
#: defaults.php:2024
|
3902 |
msgid "Revoked Super Admin privileges from %TargetUsername%."
|
3903 |
msgstr ""
|
3904 |
|
3905 |
+
#: defaults.php:2037
|
3906 |
msgid "Existing user added to a site"
|
3907 |
msgstr ""
|
3908 |
|
3909 |
+
#: defaults.php:2038
|
3910 |
msgid "Added user %TargetUsername% to the site %SiteName%."
|
3911 |
msgstr ""
|
3912 |
|
3913 |
+
#: defaults.php:2051
|
3914 |
msgid "User removed from site"
|
3915 |
msgstr ""
|
3916 |
|
3917 |
+
#: defaults.php:2052
|
3918 |
msgid "Removed user %TargetUsername% from the site %SiteName%"
|
3919 |
msgstr ""
|
3920 |
|
3921 |
+
#: defaults.php:2054
|
3922 |
msgid "Site role"
|
3923 |
msgstr ""
|
3924 |
|
3925 |
+
#: defaults.php:2065
|
3926 |
msgid "New network user created"
|
3927 |
msgstr ""
|
3928 |
|
3929 |
+
#: defaults.php:2066
|
3930 |
msgid "Created the new network user %NewUserData->Username%."
|
3931 |
msgstr ""
|
3932 |
|
3933 |
+
#: defaults.php:2078
|
3934 |
+
msgid "Network user has been activated"
|
3935 |
+
msgstr ""
|
3936 |
+
|
3937 |
+
#: defaults.php:2079
|
3938 |
+
msgid "User %NewUserData->Username% has been activated."
|
3939 |
+
msgstr ""
|
3940 |
+
|
3941 |
+
#: defaults.php:2092
|
3942 |
+
msgid "Network user has signed-up"
|
3943 |
+
msgstr ""
|
3944 |
+
|
3945 |
+
#: defaults.php:2093
|
3946 |
+
msgid "User with the email address %email_address% has signed up to the network."
|
3947 |
+
msgstr ""
|
3948 |
+
|
3949 |
+
#: defaults.php:2095
|
3950 |
+
msgid "Username"
|
3951 |
+
msgstr ""
|
3952 |
+
|
3953 |
+
#: defaults.php:2104
|
3954 |
msgid "Plugins & Themes"
|
3955 |
msgstr ""
|
3956 |
|
3957 |
+
#: defaults.php:2109
|
3958 |
msgid "User installed a plugin"
|
3959 |
msgstr ""
|
3960 |
|
3961 |
+
#: defaults.php:2110
|
3962 |
msgid "Installed the plugin %Plugin->Name%."
|
3963 |
msgstr ""
|
3964 |
|
3965 |
+
#: defaults.php:2112 defaults.php:2125 defaults.php:2138 defaults.php:2151
|
3966 |
+
#: defaults.php:2247 defaults.php:2260 defaults.php:2273 defaults.php:2312
|
3967 |
+
#: defaults.php:2325
|
3968 |
msgid "Version"
|
3969 |
msgstr ""
|
3970 |
|
3971 |
+
#: defaults.php:2113 defaults.php:2126 defaults.php:2139 defaults.php:2152
|
3972 |
+
#: defaults.php:2165 defaults.php:2208 defaults.php:2221 defaults.php:2248
|
3973 |
+
#: defaults.php:2261 defaults.php:2274 defaults.php:2287 defaults.php:2313
|
3974 |
+
#: defaults.php:2326
|
3975 |
msgid "Install location"
|
3976 |
msgstr ""
|
3977 |
|
3978 |
+
#: defaults.php:2122
|
3979 |
msgid "User activated a WordPress plugin"
|
3980 |
msgstr ""
|
3981 |
|
3982 |
+
#: defaults.php:2123
|
3983 |
msgid "Activated the plugin %PluginData->Name%."
|
3984 |
msgstr ""
|
3985 |
|
3986 |
+
#: defaults.php:2135
|
3987 |
msgid "User deactivated a WordPress plugin"
|
3988 |
msgstr ""
|
3989 |
|
3990 |
+
#: defaults.php:2136
|
3991 |
msgid "Deactivated the plugin %PluginData->Name%."
|
3992 |
msgstr ""
|
3993 |
|
3994 |
+
#: defaults.php:2148
|
3995 |
msgid "User uninstalled a plugin"
|
3996 |
msgstr ""
|
3997 |
|
3998 |
+
#: defaults.php:2149
|
3999 |
msgid "Uninstalled the plugin %PluginData->Name%."
|
4000 |
msgstr ""
|
4001 |
|
4002 |
+
#: defaults.php:2161
|
4003 |
msgid "User upgraded a plugin"
|
4004 |
msgstr ""
|
4005 |
|
4006 |
+
#: defaults.php:2162
|
4007 |
msgid "Updated the plugin %PluginData->Name%."
|
4008 |
msgstr ""
|
4009 |
|
4010 |
+
#: defaults.php:2164
|
4011 |
msgid "Updated version"
|
4012 |
msgstr ""
|
4013 |
|
4014 |
+
#: defaults.php:2174
|
4015 |
msgid "A plugin created a post"
|
4016 |
msgstr ""
|
4017 |
|
4018 |
+
#: defaults.php:2175
|
4019 |
msgid "The plugin created the post %PostTitle%."
|
4020 |
msgstr ""
|
4021 |
|
4022 |
+
#: defaults.php:2189
|
4023 |
msgid "A plugin deleted a post"
|
4024 |
msgstr ""
|
4025 |
|
4026 |
+
#: defaults.php:2190
|
4027 |
msgid "A plugin deleted the post %PostTitle%."
|
4028 |
msgstr ""
|
4029 |
|
4030 |
+
#: defaults.php:2205
|
4031 |
msgid "Changed the Automatic updates setting for a plugin."
|
4032 |
msgstr ""
|
4033 |
|
4034 |
+
#: defaults.php:2206
|
4035 |
msgid "Changed the Automatic updates setting for the plugin %name%."
|
4036 |
msgstr ""
|
4037 |
|
4038 |
+
#: defaults.php:2218
|
4039 |
msgid "Changed the Automatic updates setting for a theme."
|
4040 |
msgstr ""
|
4041 |
|
4042 |
+
#: defaults.php:2219
|
4043 |
msgid "Changed the Automatic updates setting for the theme %name%."
|
4044 |
msgstr ""
|
4045 |
|
4046 |
+
#: defaults.php:2231
|
4047 |
msgid "User changed a file using the plugin editor"
|
4048 |
msgstr ""
|
4049 |
|
4050 |
+
#: defaults.php:2232
|
4051 |
msgid "Modified the file %File% with the plugin editor."
|
4052 |
msgstr ""
|
4053 |
|
4054 |
+
#: defaults.php:2240
|
4055 |
msgid "Themes"
|
4056 |
msgstr ""
|
4057 |
|
4058 |
+
#: defaults.php:2244
|
4059 |
msgid "User installed a theme"
|
4060 |
msgstr ""
|
4061 |
|
4062 |
+
#: defaults.php:2245
|
4063 |
msgid "Installed the theme %Theme->Name%."
|
4064 |
msgstr ""
|
4065 |
|
4066 |
+
#: defaults.php:2257
|
4067 |
msgid "User activated a theme"
|
4068 |
msgstr ""
|
4069 |
|
4070 |
+
#: defaults.php:2258
|
4071 |
msgid "Activated the theme %Theme->Name%."
|
4072 |
msgstr ""
|
4073 |
|
4074 |
+
#: defaults.php:2270
|
4075 |
msgid "User uninstalled a theme"
|
4076 |
msgstr ""
|
4077 |
|
4078 |
+
#: defaults.php:2271
|
4079 |
msgid "Deleted the theme %Theme->Name%."
|
4080 |
msgstr ""
|
4081 |
|
4082 |
+
#: defaults.php:2283
|
4083 |
msgid "User updated a theme"
|
4084 |
msgstr ""
|
4085 |
|
4086 |
+
#: defaults.php:2284
|
4087 |
msgid "Updated the theme %Theme->Name%."
|
4088 |
msgstr ""
|
4089 |
|
4090 |
+
#: defaults.php:2286 defaults.php:2380
|
4091 |
msgid "New version"
|
4092 |
msgstr ""
|
4093 |
|
4094 |
+
#: defaults.php:2296
|
4095 |
msgid "User changed a file using the theme editor"
|
4096 |
msgstr ""
|
4097 |
|
4098 |
+
#: defaults.php:2297
|
4099 |
msgid "Modified the file %Theme%/%File% with the theme editor."
|
4100 |
msgstr ""
|
4101 |
|
4102 |
+
#: defaults.php:2305
|
4103 |
msgid "Themes on Multisite"
|
4104 |
msgstr ""
|
4105 |
|
4106 |
+
#: defaults.php:2309
|
4107 |
msgid "Activated theme on network"
|
4108 |
msgstr ""
|
4109 |
|
4110 |
+
#: defaults.php:2310
|
4111 |
msgid "Network activated the theme %Theme->Name%."
|
4112 |
msgstr ""
|
4113 |
|
4114 |
+
#: defaults.php:2322
|
4115 |
msgid "Deactivated theme from network"
|
4116 |
msgstr ""
|
4117 |
|
4118 |
+
#: defaults.php:2323
|
4119 |
msgid "Network deactivated the theme %Theme->Name%."
|
4120 |
msgstr ""
|
4121 |
|
4122 |
+
#: defaults.php:2335
|
4123 |
msgid "WordPress & System"
|
4124 |
msgstr ""
|
4125 |
|
4126 |
+
#: defaults.php:2340
|
4127 |
msgid "Unknown Error"
|
4128 |
msgstr ""
|
4129 |
|
4130 |
+
#: defaults.php:2341
|
4131 |
msgid "An unexpected error has occurred."
|
4132 |
msgstr ""
|
4133 |
|
4134 |
+
#: defaults.php:2346
|
4135 |
msgid "PHP error"
|
4136 |
msgstr ""
|
4137 |
|
4138 |
+
#: defaults.php:2347 defaults.php:2353 defaults.php:2359 defaults.php:2365
|
4139 |
+
#: defaults.php:2371
|
4140 |
msgid "%Message%."
|
4141 |
msgstr ""
|
4142 |
|
4143 |
+
#: defaults.php:2352
|
4144 |
msgid "PHP warning"
|
4145 |
msgstr ""
|
4146 |
|
4147 |
+
#: defaults.php:2358
|
4148 |
msgid "PHP notice"
|
4149 |
msgstr ""
|
4150 |
|
4151 |
+
#: defaults.php:2364
|
4152 |
msgid "PHP exception"
|
4153 |
msgstr ""
|
4154 |
|
4155 |
+
#: defaults.php:2370
|
4156 |
msgid "PHP shutdown error"
|
4157 |
msgstr ""
|
4158 |
|
4159 |
+
#: defaults.php:2376
|
4160 |
msgid "WordPress was updated"
|
4161 |
msgstr ""
|
4162 |
|
4163 |
+
#: defaults.php:2377
|
4164 |
msgid "Updated WordPress."
|
4165 |
msgstr ""
|
4166 |
|
4167 |
+
#: defaults.php:2379
|
4168 |
msgid "Previous version"
|
4169 |
msgstr ""
|
4170 |
|
4171 |
+
#: defaults.php:2396
|
4172 |
msgid "Advertising Extensions"
|
4173 |
msgstr ""
|
4174 |
|
4175 |
+
#: defaults.php:2397
|
4176 |
msgid "%PromoName% %PromoMessage%"
|
4177 |
msgstr ""
|
4178 |
|
4179 |
+
#: defaults.php:2401
|
4180 |
msgid "Activity log plugin"
|
4181 |
msgstr ""
|
4182 |
|
4183 |
+
#: defaults.php:2405
|
4184 |
msgid "Events automatically pruned by system"
|
4185 |
msgstr ""
|
4186 |
|
4187 |
+
#: defaults.php:2406
|
4188 |
msgid "System automatically deleted %EventCount% events from the activity log."
|
4189 |
msgstr ""
|
4190 |
|
4191 |
+
#: defaults.php:2415
|
4192 |
msgid "Reset the plugin's settings to default"
|
4193 |
msgstr ""
|
4194 |
|
4195 |
+
#: defaults.php:2416
|
4196 |
msgid "Reset the activity log plugin's settings to default."
|
4197 |
msgstr ""
|
4198 |
|
4199 |
+
#: defaults.php:2425
|
4200 |
msgid "Purged the activity log"
|
4201 |
msgstr ""
|
4202 |
|
4203 |
+
#: defaults.php:2426
|
4204 |
msgid "Purged the activity log."
|
4205 |
msgstr ""
|
4206 |
|
4207 |
+
#: defaults.php:2436
|
4208 |
msgid "Deleted all the data about a user from the activity log."
|
4209 |
msgstr ""
|
4210 |
|
4211 |
+
#: defaults.php:2437
|
4212 |
msgid "Deleted all the data about the user <strong>%user%</strong> from the activity log."
|
4213 |
msgstr ""
|
4214 |
|
4215 |
+
#: defaults.php:2450
|
4216 |
msgid "Deleted all the data of a specific type from the activity log."
|
4217 |
msgstr ""
|
4218 |
|
4219 |
+
#: defaults.php:2451
|
4220 |
msgid "Deleted all the data about the %deleted_data_type% %deleted_data% from the activity log."
|
4221 |
msgstr ""
|
4222 |
|
4223 |
+
#: defaults.php:2461
|
4224 |
msgid "Some WP Activity Log plugin settings on this site were propagated and overridden from the MainWP dashboard"
|
4225 |
msgstr ""
|
4226 |
|
4227 |
+
#: defaults.php:2462
|
4228 |
msgid "Some <strong>WP Activity Log</strong> plugin settings on this site were propagated and overridden from the MainWP dashboard."
|
4229 |
msgstr ""
|
4230 |
|
4231 |
+
#: defaults.php:2472
|
4232 |
msgid "Changed the status of the Login Page Notification"
|
4233 |
msgstr ""
|
4234 |
|
4235 |
+
#: defaults.php:2473
|
4236 |
msgid "Changed the status of the <strong>Login Page Notification.</strong>"
|
4237 |
msgstr ""
|
4238 |
|
4239 |
+
#: defaults.php:2482
|
4240 |
msgid "Changed the text of the Login Page Notification"
|
4241 |
msgstr ""
|
4242 |
|
4243 |
+
#: defaults.php:2483
|
4244 |
msgid "Changed the text of the <strong>Login Page Notification.</strong>"
|
4245 |
msgstr ""
|
4246 |
|
4247 |
+
#: defaults.php:2492
|
4248 |
msgid "Changed the status of the Reverse proxy / firewall option"
|
4249 |
msgstr ""
|
4250 |
|
4251 |
+
#: defaults.php:2493
|
4252 |
msgid "Changed the status of the <strong>Reverse proxy / firewall option.</strong>"
|
4253 |
msgstr ""
|
4254 |
|
4255 |
+
#: defaults.php:2502
|
4256 |
msgid "Changed the Restrict plugin access setting"
|
4257 |
msgstr ""
|
4258 |
|
4259 |
+
#: defaults.php:2503
|
4260 |
msgid "Changed the <strong>Restrict plugin access</strong> setting to %new_setting%."
|
4261 |
msgstr ""
|
4262 |
|
4263 |
+
#: defaults.php:2505 defaults.php:2539 defaults.php:3009 defaults.php:3096
|
4264 |
+
#: defaults.php:3109 defaults.php:3402
|
4265 |
msgid "Previous setting"
|
4266 |
msgstr ""
|
4267 |
|
4268 |
+
#: defaults.php:2514
|
4269 |
msgid "The user %user% to / from the list of users who can view the activity log"
|
4270 |
msgstr ""
|
4271 |
|
4272 |
+
#: defaults.php:2515
|
4273 |
msgid "The user %user% to / from the list of users who can view the activity log."
|
4274 |
msgstr ""
|
4275 |
|
4276 |
+
#: defaults.php:2517
|
4277 |
msgid "Previous list of users who had access to view the activity log"
|
4278 |
msgstr ""
|
4279 |
|
4280 |
+
#: defaults.php:2526
|
4281 |
msgid "Changed the status of the Hide plugin in plugins page setting"
|
4282 |
msgstr ""
|
4283 |
|
4284 |
+
#: defaults.php:2527
|
4285 |
msgid "Changed the status of the <strong>Hide plugin in plugins page</strong> setting."
|
4286 |
msgstr ""
|
4287 |
|
4288 |
+
#: defaults.php:2536
|
4289 |
msgid "Changed the Activity log retention setting"
|
4290 |
msgstr ""
|
4291 |
|
4292 |
+
#: defaults.php:2537
|
4293 |
msgid "Changed the <strong>Activity log retention</strong> to %new_setting%."
|
4294 |
msgstr ""
|
4295 |
|
4296 |
+
#: defaults.php:2548
|
4297 |
msgid "A user was added to / from the list of excluded users from the activity log"
|
4298 |
msgstr ""
|
4299 |
|
4300 |
+
#: defaults.php:2549
|
4301 |
msgid "The user %user% to / from the list of excluded users from the activity log."
|
4302 |
msgstr ""
|
4303 |
|
4304 |
+
#: defaults.php:2551 defaults.php:2563
|
4305 |
msgid "Previous list of users"
|
4306 |
msgstr ""
|
4307 |
|
4308 |
+
#: defaults.php:2560
|
4309 |
msgid "A user role was added to / from the list of excluded roles from the activity log"
|
4310 |
msgstr ""
|
4311 |
|
4312 |
+
#: defaults.php:2561
|
4313 |
msgid "The user role %role% to / from the list of excluded roles from the activity log."
|
4314 |
msgstr ""
|
4315 |
|
4316 |
+
#: defaults.php:2572
|
4317 |
msgid "An IP address was added to / from the list of excluded IP addresses from the activity log"
|
4318 |
msgstr ""
|
4319 |
|
4320 |
+
#: defaults.php:2573
|
4321 |
msgid "The IP address %ip% to / from the list of excluded IP addresses from the activity log."
|
4322 |
msgstr ""
|
4323 |
|
4324 |
+
#: defaults.php:2575
|
4325 |
msgid "Previous list of IPs"
|
4326 |
msgstr ""
|
4327 |
|
4328 |
+
#: defaults.php:2584
|
4329 |
msgid "A post type was added to / from the list of excluded post types from the activity log"
|
4330 |
msgstr ""
|
4331 |
|
4332 |
+
#: defaults.php:2585
|
4333 |
msgid "The post type %post_type% to / from the list of excluded post types from the activity log."
|
4334 |
msgstr ""
|
4335 |
|
4336 |
+
#: defaults.php:2587
|
4337 |
msgid "Previous list of Post types"
|
4338 |
msgstr ""
|
4339 |
|
4340 |
+
#: defaults.php:2596
|
4341 |
msgid "A custom field was added to / from the list of excluded custom fields from the activity log"
|
4342 |
msgstr ""
|
4343 |
|
4344 |
+
#: defaults.php:2597
|
4345 |
msgid "The custom field %custom_field% to / from the list of excluded custom fields from the activity log."
|
4346 |
msgstr ""
|
4347 |
|
4348 |
+
#: defaults.php:2599
|
4349 |
msgid "Previous list of Custom fields"
|
4350 |
msgstr ""
|
4351 |
|
4352 |
+
#: defaults.php:2608
|
4353 |
msgid "A custom field was added to / from the list of excluded user profile custom fields from the activity log"
|
4354 |
msgstr ""
|
4355 |
|
4356 |
+
#: defaults.php:2609
|
4357 |
msgid "The custom field %custom_field% to / from the list of excluded user profile custom fields from the activity log."
|
4358 |
msgstr ""
|
4359 |
|
4360 |
+
#: defaults.php:2611
|
4361 |
msgid "Previous list of user profile Custom fields"
|
4362 |
msgstr ""
|
4363 |
|
4364 |
+
#: defaults.php:2619
|
4365 |
msgid "Notifications & Integrations"
|
4366 |
msgstr ""
|
4367 |
|
4368 |
+
#: defaults.php:2623
|
4369 |
msgid "Changed the status of the Daily Summary of Activity Log"
|
4370 |
msgstr ""
|
4371 |
|
4372 |
+
#: defaults.php:2624
|
4373 |
msgid "Changed the status of the <strong>Daily Summary of Activity Log.</strong>."
|
4374 |
msgstr ""
|
4375 |
|
4376 |
+
#: defaults.php:2633
|
4377 |
msgid "Modified the reciepients of the Daily Summary of Activity Log."
|
4378 |
msgstr ""
|
4379 |
|
4380 |
+
#: defaults.php:2634
|
4381 |
msgid "Modified the reciepients of the <strong>Daily Summary of Activity Log</strong>."
|
4382 |
msgstr ""
|
4383 |
|
4384 |
+
#: defaults.php:2636
|
4385 |
msgid "New recipient"
|
4386 |
msgstr ""
|
4387 |
|
4388 |
+
#: defaults.php:2637
|
4389 |
msgid "Previous recipient"
|
4390 |
msgstr ""
|
4391 |
|
4392 |
+
#: defaults.php:2646
|
4393 |
msgid "Changed the status of a built in notification"
|
4394 |
msgstr ""
|
4395 |
|
4396 |
+
#: defaults.php:2647
|
4397 |
msgid "Changed the status of the built in notification %notification_name%."
|
4398 |
msgstr ""
|
4399 |
|
4400 |
+
#: defaults.php:2656
|
4401 |
msgid "Modified the recipient(s) of the built a notification"
|
4402 |
msgstr ""
|
4403 |
|
4404 |
+
#: defaults.php:2657
|
4405 |
msgid "Modified the recipient(s) of the built in notification %notification_name%."
|
4406 |
msgstr ""
|
4407 |
|
4408 |
+
#: defaults.php:2659
|
4409 |
msgid "New recipient(s)"
|
4410 |
msgstr ""
|
4411 |
|
4412 |
+
#: defaults.php:2660
|
4413 |
msgid "Previous recipient(s)"
|
4414 |
msgstr ""
|
4415 |
|
4416 |
+
#: defaults.php:2669
|
4417 |
msgid "Added a new custom notification"
|
4418 |
msgstr ""
|
4419 |
|
4420 |
+
#: defaults.php:2670
|
4421 |
msgid "Added a new custom notification %notification_name%."
|
4422 |
msgstr ""
|
4423 |
|
4424 |
+
#: defaults.php:2672 defaults.php:2684
|
4425 |
msgid "Recipient(s)"
|
4426 |
msgstr ""
|
4427 |
|
4428 |
+
#: defaults.php:2681
|
4429 |
msgid "Modified a custom notification"
|
4430 |
msgstr ""
|
4431 |
|
4432 |
+
#: defaults.php:2682
|
4433 |
msgid "Modified the custom notification %notification_name%."
|
4434 |
msgstr ""
|
4435 |
|
4436 |
+
#: defaults.php:2693
|
4437 |
msgid "Changed the status of a custom notification"
|
4438 |
msgstr ""
|
4439 |
|
4440 |
+
#: defaults.php:2694
|
4441 |
msgid "Changed the status of the custom notification %notification_name%."
|
4442 |
msgstr ""
|
4443 |
|
4444 |
+
#: defaults.php:2703
|
4445 |
msgid "Deleted a custom notification"
|
4446 |
msgstr ""
|
4447 |
|
4448 |
+
#: defaults.php:2704
|
4449 |
msgid "Deleted the custom notification %notification_name%."
|
4450 |
msgstr ""
|
4451 |
|
4452 |
+
#: defaults.php:2713
|
4453 |
msgid "Modified a default notification template"
|
4454 |
msgstr ""
|
4455 |
|
4456 |
+
#: defaults.php:2714
|
4457 |
msgid "Modified the default %template_name% notification template."
|
4458 |
msgstr ""
|
4459 |
|
4460 |
+
#: defaults.php:2725
|
4461 |
msgid "Added a new integrations connection"
|
4462 |
msgstr ""
|
4463 |
|
4464 |
+
#: defaults.php:2726
|
4465 |
msgid "Added / removed the integrations connection %name%"
|
4466 |
msgstr ""
|
4467 |
|
4468 |
+
#: defaults.php:2728 defaults.php:2740
|
4469 |
msgid "Connection type"
|
4470 |
msgstr ""
|
4471 |
|
4472 |
+
#: defaults.php:2737
|
4473 |
msgid "Modified an integrations connection"
|
4474 |
msgstr ""
|
4475 |
|
4476 |
+
#: defaults.php:2738
|
4477 |
msgid "Modified the integrations connection %name%."
|
4478 |
msgstr ""
|
4479 |
|
4480 |
+
#: defaults.php:2749
|
4481 |
msgid "Deleted a integrations connection"
|
4482 |
msgstr ""
|
4483 |
|
4484 |
+
#: defaults.php:2750
|
4485 |
msgid "Deleted the integrations connection %name%."
|
4486 |
msgstr ""
|
4487 |
|
4488 |
+
#: defaults.php:2759
|
4489 |
msgid "Added a new activity log mirror"
|
4490 |
msgstr ""
|
4491 |
|
4492 |
+
#: defaults.php:2760
|
4493 |
msgid "Added a new activity log mirror %name%."
|
4494 |
msgstr ""
|
4495 |
|
4496 |
+
#: defaults.php:2762 defaults.php:2774 defaults.php:2786
|
4497 |
msgid "Connection used by this mirror"
|
4498 |
msgstr ""
|
4499 |
|
4500 |
+
#: defaults.php:2771
|
4501 |
msgid "Modified an activity log mirror"
|
4502 |
msgstr ""
|
4503 |
|
4504 |
+
#: defaults.php:2772
|
4505 |
msgid "Modified the activity log mirror %name%."
|
4506 |
msgstr ""
|
4507 |
|
4508 |
+
#: defaults.php:2783
|
4509 |
msgid "Changed the status of an activity log mirror"
|
4510 |
msgstr ""
|
4511 |
|
4512 |
+
#: defaults.php:2784
|
4513 |
msgid "Changed the status of the activity log mirror %name%."
|
4514 |
msgstr ""
|
4515 |
|
4516 |
+
#: defaults.php:2795
|
4517 |
msgid "Deleted an activity log mirror"
|
4518 |
msgstr ""
|
4519 |
|
4520 |
+
#: defaults.php:2796
|
4521 |
msgid "Deleted the activity log mirror %name%."
|
4522 |
msgstr ""
|
4523 |
|
4524 |
+
#: defaults.php:2805
|
4525 |
msgid "Changed the status of Logging of events to the database"
|
4526 |
msgstr ""
|
4527 |
|
4528 |
+
#: defaults.php:2806
|
4529 |
msgid "Changed the status of <strong>Logging of events to the database</strong>."
|
4530 |
msgstr ""
|
4531 |
|
4532 |
+
#: defaults.php:2814
|
4533 |
msgid "WordPress Site Settings"
|
4534 |
msgstr ""
|
4535 |
|
4536 |
+
#: defaults.php:2818
|
4537 |
msgid "Option Anyone Can Register in WordPress settings changed"
|
4538 |
msgstr ""
|
4539 |
|
4540 |
+
#: defaults.php:2819
|
4541 |
msgid "The <strong>Membership</strong> setting <strong>Anyone can register</strong>."
|
4542 |
msgstr ""
|
4543 |
|
4544 |
+
#: defaults.php:2828
|
4545 |
msgid "New User Default Role changed"
|
4546 |
msgstr ""
|
4547 |
|
4548 |
+
#: defaults.php:2829
|
4549 |
msgid "Changed the <strong>New user default role</strong> WordPress setting."
|
4550 |
msgstr ""
|
4551 |
|
4552 |
+
#: defaults.php:2832
|
4553 |
msgid "New role"
|
4554 |
msgstr ""
|
4555 |
|
4556 |
+
#: defaults.php:2841
|
4557 |
msgid "WordPress Administrator Notification email changed"
|
4558 |
msgstr ""
|
4559 |
|
4560 |
+
#: defaults.php:2842
|
4561 |
msgid "Change the <strong>Administrator email address</strong> in the WordPress settings."
|
4562 |
msgstr ""
|
4563 |
|
4564 |
+
#: defaults.php:2844
|
4565 |
msgid "Previous address"
|
4566 |
msgstr ""
|
4567 |
|
4568 |
+
#: defaults.php:2845
|
4569 |
msgid "New address"
|
4570 |
msgstr ""
|
4571 |
|
4572 |
+
#: defaults.php:2854
|
4573 |
msgid "User changes the WordPress Permalinks"
|
4574 |
msgstr ""
|
4575 |
|
4576 |
+
#: defaults.php:2855
|
4577 |
msgid "Changed the <strong>WordPress permalinks</strong>."
|
4578 |
msgstr ""
|
4579 |
|
4580 |
+
#: defaults.php:2857
|
4581 |
msgid "Previous permalinks"
|
4582 |
msgstr ""
|
4583 |
|
4584 |
+
#: defaults.php:2858
|
4585 |
msgid "New permalinks"
|
4586 |
msgstr ""
|
4587 |
|
4588 |
+
#: defaults.php:2867
|
4589 |
msgid "Enabled/Disabled the option Discourage search engines from indexing this site"
|
4590 |
msgstr ""
|
4591 |
|
4592 |
+
#: defaults.php:2868
|
4593 |
msgid "Changed the status of the WordPress setting <strong>Search engine visibility</strong> (Discourage search engines from indexing this site)"
|
4594 |
msgstr ""
|
4595 |
|
4596 |
+
#: defaults.php:2877
|
4597 |
msgid "Enabled/Disabled comments on all the website"
|
4598 |
msgstr ""
|
4599 |
|
4600 |
+
#: defaults.php:2878
|
4601 |
msgid "Changed the status of the WordPress setting <strong>Allow people to submit comments on new posts</strong>."
|
4602 |
msgstr ""
|
4603 |
|
4604 |
+
#: defaults.php:2888
|
4605 |
msgid "Enabled/Disabled the option Comment author must fill out name and email"
|
4606 |
msgstr ""
|
4607 |
|
4608 |
+
#: defaults.php:2889
|
4609 |
msgid "Changed the status of the WordPress setting <strong>.Comment author must fill out name and email</strong>."
|
4610 |
msgstr ""
|
4611 |
|
4612 |
+
#: defaults.php:2898
|
4613 |
msgid "Enabled/Disabled the option Users must be logged in and registered to comment"
|
4614 |
msgstr ""
|
4615 |
|
4616 |
+
#: defaults.php:2899
|
4617 |
msgid "Changed the status of the WordPress setting <strong>Users must be registered and logged in to comment</strong>."
|
4618 |
msgstr ""
|
4619 |
|
4620 |
+
#: defaults.php:2908
|
4621 |
msgid "Enabled/Disabled the option to automatically close comments"
|
4622 |
msgstr ""
|
4623 |
|
4624 |
+
#: defaults.php:2909
|
4625 |
msgid "Changed the status of the WordPress setting <strong>Automatically close comments after %Value% days</strong>."
|
4626 |
msgstr ""
|
4627 |
|
4628 |
+
#: defaults.php:2918
|
4629 |
msgid "Changed the value of the option Automatically close comments"
|
4630 |
msgstr ""
|
4631 |
|
4632 |
+
#: defaults.php:2919
|
4633 |
msgid "Changed the value of the WordPress setting <strong>Automatically close comments after a number of days</strong> to %NewValue%."
|
4634 |
msgstr ""
|
4635 |
|
4636 |
+
#: defaults.php:2930
|
4637 |
msgid "Enabled/Disabled the option for comments to be manually approved"
|
4638 |
msgstr ""
|
4639 |
|
4640 |
+
#: defaults.php:2931
|
4641 |
msgid "Changed the value of the WordPress setting <strong>Comments must be manualy approved</strong>."
|
4642 |
msgstr ""
|
4643 |
|
4644 |
+
#: defaults.php:2940
|
4645 |
msgid "Enabled/Disabled the option for an author to have previously approved comments for the comments to appear"
|
4646 |
msgstr ""
|
4647 |
|
4648 |
+
#: defaults.php:2941
|
4649 |
msgid "Changed the value of the WordPress setting <strong>Comment author must have a previously approved comment</strong>."
|
4650 |
msgstr ""
|
4651 |
|
4652 |
+
#: defaults.php:2950
|
4653 |
msgid "Changed the number of links that a comment must have to be held in the queue"
|
4654 |
msgstr ""
|
4655 |
|
4656 |
+
#: defaults.php:2951
|
4657 |
msgid "Changed the value of the WordPress setting <strong>Hold a comment in the queue if it contains links</strong> to %NewValue% links."
|
4658 |
msgstr ""
|
4659 |
|
4660 |
+
#: defaults.php:2962
|
4661 |
msgid "Modified the list of keywords for comments moderation"
|
4662 |
msgstr ""
|
4663 |
|
4664 |
+
#: defaults.php:2963
|
4665 |
+
msgid "Modified the list of keywords for comments moderation in WordPress."
|
4666 |
msgstr ""
|
4667 |
|
4668 |
+
#: defaults.php:2972
|
4669 |
msgid "Modified the list of keywords for comments blacklisting"
|
4670 |
msgstr ""
|
4671 |
|
4672 |
+
#: defaults.php:2973
|
4673 |
msgid "Modified the list of <strong>Disallowed comment keys</strong> (keywords) for comments blacklisting in WordPress."
|
4674 |
msgstr ""
|
4675 |
|
4676 |
+
#: defaults.php:2982
|
4677 |
msgid "Option WordPress Address (URL) in WordPress settings changed"
|
4678 |
msgstr ""
|
4679 |
|
4680 |
+
#: defaults.php:2983
|
4681 |
msgid "Changed the <strong>WordPress address (URL)</strong> tp %new_url%."
|
4682 |
msgstr ""
|
4683 |
|
4684 |
+
#: defaults.php:2994
|
4685 |
msgid "Option Site Address (URL) in WordPress settings changed"
|
4686 |
msgstr ""
|
4687 |
|
4688 |
+
#: defaults.php:2995
|
4689 |
msgid "Changed the <strong>Site address (URL)</strong> to %new_url%."
|
4690 |
msgstr ""
|
4691 |
|
4692 |
+
#: defaults.php:3006
|
4693 |
msgid "Option Your homepage displays in WordPress settings changed"
|
4694 |
msgstr ""
|
4695 |
|
4696 |
+
#: defaults.php:3007
|
4697 |
msgid "Changed the <strong>Your homepage displays</strong> WordPress setting to %new_homepage%."
|
4698 |
msgstr ""
|
4699 |
|
4700 |
+
#: defaults.php:3018
|
4701 |
msgid "Option homepage in WordPress settings changed"
|
4702 |
msgstr ""
|
4703 |
|
4704 |
+
#: defaults.php:3019
|
4705 |
msgid "Changed the <strong>Homepage</strong> in the WordPress settings to %new_page%."
|
4706 |
msgstr ""
|
4707 |
|
4708 |
+
#: defaults.php:3021 defaults.php:3033
|
4709 |
msgid "Previous page"
|
4710 |
msgstr ""
|
4711 |
|
4712 |
+
#: defaults.php:3030
|
4713 |
msgid "Option posts page in WordPress settings changed"
|
4714 |
msgstr ""
|
4715 |
|
4716 |
+
#: defaults.php:3031
|
4717 |
msgid "Changed the <strong> Posts</strong> page in the WordPress settings to %new_page%."
|
4718 |
msgstr ""
|
4719 |
|
4720 |
+
#: defaults.php:3043
|
4721 |
msgid "Option Timezone in WordPress settings changed"
|
4722 |
msgstr ""
|
4723 |
|
4724 |
+
#: defaults.php:3044
|
4725 |
msgid "Changed the <strong>Timezone</strong> in the WordPress settings to %new_timezone%."
|
4726 |
msgstr ""
|
4727 |
|
4728 |
+
#: defaults.php:3046
|
4729 |
msgid "Previous timezone"
|
4730 |
msgstr ""
|
4731 |
|
4732 |
+
#: defaults.php:3055
|
4733 |
msgid "Option Date format in WordPress settings changed"
|
4734 |
msgstr ""
|
4735 |
|
4736 |
+
#: defaults.php:3056
|
4737 |
msgid "Changed the <strong>Date format</strong> in the WordPress settings to %new_date_format%."
|
4738 |
msgstr ""
|
4739 |
|
4740 |
+
#: defaults.php:3058 defaults.php:3070
|
4741 |
msgid "Previous format"
|
4742 |
msgstr ""
|
4743 |
|
4744 |
+
#: defaults.php:3067
|
4745 |
msgid "Option Time format in WordPress settings changed"
|
4746 |
msgstr ""
|
4747 |
|
4748 |
+
#: defaults.php:3068
|
4749 |
msgid "Changed the <strong>Time format</strong> in the WordPress settings to %new_time_format%."
|
4750 |
msgstr ""
|
4751 |
|
4752 |
+
#: defaults.php:3080
|
4753 |
msgid "Option Automatic updates setting changed"
|
4754 |
msgstr ""
|
4755 |
|
4756 |
+
#: defaults.php:3081
|
4757 |
msgid "Changed the <strong>Automatic updates</strong> setting."
|
4758 |
msgstr ""
|
4759 |
|
4760 |
+
#: defaults.php:3083
|
4761 |
msgid "New setting status"
|
4762 |
msgstr ""
|
4763 |
|
4764 |
+
#: defaults.php:3093
|
4765 |
msgid "Option Site Language setting changed"
|
4766 |
msgstr ""
|
4767 |
|
4768 |
+
#: defaults.php:3094
|
4769 |
msgid "Changed the <strong>Site Language</strong> to %new_value%."
|
4770 |
msgstr ""
|
4771 |
|
4772 |
+
#: defaults.php:3106
|
4773 |
+
msgid "Option Site Title changed"
|
4774 |
+
msgstr ""
|
4775 |
+
|
4776 |
+
#: defaults.php:3107
|
4777 |
+
msgid "Changed the <strong>Site Title</strong> to %new_value%."
|
4778 |
+
msgstr ""
|
4779 |
+
|
4780 |
+
#: defaults.php:3117
|
4781 |
msgid "Database Events"
|
4782 |
msgstr ""
|
4783 |
|
4784 |
+
#: defaults.php:3121
|
4785 |
msgid "Plugin created table"
|
4786 |
msgstr ""
|
4787 |
|
4788 |
+
#: defaults.php:3122
|
4789 |
msgid "The plugin %Plugin->Name% created this table in the database."
|
4790 |
msgstr ""
|
4791 |
|
4792 |
+
#: defaults.php:3124 defaults.php:3136 defaults.php:3148 defaults.php:3160
|
4793 |
+
#: defaults.php:3172
|
4794 |
msgid "Table"
|
4795 |
msgstr ""
|
4796 |
|
4797 |
+
#: defaults.php:3133
|
4798 |
msgid "Plugin modified table structure"
|
4799 |
msgstr ""
|
4800 |
|
4801 |
+
#: defaults.php:3134
|
4802 |
msgid "The plugin %Plugin->Name% modified the structure of a database table."
|
4803 |
msgstr ""
|
4804 |
|
4805 |
+
#: defaults.php:3145
|
4806 |
msgid "Plugin deleted table"
|
4807 |
msgstr ""
|
4808 |
|
4809 |
+
#: defaults.php:3146
|
4810 |
msgid "The plugin %Plugin->Name% deleted this table from the database."
|
4811 |
msgstr ""
|
4812 |
|
4813 |
+
#: defaults.php:3157
|
4814 |
msgid "Theme created tables"
|
4815 |
msgstr ""
|
4816 |
|
4817 |
+
#: defaults.php:3158
|
4818 |
msgid "The theme %Theme->Name% created this tables in the database."
|
4819 |
msgstr ""
|
4820 |
|
4821 |
+
#: defaults.php:3169
|
4822 |
msgid "Theme modified tables structure"
|
4823 |
msgstr ""
|
4824 |
|
4825 |
+
#: defaults.php:3170
|
4826 |
msgid "The theme %Theme->Name% modified the structure of this database table"
|
4827 |
msgstr ""
|
4828 |
|
4829 |
+
#: defaults.php:3181
|
4830 |
msgid "Theme deleted tables"
|
4831 |
msgstr ""
|
4832 |
|
4833 |
+
#: defaults.php:3182
|
4834 |
msgid "The theme %Theme->Name% deleted this table from the database."
|
4835 |
msgstr ""
|
4836 |
|
4837 |
+
#: defaults.php:3184 defaults.php:3196 defaults.php:3208 defaults.php:3220
|
4838 |
+
#: defaults.php:3232 defaults.php:3244 defaults.php:3256
|
4839 |
msgid "Tables"
|
4840 |
msgstr ""
|
4841 |
|
4842 |
+
#: defaults.php:3193
|
4843 |
msgid "Unknown component created tables"
|
4844 |
msgstr ""
|
4845 |
|
4846 |
+
#: defaults.php:3194
|
4847 |
msgid "An unknown component created these tables in the database."
|
4848 |
msgstr ""
|
4849 |
|
4850 |
+
#: defaults.php:3205
|
4851 |
msgid "Unknown component modified tables structure"
|
4852 |
msgstr ""
|
4853 |
|
4854 |
+
#: defaults.php:3206
|
4855 |
msgid "An unknown component modified the structure of these database tables."
|
4856 |
msgstr ""
|
4857 |
|
4858 |
+
#: defaults.php:3217
|
4859 |
msgid "Unknown component deleted tables"
|
4860 |
msgstr ""
|
4861 |
|
4862 |
+
#: defaults.php:3218
|
4863 |
msgid "An unknown component deleted these tables from the database."
|
4864 |
msgstr ""
|
4865 |
|
4866 |
+
#: defaults.php:3229
|
4867 |
msgid "WordPress created tables"
|
4868 |
msgstr ""
|
4869 |
|
4870 |
+
#: defaults.php:3230
|
4871 |
msgid "WordPress has created these tables in the database."
|
4872 |
msgstr ""
|
4873 |
|
4874 |
+
#: defaults.php:3241
|
4875 |
msgid "WordPress modified tables structure"
|
4876 |
msgstr ""
|
4877 |
|
4878 |
+
#: defaults.php:3242
|
4879 |
msgid "WordPress modified the structure of these database tables."
|
4880 |
msgstr ""
|
4881 |
|
4882 |
+
#: defaults.php:3253
|
4883 |
msgid "WordPress deleted tables"
|
4884 |
msgstr ""
|
4885 |
|
4886 |
+
#: defaults.php:3254
|
4887 |
msgid "WordPress deleted these tables from the database."
|
4888 |
msgstr ""
|
4889 |
|
4890 |
+
#: defaults.php:3265
|
4891 |
msgid "Multisite Network Sites"
|
4892 |
msgstr ""
|
4893 |
|
4894 |
+
#: defaults.php:3266
|
4895 |
+
msgid "MultiSite"
|
4896 |
+
msgstr ""
|
4897 |
+
|
4898 |
+
#: defaults.php:3270
|
4899 |
msgid "New site added on the network"
|
4900 |
msgstr ""
|
4901 |
|
4902 |
+
#: defaults.php:3271
|
4903 |
msgid "Added the new site %SiteName% to the network."
|
4904 |
msgstr ""
|
4905 |
|
4906 |
+
#: defaults.php:3282
|
4907 |
msgid "Existing site archived"
|
4908 |
msgstr ""
|
4909 |
|
4910 |
+
#: defaults.php:3283
|
4911 |
msgid "Archived the site %SiteName% on the network."
|
4912 |
msgstr ""
|
4913 |
|
4914 |
+
#: defaults.php:3294
|
4915 |
msgid "Archived site has been unarchived"
|
4916 |
msgstr ""
|
4917 |
|
4918 |
+
#: defaults.php:3295
|
4919 |
msgid "Unarchived the site %SiteName%."
|
4920 |
msgstr ""
|
4921 |
|
4922 |
+
#: defaults.php:3306
|
4923 |
msgid "Deactivated site has been activated"
|
4924 |
msgstr ""
|
4925 |
|
4926 |
+
#: defaults.php:3307
|
4927 |
msgid "Activated the site %SiteName% on the network."
|
4928 |
msgstr ""
|
4929 |
|
4930 |
+
#: defaults.php:3318
|
4931 |
msgid "Site has been deactivated"
|
4932 |
msgstr ""
|
4933 |
|
4934 |
+
#: defaults.php:3319
|
4935 |
msgid "Deactiveated the site %SiteName% on the network."
|
4936 |
msgstr ""
|
4937 |
|
4938 |
+
#: defaults.php:3330
|
4939 |
msgid "Existing site deleted from network"
|
4940 |
msgstr ""
|
4941 |
|
4942 |
+
#: defaults.php:3331
|
4943 |
msgid "The site: %SiteName%."
|
4944 |
msgstr ""
|
4945 |
|
4946 |
+
#: defaults.php:3342
|
4947 |
msgid "Allow site administrators to add new users to their sites settings changed"
|
4948 |
msgstr ""
|
4949 |
|
4950 |
+
#: defaults.php:3343
|
4951 |
msgid "Changed the status of the network setting <strong>Allow site administrators to add new users to their sites</strong>."
|
4952 |
msgstr ""
|
4953 |
|
4954 |
+
#: defaults.php:3352
|
4955 |
msgid "Site upload space settings changed"
|
4956 |
msgstr ""
|
4957 |
|
4958 |
+
#: defaults.php:3353
|
4959 |
msgid "Changed the status of the network setting <strong>Site upload space</strong> (to limit space allocated for each site's upload directory)."
|
4960 |
msgstr ""
|
4961 |
|
4962 |
+
#: defaults.php:3362
|
4963 |
msgid "Site upload space file size settings changed"
|
4964 |
msgstr ""
|
4965 |
|
4966 |
+
#: defaults.php:3363
|
4967 |
msgid "Changed the file size in the <strong>Site upload space</strong> network setting to %new_value%."
|
4968 |
msgstr ""
|
4969 |
|
4970 |
+
#: defaults.php:3365
|
4971 |
msgid "Previous size (MB)"
|
4972 |
msgstr ""
|
4973 |
|
4974 |
+
#: defaults.php:3374
|
4975 |
msgid "Site Upload file types settings changed"
|
4976 |
msgstr ""
|
4977 |
|
4978 |
+
#: defaults.php:3375
|
4979 |
msgid "Changed the network setting <strong>Upload file types (list of allowed file types)</strong>."
|
4980 |
msgstr ""
|
4981 |
|
4982 |
+
#: defaults.php:3387
|
4983 |
msgid "Site Max upload file size settings changed"
|
4984 |
msgstr ""
|
4985 |
|
4986 |
+
#: defaults.php:3388
|
4987 |
msgid "Changed the <strong>Max upload file size</strong> network setting to %new_value%."
|
4988 |
msgstr ""
|
4989 |
|
4990 |
+
#: defaults.php:3390
|
4991 |
msgid "Previous size (KB)"
|
4992 |
msgstr ""
|
4993 |
|
4994 |
+
#: defaults.php:3399
|
4995 |
msgid "Allow new registrations settings changed"
|
4996 |
msgstr ""
|
4997 |
|
4998 |
+
#: defaults.php:3400
|
4999 |
msgid "Changed the <strong>Allow new registrations</strong> setting to %new_setting%."
|
5000 |
msgstr ""
|
5001 |
|
5002 |
+
#: defaults.php:3416
|
5003 |
+
msgid "File Changes"
|
5004 |
+
msgstr ""
|
5005 |
+
|
5006 |
+
#: defaults.php:3417
|
5007 |
+
msgid "Monitor File Changes"
|
5008 |
+
msgstr ""
|
5009 |
+
|
5010 |
+
#: defaults.php:3421
|
5011 |
msgid "Dummy"
|
5012 |
msgstr ""
|
5013 |
|
5014 |
+
#: third-party/vendor/deliciousbrains/wp-background-processing/classes/wp-background-process.php:371
|
5015 |
+
#, php-format
|
5016 |
+
msgid "Every %d Minutes"
|
5017 |
+
msgstr ""
|
5018 |
+
|
5019 |
+
#: wp-security-audit-log.php:861 wp-security-audit-log.php:889
|
5020 |
#, php-format
|
5021 |
msgid "Hey %s"
|
5022 |
msgstr ""
|
5023 |
|
5024 |
+
#: wp-security-audit-log.php:865
|
5025 |
msgid "Never miss an important update! Opt-in to our security and feature updates notifications, and non-sensitive diagnostic tracking with freemius.com."
|
5026 |
msgstr ""
|
5027 |
|
5028 |
+
#: wp-security-audit-log.php:866 wp-security-audit-log.php:901
|
5029 |
msgid "Note: "
|
5030 |
msgstr ""
|
5031 |
|
5032 |
+
#: wp-security-audit-log.php:867 wp-security-audit-log.php:902
|
5033 |
msgid "NO ACTIVITY LOG ACTIVITY & DATA IS SENT BACK TO OUR SERVERS."
|
5034 |
msgstr ""
|
5035 |
|
5036 |
+
#: wp-security-audit-log.php:895
|
5037 |
#, php-format
|
5038 |
msgid "Please help us improve %1$s! If you opt-in, some non-sensitive data about your usage of %2$s will be sent to %3$s, a diagnostic tracking service we use. If you skip this, that's okay! %2$s will still work just fine."
|
5039 |
msgstr ""
|
5040 |
|
5041 |
+
#: wp-security-audit-log.php:947
|
5042 |
#, php-format
|
5043 |
msgid "You need to activate the licence key to use WP Activity Log Premium. %2$s"
|
5044 |
msgstr ""
|
5045 |
|
5046 |
+
#: wp-security-audit-log.php:948
|
5047 |
msgid "Activate the licence key now"
|
5048 |
msgstr ""
|
5049 |
|
5050 |
+
#: wp-security-audit-log.php:972
|
5051 |
#, php-format
|
5052 |
msgid "%s You need to renew your license to continue using premium features."
|
5053 |
msgstr ""
|
5054 |
|
5055 |
+
#: wp-security-audit-log.php:975
|
5056 |
#, php-format
|
5057 |
msgid "The license is limited to %s sub-sites. You need to upgrade your license to cover all the sub-sites on this network."
|
5058 |
msgstr ""
|
5059 |
|
5060 |
+
#: wp-security-audit-log.php:1077
|
5061 |
msgid "Error: You do not have sufficient permissions to disable this custom field."
|
5062 |
msgstr ""
|
5063 |
|
5064 |
+
#: wp-security-audit-log.php:1125
|
5065 |
#, php-format
|
5066 |
msgid "Custom field %s is no longer being monitored."
|
5067 |
msgstr ""
|
5068 |
|
5069 |
+
#: wp-security-audit-log.php:1130
|
5070 |
#, php-format
|
5071 |
msgid "Enable the monitoring of this custom field again from the %s tab in the plugin settings."
|
5072 |
msgstr ""
|
5073 |
|
5074 |
+
#: wp-security-audit-log.php:1131
|
5075 |
msgid "Excluded Objects"
|
5076 |
msgstr ""
|
5077 |
|
5078 |
+
#: wp-security-audit-log.php:1144
|
5079 |
msgid "Error: You do not have sufficient permissions to disable this alert."
|
5080 |
msgstr ""
|
5081 |
|
5082 |
+
#: wp-security-audit-log.php:1168
|
5083 |
#, php-format
|
5084 |
msgid "Alert %1$s is no longer being monitored.<br /> %2$s"
|
5085 |
msgstr ""
|
5086 |
|
5087 |
+
#: wp-security-audit-log.php:1168
|
5088 |
msgid "You can enable this alert again from the Enable/Disable Alerts node in the plugin menu."
|
5089 |
msgstr ""
|
5090 |
|
5091 |
+
#: wp-security-audit-log.php:1249
|
5092 |
#, php-format
|
5093 |
msgid "You are using a version of PHP that is older than %s, which is no longer supported."
|
5094 |
msgstr ""
|
5095 |
|
5096 |
+
#: wp-security-audit-log.php:1251
|
5097 |
msgid "Contact us on <a href=\"mailto:plugins@wpwhitesecurity.com\">plugins@wpwhitesecurity.com</a> to help you switch the version of PHP you are using."
|
5098 |
msgstr ""
|
5099 |
|
5100 |
+
#: wp-security-audit-log.php:1256
|
5101 |
#, php-format
|
5102 |
msgid "Please install the %s plugin on the MainWP dashboard."
|
5103 |
msgstr ""
|
5104 |
|
5105 |
+
#: wp-security-audit-log.php:1256
|
5106 |
msgid "Activity Log for MainWP"
|
5107 |
msgstr ""
|
5108 |
|
5109 |
+
#: wp-security-audit-log.php:1258
|
5110 |
#, php-format
|
5111 |
msgid "The WP Activity Log should be installed on the child sites only. Refer to the %s for more information."
|
5112 |
msgstr ""
|
5113 |
|
5114 |
+
#: wp-security-audit-log.php:1258
|
5115 |
msgid "getting started guide"
|
5116 |
msgstr ""
|
5117 |
|
5118 |
+
#: wp-security-audit-log.php:1771
|
5119 |
msgid "For security and auditing purposes, a record of all of your logged-in actions and changes within the WordPress dashboard will be recorded in an activity log with the <a href=\"https://wpactivitylog.com/\" target=\"_blank\">WP Activity Log plugin</a>. The audit log also includes the IP address where you accessed this site from."
|
5120 |
msgstr ""
|
5121 |
|
5122 |
+
#: wp-security-audit-log.php:1790
|
5123 |
msgid "Every 6 hours"
|
5124 |
msgstr ""
|
5125 |
|
5126 |
+
#: wp-security-audit-log.php:1794
|
5127 |
msgid "Every 45 minutes"
|
5128 |
msgstr ""
|
5129 |
|
5130 |
+
#: wp-security-audit-log.php:1798
|
5131 |
msgid "Every 30 minutes"
|
5132 |
msgstr ""
|
5133 |
|
5134 |
+
#: wp-security-audit-log.php:1802
|
5135 |
msgid "Every 15 minutes"
|
5136 |
msgstr ""
|
5137 |
|
5138 |
+
#: wp-security-audit-log.php:1806
|
5139 |
msgid "Every 10 minutes"
|
5140 |
msgstr ""
|
5141 |
|
5142 |
+
#: wp-security-audit-log.php:1810
|
5143 |
msgid "Every 1 minute"
|
5144 |
msgstr ""
|
5145 |
|
5146 |
+
#: wp-security-audit-log.php:1824
|
5147 |
#, php-format
|
5148 |
msgid "Method %1$s is deprecated since version %2$s!"
|
5149 |
msgstr ""
|
license.txt
ADDED
@@ -0,0 +1,674 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 3, 29 June 2007
|
3 |
+
|
4 |
+
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
5 |
+
Everyone is permitted to copy and distribute verbatim copies
|
6 |
+
of this license document, but changing it is not allowed.
|
7 |
+
|
8 |
+
Preamble
|
9 |
+
|
10 |
+
The GNU General Public License is a free, copyleft license for
|
11 |
+
software and other kinds of works.
|
12 |
+
|
13 |
+
The licenses for most software and other practical works are designed
|
14 |
+
to take away your freedom to share and change the works. By contrast,
|
15 |
+
the GNU General Public License is intended to guarantee your freedom to
|
16 |
+
share and change all versions of a program--to make sure it remains free
|
17 |
+
software for all its users. We, the Free Software Foundation, use the
|
18 |
+
GNU General Public License for most of our software; it applies also to
|
19 |
+
any other work released this way by its authors. You can apply it to
|
20 |
+
your programs, too.
|
21 |
+
|
22 |
+
When we speak of free software, we are referring to freedom, not
|
23 |
+
price. Our General Public Licenses are designed to make sure that you
|
24 |
+
have the freedom to distribute copies of free software (and charge for
|
25 |
+
them if you wish), that you receive source code or can get it if you
|
26 |
+
want it, that you can change the software or use pieces of it in new
|
27 |
+
free programs, and that you know you can do these things.
|
28 |
+
|
29 |
+
To protect your rights, we need to prevent others from denying you
|
30 |
+
these rights or asking you to surrender the rights. Therefore, you have
|
31 |
+
certain responsibilities if you distribute copies of the software, or if
|
32 |
+
you modify it: responsibilities to respect the freedom of others.
|
33 |
+
|
34 |
+
For example, if you distribute copies of such a program, whether
|
35 |
+
gratis or for a fee, you must pass on to the recipients the same
|
36 |
+
freedoms that you received. You must make sure that they, too, receive
|
37 |
+
or can get the source code. And you must show them these terms so they
|
38 |
+
know their rights.
|
39 |
+
|
40 |
+
Developers that use the GNU GPL protect your rights with two steps:
|
41 |
+
(1) assert copyright on the software, and (2) offer you this License
|
42 |
+
giving you legal permission to copy, distribute and/or modify it.
|
43 |
+
|
44 |
+
For the developers' and authors' protection, the GPL clearly explains
|
45 |
+
that there is no warranty for this free software. For both users' and
|
46 |
+
authors' sake, the GPL requires that modified versions be marked as
|
47 |
+
changed, so that their problems will not be attributed erroneously to
|
48 |
+
authors of previous versions.
|
49 |
+
|
50 |
+
Some devices are designed to deny users access to install or run
|
51 |
+
modified versions of the software inside them, although the manufacturer
|
52 |
+
can do so. This is fundamentally incompatible with the aim of
|
53 |
+
protecting users' freedom to change the software. The systematic
|
54 |
+
pattern of such abuse occurs in the area of products for individuals to
|
55 |
+
use, which is precisely where it is most unacceptable. Therefore, we
|
56 |
+
have designed this version of the GPL to prohibit the practice for those
|
57 |
+
products. If such problems arise substantially in other domains, we
|
58 |
+
stand ready to extend this provision to those domains in future versions
|
59 |
+
of the GPL, as needed to protect the freedom of users.
|
60 |
+
|
61 |
+
Finally, every program is threatened constantly by software patents.
|
62 |
+
States should not allow patents to restrict development and use of
|
63 |
+
software on general-purpose computers, but in those that do, we wish to
|
64 |
+
avoid the special danger that patents applied to a free program could
|
65 |
+
make it effectively proprietary. To prevent this, the GPL assures that
|
66 |
+
patents cannot be used to render the program non-free.
|
67 |
+
|
68 |
+
The precise terms and conditions for copying, distribution and
|
69 |
+
modification follow.
|
70 |
+
|
71 |
+
TERMS AND CONDITIONS
|
72 |
+
|
73 |
+
0. Definitions.
|
74 |
+
|
75 |
+
"This License" refers to version 3 of the GNU General Public License.
|
76 |
+
|
77 |
+
"Copyright" also means copyright-like laws that apply to other kinds of
|
78 |
+
works, such as semiconductor masks.
|
79 |
+
|
80 |
+
"The Program" refers to any copyrightable work licensed under this
|
81 |
+
License. Each licensee is addressed as "you". "Licensees" and
|
82 |
+
"recipients" may be individuals or organizations.
|
83 |
+
|
84 |
+
To "modify" a work means to copy from or adapt all or part of the work
|
85 |
+
in a fashion requiring copyright permission, other than the making of an
|
86 |
+
exact copy. The resulting work is called a "modified version" of the
|
87 |
+
earlier work or a work "based on" the earlier work.
|
88 |
+
|
89 |
+
A "covered work" means either the unmodified Program or a work based
|
90 |
+
on the Program.
|
91 |
+
|
92 |
+
To "propagate" a work means to do anything with it that, without
|
93 |
+
permission, would make you directly or secondarily liable for
|
94 |
+
infringement under applicable copyright law, except executing it on a
|
95 |
+
computer or modifying a private copy. Propagation includes copying,
|
96 |
+
distribution (with or without modification), making available to the
|
97 |
+
public, and in some countries other activities as well.
|
98 |
+
|
99 |
+
To "convey" a work means any kind of propagation that enables other
|
100 |
+
parties to make or receive copies. Mere interaction with a user through
|
101 |
+
a computer network, with no transfer of a copy, is not conveying.
|
102 |
+
|
103 |
+
An interactive user interface displays "Appropriate Legal Notices"
|
104 |
+
to the extent that it includes a convenient and prominently visible
|
105 |
+
feature that (1) displays an appropriate copyright notice, and (2)
|
106 |
+
tells the user that there is no warranty for the work (except to the
|
107 |
+
extent that warranties are provided), that licensees may convey the
|
108 |
+
work under this License, and how to view a copy of this License. If
|
109 |
+
the interface presents a list of user commands or options, such as a
|
110 |
+
menu, a prominent item in the list meets this criterion.
|
111 |
+
|
112 |
+
1. Source Code.
|
113 |
+
|
114 |
+
The "source code" for a work means the preferred form of the work
|
115 |
+
for making modifications to it. "Object code" means any non-source
|
116 |
+
form of a work.
|
117 |
+
|
118 |
+
A "Standard Interface" means an interface that either is an official
|
119 |
+
standard defined by a recognized standards body, or, in the case of
|
120 |
+
interfaces specified for a particular programming language, one that
|
121 |
+
is widely used among developers working in that language.
|
122 |
+
|
123 |
+
The "System Libraries" of an executable work include anything, other
|
124 |
+
than the work as a whole, that (a) is included in the normal form of
|
125 |
+
packaging a Major Component, but which is not part of that Major
|
126 |
+
Component, and (b) serves only to enable use of the work with that
|
127 |
+
Major Component, or to implement a Standard Interface for which an
|
128 |
+
implementation is available to the public in source code form. A
|
129 |
+
"Major Component", in this context, means a major essential component
|
130 |
+
(kernel, window system, and so on) of the specific operating system
|
131 |
+
(if any) on which the executable work runs, or a compiler used to
|
132 |
+
produce the work, or an object code interpreter used to run it.
|
133 |
+
|
134 |
+
The "Corresponding Source" for a work in object code form means all
|
135 |
+
the source code needed to generate, install, and (for an executable
|
136 |
+
work) run the object code and to modify the work, including scripts to
|
137 |
+
control those activities. However, it does not include the work's
|
138 |
+
System Libraries, or general-purpose tools or generally available free
|
139 |
+
programs which are used unmodified in performing those activities but
|
140 |
+
which are not part of the work. For example, Corresponding Source
|
141 |
+
includes interface definition files associated with source files for
|
142 |
+
the work, and the source code for shared libraries and dynamically
|
143 |
+
linked subprograms that the work is specifically designed to require,
|
144 |
+
such as by intimate data communication or control flow between those
|
145 |
+
subprograms and other parts of the work.
|
146 |
+
|
147 |
+
The Corresponding Source need not include anything that users
|
148 |
+
can regenerate automatically from other parts of the Corresponding
|
149 |
+
Source.
|
150 |
+
|
151 |
+
The Corresponding Source for a work in source code form is that
|
152 |
+
same work.
|
153 |
+
|
154 |
+
2. Basic Permissions.
|
155 |
+
|
156 |
+
All rights granted under this License are granted for the term of
|
157 |
+
copyright on the Program, and are irrevocable provided the stated
|
158 |
+
conditions are met. This License explicitly affirms your unlimited
|
159 |
+
permission to run the unmodified Program. The output from running a
|
160 |
+
covered work is covered by this License only if the output, given its
|
161 |
+
content, constitutes a covered work. This License acknowledges your
|
162 |
+
rights of fair use or other equivalent, as provided by copyright law.
|
163 |
+
|
164 |
+
You may make, run and propagate covered works that you do not
|
165 |
+
convey, without conditions so long as your license otherwise remains
|
166 |
+
in force. You may convey covered works to others for the sole purpose
|
167 |
+
of having them make modifications exclusively for you, or provide you
|
168 |
+
with facilities for running those works, provided that you comply with
|
169 |
+
the terms of this License in conveying all material for which you do
|
170 |
+
not control copyright. Those thus making or running the covered works
|
171 |
+
for you must do so exclusively on your behalf, under your direction
|
172 |
+
and control, on terms that prohibit them from making any copies of
|
173 |
+
your copyrighted material outside their relationship with you.
|
174 |
+
|
175 |
+
Conveying under any other circumstances is permitted solely under
|
176 |
+
the conditions stated below. Sublicensing is not allowed; section 10
|
177 |
+
makes it unnecessary.
|
178 |
+
|
179 |
+
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
180 |
+
|
181 |
+
No covered work shall be deemed part of an effective technological
|
182 |
+
measure under any applicable law fulfilling obligations under article
|
183 |
+
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
184 |
+
similar laws prohibiting or restricting circumvention of such
|
185 |
+
measures.
|
186 |
+
|
187 |
+
When you convey a covered work, you waive any legal power to forbid
|
188 |
+
circumvention of technological measures to the extent such circumvention
|
189 |
+
is effected by exercising rights under this License with respect to
|
190 |
+
the covered work, and you disclaim any intention to limit operation or
|
191 |
+
modification of the work as a means of enforcing, against the work's
|
192 |
+
users, your or third parties' legal rights to forbid circumvention of
|
193 |
+
technological measures.
|
194 |
+
|
195 |
+
4. Conveying Verbatim Copies.
|
196 |
+
|
197 |
+
You may convey verbatim copies of the Program's source code as you
|
198 |
+
receive it, in any medium, provided that you conspicuously and
|
199 |
+
appropriately publish on each copy an appropriate copyright notice;
|
200 |
+
keep intact all notices stating that this License and any
|
201 |
+
non-permissive terms added in accord with section 7 apply to the code;
|
202 |
+
keep intact all notices of the absence of any warranty; and give all
|
203 |
+
recipients a copy of this License along with the Program.
|
204 |
+
|
205 |
+
You may charge any price or no price for each copy that you convey,
|
206 |
+
and you may offer support or warranty protection for a fee.
|
207 |
+
|
208 |
+
5. Conveying Modified Source Versions.
|
209 |
+
|
210 |
+
You may convey a work based on the Program, or the modifications to
|
211 |
+
produce it from the Program, in the form of source code under the
|
212 |
+
terms of section 4, provided that you also meet all of these conditions:
|
213 |
+
|
214 |
+
a) The work must carry prominent notices stating that you modified
|
215 |
+
it, and giving a relevant date.
|
216 |
+
|
217 |
+
b) The work must carry prominent notices stating that it is
|
218 |
+
released under this License and any conditions added under section
|
219 |
+
7. This requirement modifies the requirement in section 4 to
|
220 |
+
"keep intact all notices".
|
221 |
+
|
222 |
+
c) You must license the entire work, as a whole, under this
|
223 |
+
License to anyone who comes into possession of a copy. This
|
224 |
+
License will therefore apply, along with any applicable section 7
|
225 |
+
additional terms, to the whole of the work, and all its parts,
|
226 |
+
regardless of how they are packaged. This License gives no
|
227 |
+
permission to license the work in any other way, but it does not
|
228 |
+
invalidate such permission if you have separately received it.
|
229 |
+
|
230 |
+
d) If the work has interactive user interfaces, each must display
|
231 |
+
Appropriate Legal Notices; however, if the Program has interactive
|
232 |
+
interfaces that do not display Appropriate Legal Notices, your
|
233 |
+
work need not make them do so.
|
234 |
+
|
235 |
+
A compilation of a covered work with other separate and independent
|
236 |
+
works, which are not by their nature extensions of the covered work,
|
237 |
+
and which are not combined with it such as to form a larger program,
|
238 |
+
in or on a volume of a storage or distribution medium, is called an
|
239 |
+
"aggregate" if the compilation and its resulting copyright are not
|
240 |
+
used to limit the access or legal rights of the compilation's users
|
241 |
+
beyond what the individual works permit. Inclusion of a covered work
|
242 |
+
in an aggregate does not cause this License to apply to the other
|
243 |
+
parts of the aggregate.
|
244 |
+
|
245 |
+
6. Conveying Non-Source Forms.
|
246 |
+
|
247 |
+
You may convey a covered work in object code form under the terms
|
248 |
+
of sections 4 and 5, provided that you also convey the
|
249 |
+
machine-readable Corresponding Source under the terms of this License,
|
250 |
+
in one of these ways:
|
251 |
+
|
252 |
+
a) Convey the object code in, or embodied in, a physical product
|
253 |
+
(including a physical distribution medium), accompanied by the
|
254 |
+
Corresponding Source fixed on a durable physical medium
|
255 |
+
customarily used for software interchange.
|
256 |
+
|
257 |
+
b) Convey the object code in, or embodied in, a physical product
|
258 |
+
(including a physical distribution medium), accompanied by a
|
259 |
+
written offer, valid for at least three years and valid for as
|
260 |
+
long as you offer spare parts or customer support for that product
|
261 |
+
model, to give anyone who possesses the object code either (1) a
|
262 |
+
copy of the Corresponding Source for all the software in the
|
263 |
+
product that is covered by this License, on a durable physical
|
264 |
+
medium customarily used for software interchange, for a price no
|
265 |
+
more than your reasonable cost of physically performing this
|
266 |
+
conveying of source, or (2) access to copy the
|
267 |
+
Corresponding Source from a network server at no charge.
|
268 |
+
|
269 |
+
c) Convey individual copies of the object code with a copy of the
|
270 |
+
written offer to provide the Corresponding Source. This
|
271 |
+
alternative is allowed only occasionally and noncommercially, and
|
272 |
+
only if you received the object code with such an offer, in accord
|
273 |
+
with subsection 6b.
|
274 |
+
|
275 |
+
d) Convey the object code by offering access from a designated
|
276 |
+
place (gratis or for a charge), and offer equivalent access to the
|
277 |
+
Corresponding Source in the same way through the same place at no
|
278 |
+
further charge. You need not require recipients to copy the
|
279 |
+
Corresponding Source along with the object code. If the place to
|
280 |
+
copy the object code is a network server, the Corresponding Source
|
281 |
+
may be on a different server (operated by you or a third party)
|
282 |
+
that supports equivalent copying facilities, provided you maintain
|
283 |
+
clear directions next to the object code saying where to find the
|
284 |
+
Corresponding Source. Regardless of what server hosts the
|
285 |
+
Corresponding Source, you remain obligated to ensure that it is
|
286 |
+
available for as long as needed to satisfy these requirements.
|
287 |
+
|
288 |
+
e) Convey the object code using peer-to-peer transmission, provided
|
289 |
+
you inform other peers where the object code and Corresponding
|
290 |
+
Source of the work are being offered to the general public at no
|
291 |
+
charge under subsection 6d.
|
292 |
+
|
293 |
+
A separable portion of the object code, whose source code is excluded
|
294 |
+
from the Corresponding Source as a System Library, need not be
|
295 |
+
included in conveying the object code work.
|
296 |
+
|
297 |
+
A "User Product" is either (1) a "consumer product", which means any
|
298 |
+
tangible personal property which is normally used for personal, family,
|
299 |
+
or household purposes, or (2) anything designed or sold for incorporation
|
300 |
+
into a dwelling. In determining whether a product is a consumer product,
|
301 |
+
doubtful cases shall be resolved in favor of coverage. For a particular
|
302 |
+
product received by a particular user, "normally used" refers to a
|
303 |
+
typical or common use of that class of product, regardless of the status
|
304 |
+
of the particular user or of the way in which the particular user
|
305 |
+
actually uses, or expects or is expected to use, the product. A product
|
306 |
+
is a consumer product regardless of whether the product has substantial
|
307 |
+
commercial, industrial or non-consumer uses, unless such uses represent
|
308 |
+
the only significant mode of use of the product.
|
309 |
+
|
310 |
+
"Installation Information" for a User Product means any methods,
|
311 |
+
procedures, authorization keys, or other information required to install
|
312 |
+
and execute modified versions of a covered work in that User Product from
|
313 |
+
a modified version of its Corresponding Source. The information must
|
314 |
+
suffice to ensure that the continued functioning of the modified object
|
315 |
+
code is in no case prevented or interfered with solely because
|
316 |
+
modification has been made.
|
317 |
+
|
318 |
+
If you convey an object code work under this section in, or with, or
|
319 |
+
specifically for use in, a User Product, and the conveying occurs as
|
320 |
+
part of a transaction in which the right of possession and use of the
|
321 |
+
User Product is transferred to the recipient in perpetuity or for a
|
322 |
+
fixed term (regardless of how the transaction is characterized), the
|
323 |
+
Corresponding Source conveyed under this section must be accompanied
|
324 |
+
by the Installation Information. But this requirement does not apply
|
325 |
+
if neither you nor any third party retains the ability to install
|
326 |
+
modified object code on the User Product (for example, the work has
|
327 |
+
been installed in ROM).
|
328 |
+
|
329 |
+
The requirement to provide Installation Information does not include a
|
330 |
+
requirement to continue to provide support service, warranty, or updates
|
331 |
+
for a work that has been modified or installed by the recipient, or for
|
332 |
+
the User Product in which it has been modified or installed. Access to a
|
333 |
+
network may be denied when the modification itself materially and
|
334 |
+
adversely affects the operation of the network or violates the rules and
|
335 |
+
protocols for communication across the network.
|
336 |
+
|
337 |
+
Corresponding Source conveyed, and Installation Information provided,
|
338 |
+
in accord with this section must be in a format that is publicly
|
339 |
+
documented (and with an implementation available to the public in
|
340 |
+
source code form), and must require no special password or key for
|
341 |
+
unpacking, reading or copying.
|
342 |
+
|
343 |
+
7. Additional Terms.
|
344 |
+
|
345 |
+
"Additional permissions" are terms that supplement the terms of this
|
346 |
+
License by making exceptions from one or more of its conditions.
|
347 |
+
Additional permissions that are applicable to the entire Program shall
|
348 |
+
be treated as though they were included in this License, to the extent
|
349 |
+
that they are valid under applicable law. If additional permissions
|
350 |
+
apply only to part of the Program, that part may be used separately
|
351 |
+
under those permissions, but the entire Program remains governed by
|
352 |
+
this License without regard to the additional permissions.
|
353 |
+
|
354 |
+
When you convey a copy of a covered work, you may at your option
|
355 |
+
remove any additional permissions from that copy, or from any part of
|
356 |
+
it. (Additional permissions may be written to require their own
|
357 |
+
removal in certain cases when you modify the work.) You may place
|
358 |
+
additional permissions on material, added by you to a covered work,
|
359 |
+
for which you have or can give appropriate copyright permission.
|
360 |
+
|
361 |
+
Notwithstanding any other provision of this License, for material you
|
362 |
+
add to a covered work, you may (if authorized by the copyright holders of
|
363 |
+
that material) supplement the terms of this License with terms:
|
364 |
+
|
365 |
+
a) Disclaiming warranty or limiting liability differently from the
|
366 |
+
terms of sections 15 and 16 of this License; or
|
367 |
+
|
368 |
+
b) Requiring preservation of specified reasonable legal notices or
|
369 |
+
author attributions in that material or in the Appropriate Legal
|
370 |
+
Notices displayed by works containing it; or
|
371 |
+
|
372 |
+
c) Prohibiting misrepresentation of the origin of that material, or
|
373 |
+
requiring that modified versions of such material be marked in
|
374 |
+
reasonable ways as different from the original version; or
|
375 |
+
|
376 |
+
d) Limiting the use for publicity purposes of names of licensors or
|
377 |
+
authors of the material; or
|
378 |
+
|
379 |
+
e) Declining to grant rights under trademark law for use of some
|
380 |
+
trade names, trademarks, or service marks; or
|
381 |
+
|
382 |
+
f) Requiring indemnification of licensors and authors of that
|
383 |
+
material by anyone who conveys the material (or modified versions of
|
384 |
+
it) with contractual assumptions of liability to the recipient, for
|
385 |
+
any liability that these contractual assumptions directly impose on
|
386 |
+
those licensors and authors.
|
387 |
+
|
388 |
+
All other non-permissive additional terms are considered "further
|
389 |
+
restrictions" within the meaning of section 10. If the Program as you
|
390 |
+
received it, or any part of it, contains a notice stating that it is
|
391 |
+
governed by this License along with a term that is a further
|
392 |
+
restriction, you may remove that term. If a license document contains
|
393 |
+
a further restriction but permits relicensing or conveying under this
|
394 |
+
License, you may add to a covered work material governed by the terms
|
395 |
+
of that license document, provided that the further restriction does
|
396 |
+
not survive such relicensing or conveying.
|
397 |
+
|
398 |
+
If you add terms to a covered work in accord with this section, you
|
399 |
+
must place, in the relevant source files, a statement of the
|
400 |
+
additional terms that apply to those files, or a notice indicating
|
401 |
+
where to find the applicable terms.
|
402 |
+
|
403 |
+
Additional terms, permissive or non-permissive, may be stated in the
|
404 |
+
form of a separately written license, or stated as exceptions;
|
405 |
+
the above requirements apply either way.
|
406 |
+
|
407 |
+
8. Termination.
|
408 |
+
|
409 |
+
You may not propagate or modify a covered work except as expressly
|
410 |
+
provided under this License. Any attempt otherwise to propagate or
|
411 |
+
modify it is void, and will automatically terminate your rights under
|
412 |
+
this License (including any patent licenses granted under the third
|
413 |
+
paragraph of section 11).
|
414 |
+
|
415 |
+
However, if you cease all violation of this License, then your
|
416 |
+
license from a particular copyright holder is reinstated (a)
|
417 |
+
provisionally, unless and until the copyright holder explicitly and
|
418 |
+
finally terminates your license, and (b) permanently, if the copyright
|
419 |
+
holder fails to notify you of the violation by some reasonable means
|
420 |
+
prior to 60 days after the cessation.
|
421 |
+
|
422 |
+
Moreover, your license from a particular copyright holder is
|
423 |
+
reinstated permanently if the copyright holder notifies you of the
|
424 |
+
violation by some reasonable means, this is the first time you have
|
425 |
+
received notice of violation of this License (for any work) from that
|
426 |
+
copyright holder, and you cure the violation prior to 30 days after
|
427 |
+
your receipt of the notice.
|
428 |
+
|
429 |
+
Termination of your rights under this section does not terminate the
|
430 |
+
licenses of parties who have received copies or rights from you under
|
431 |
+
this License. If your rights have been terminated and not permanently
|
432 |
+
reinstated, you do not qualify to receive new licenses for the same
|
433 |
+
material under section 10.
|
434 |
+
|
435 |
+
9. Acceptance Not Required for Having Copies.
|
436 |
+
|
437 |
+
You are not required to accept this License in order to receive or
|
438 |
+
run a copy of the Program. Ancillary propagation of a covered work
|
439 |
+
occurring solely as a consequence of using peer-to-peer transmission
|
440 |
+
to receive a copy likewise does not require acceptance. However,
|
441 |
+
nothing other than this License grants you permission to propagate or
|
442 |
+
modify any covered work. These actions infringe copyright if you do
|
443 |
+
not accept this License. Therefore, by modifying or propagating a
|
444 |
+
covered work, you indicate your acceptance of this License to do so.
|
445 |
+
|
446 |
+
10. Automatic Licensing of Downstream Recipients.
|
447 |
+
|
448 |
+
Each time you convey a covered work, the recipient automatically
|
449 |
+
receives a license from the original licensors, to run, modify and
|
450 |
+
propagate that work, subject to this License. You are not responsible
|
451 |
+
for enforcing compliance by third parties with this License.
|
452 |
+
|
453 |
+
An "entity transaction" is a transaction transferring control of an
|
454 |
+
organization, or substantially all assets of one, or subdividing an
|
455 |
+
organization, or merging organizations. If propagation of a covered
|
456 |
+
work results from an entity transaction, each party to that
|
457 |
+
transaction who receives a copy of the work also receives whatever
|
458 |
+
licenses to the work the party's predecessor in interest had or could
|
459 |
+
give under the previous paragraph, plus a right to possession of the
|
460 |
+
Corresponding Source of the work from the predecessor in interest, if
|
461 |
+
the predecessor has it or can get it with reasonable efforts.
|
462 |
+
|
463 |
+
You may not impose any further restrictions on the exercise of the
|
464 |
+
rights granted or affirmed under this License. For example, you may
|
465 |
+
not impose a license fee, royalty, or other charge for exercise of
|
466 |
+
rights granted under this License, and you may not initiate litigation
|
467 |
+
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
468 |
+
any patent claim is infringed by making, using, selling, offering for
|
469 |
+
sale, or importing the Program or any portion of it.
|
470 |
+
|
471 |
+
11. Patents.
|
472 |
+
|
473 |
+
A "contributor" is a copyright holder who authorizes use under this
|
474 |
+
License of the Program or a work on which the Program is based. The
|
475 |
+
work thus licensed is called the contributor's "contributor version".
|
476 |
+
|
477 |
+
A contributor's "essential patent claims" are all patent claims
|
478 |
+
owned or controlled by the contributor, whether already acquired or
|
479 |
+
hereafter acquired, that would be infringed by some manner, permitted
|
480 |
+
by this License, of making, using, or selling its contributor version,
|
481 |
+
but do not include claims that would be infringed only as a
|
482 |
+
consequence of further modification of the contributor version. For
|
483 |
+
purposes of this definition, "control" includes the right to grant
|
484 |
+
patent sublicenses in a manner consistent with the requirements of
|
485 |
+
this License.
|
486 |
+
|
487 |
+
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
488 |
+
patent license under the contributor's essential patent claims, to
|
489 |
+
make, use, sell, offer for sale, import and otherwise run, modify and
|
490 |
+
propagate the contents of its contributor version.
|
491 |
+
|
492 |
+
In the following three paragraphs, a "patent license" is any express
|
493 |
+
agreement or commitment, however denominated, not to enforce a patent
|
494 |
+
(such as an express permission to practice a patent or covenant not to
|
495 |
+
sue for patent infringement). To "grant" such a patent license to a
|
496 |
+
party means to make such an agreement or commitment not to enforce a
|
497 |
+
patent against the party.
|
498 |
+
|
499 |
+
If you convey a covered work, knowingly relying on a patent license,
|
500 |
+
and the Corresponding Source of the work is not available for anyone
|
501 |
+
to copy, free of charge and under the terms of this License, through a
|
502 |
+
publicly available network server or other readily accessible means,
|
503 |
+
then you must either (1) cause the Corresponding Source to be so
|
504 |
+
available, or (2) arrange to deprive yourself of the benefit of the
|
505 |
+
patent license for this particular work, or (3) arrange, in a manner
|
506 |
+
consistent with the requirements of this License, to extend the patent
|
507 |
+
license to downstream recipients. "Knowingly relying" means you have
|
508 |
+
actual knowledge that, but for the patent license, your conveying the
|
509 |
+
covered work in a country, or your recipient's use of the covered work
|
510 |
+
in a country, would infringe one or more identifiable patents in that
|
511 |
+
country that you have reason to believe are valid.
|
512 |
+
|
513 |
+
If, pursuant to or in connection with a single transaction or
|
514 |
+
arrangement, you convey, or propagate by procuring conveyance of, a
|
515 |
+
covered work, and grant a patent license to some of the parties
|
516 |
+
receiving the covered work authorizing them to use, propagate, modify
|
517 |
+
or convey a specific copy of the covered work, then the patent license
|
518 |
+
you grant is automatically extended to all recipients of the covered
|
519 |
+
work and works based on it.
|
520 |
+
|
521 |
+
A patent license is "discriminatory" if it does not include within
|
522 |
+
the scope of its coverage, prohibits the exercise of, or is
|
523 |
+
conditioned on the non-exercise of one or more of the rights that are
|
524 |
+
specifically granted under this License. You may not convey a covered
|
525 |
+
work if you are a party to an arrangement with a third party that is
|
526 |
+
in the business of distributing software, under which you make payment
|
527 |
+
to the third party based on the extent of your activity of conveying
|
528 |
+
the work, and under which the third party grants, to any of the
|
529 |
+
parties who would receive the covered work from you, a discriminatory
|
530 |
+
patent license (a) in connection with copies of the covered work
|
531 |
+
conveyed by you (or copies made from those copies), or (b) primarily
|
532 |
+
for and in connection with specific products or compilations that
|
533 |
+
contain the covered work, unless you entered into that arrangement,
|
534 |
+
or that patent license was granted, prior to 28 March 2007.
|
535 |
+
|
536 |
+
Nothing in this License shall be construed as excluding or limiting
|
537 |
+
any implied license or other defenses to infringement that may
|
538 |
+
otherwise be available to you under applicable patent law.
|
539 |
+
|
540 |
+
12. No Surrender of Others' Freedom.
|
541 |
+
|
542 |
+
If conditions are imposed on you (whether by court order, agreement or
|
543 |
+
otherwise) that contradict the conditions of this License, they do not
|
544 |
+
excuse you from the conditions of this License. If you cannot convey a
|
545 |
+
covered work so as to satisfy simultaneously your obligations under this
|
546 |
+
License and any other pertinent obligations, then as a consequence you may
|
547 |
+
not convey it at all. For example, if you agree to terms that obligate you
|
548 |
+
to collect a royalty for further conveying from those to whom you convey
|
549 |
+
the Program, the only way you could satisfy both those terms and this
|
550 |
+
License would be to refrain entirely from conveying the Program.
|
551 |
+
|
552 |
+
13. Use with the GNU Affero General Public License.
|
553 |
+
|
554 |
+
Notwithstanding any other provision of this License, you have
|
555 |
+
permission to link or combine any covered work with a work licensed
|
556 |
+
under version 3 of the GNU Affero General Public License into a single
|
557 |
+
combined work, and to convey the resulting work. The terms of this
|
558 |
+
License will continue to apply to the part which is the covered work,
|
559 |
+
but the special requirements of the GNU Affero General Public License,
|
560 |
+
section 13, concerning interaction through a network will apply to the
|
561 |
+
combination as such.
|
562 |
+
|
563 |
+
14. Revised Versions of this License.
|
564 |
+
|
565 |
+
The Free Software Foundation may publish revised and/or new versions of
|
566 |
+
the GNU General Public License from time to time. Such new versions will
|
567 |
+
be similar in spirit to the present version, but may differ in detail to
|
568 |
+
address new problems or concerns.
|
569 |
+
|
570 |
+
Each version is given a distinguishing version number. If the
|
571 |
+
Program specifies that a certain numbered version of the GNU General
|
572 |
+
Public License "or any later version" applies to it, you have the
|
573 |
+
option of following the terms and conditions either of that numbered
|
574 |
+
version or of any later version published by the Free Software
|
575 |
+
Foundation. If the Program does not specify a version number of the
|
576 |
+
GNU General Public License, you may choose any version ever published
|
577 |
+
by the Free Software Foundation.
|
578 |
+
|
579 |
+
If the Program specifies that a proxy can decide which future
|
580 |
+
versions of the GNU General Public License can be used, that proxy's
|
581 |
+
public statement of acceptance of a version permanently authorizes you
|
582 |
+
to choose that version for the Program.
|
583 |
+
|
584 |
+
Later license versions may give you additional or different
|
585 |
+
permissions. However, no additional obligations are imposed on any
|
586 |
+
author or copyright holder as a result of your choosing to follow a
|
587 |
+
later version.
|
588 |
+
|
589 |
+
15. Disclaimer of Warranty.
|
590 |
+
|
591 |
+
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
592 |
+
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
593 |
+
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
594 |
+
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
595 |
+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
596 |
+
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
597 |
+
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
598 |
+
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
599 |
+
|
600 |
+
16. Limitation of Liability.
|
601 |
+
|
602 |
+
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
603 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
604 |
+
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
605 |
+
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
606 |
+
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
607 |
+
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
608 |
+
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
609 |
+
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
610 |
+
SUCH DAMAGES.
|
611 |
+
|
612 |
+
17. Interpretation of Sections 15 and 16.
|
613 |
+
|
614 |
+
If the disclaimer of warranty and limitation of liability provided
|
615 |
+
above cannot be given local legal effect according to their terms,
|
616 |
+
reviewing courts shall apply local law that most closely approximates
|
617 |
+
an absolute waiver of all civil liability in connection with the
|
618 |
+
Program, unless a warranty or assumption of liability accompanies a
|
619 |
+
copy of the Program in return for a fee.
|
620 |
+
|
621 |
+
END OF TERMS AND CONDITIONS
|
622 |
+
|
623 |
+
How to Apply These Terms to Your New Programs
|
624 |
+
|
625 |
+
If you develop a new program, and you want it to be of the greatest
|
626 |
+
possible use to the public, the best way to achieve this is to make it
|
627 |
+
free software which everyone can redistribute and change under these terms.
|
628 |
+
|
629 |
+
To do so, attach the following notices to the program. It is safest
|
630 |
+
to attach them to the start of each source file to most effectively
|
631 |
+
state the exclusion of warranty; and each file should have at least
|
632 |
+
the "copyright" line and a pointer to where the full notice is found.
|
633 |
+
|
634 |
+
<one line to give the program's name and a brief idea of what it does.>
|
635 |
+
Copyright (C) <year> <name of author>
|
636 |
+
|
637 |
+
This program is free software: you can redistribute it and/or modify
|
638 |
+
it under the terms of the GNU General Public License as published by
|
639 |
+
the Free Software Foundation, either version 3 of the License, or
|
640 |
+
(at your option) any later version.
|
641 |
+
|
642 |
+
This program is distributed in the hope that it will be useful,
|
643 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
644 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
645 |
+
GNU General Public License for more details.
|
646 |
+
|
647 |
+
You should have received a copy of the GNU General Public License
|
648 |
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
649 |
+
|
650 |
+
Also add information on how to contact you by electronic and paper mail.
|
651 |
+
|
652 |
+
If the program does terminal interaction, make it output a short
|
653 |
+
notice like this when it starts in an interactive mode:
|
654 |
+
|
655 |
+
<program> Copyright (C) <year> <name of author>
|
656 |
+
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
657 |
+
This is free software, and you are welcome to redistribute it
|
658 |
+
under certain conditions; type `show c' for details.
|
659 |
+
|
660 |
+
The hypothetical commands `show w' and `show c' should show the appropriate
|
661 |
+
parts of the General Public License. Of course, your program's commands
|
662 |
+
might be different; for a GUI interface, you would use an "about box".
|
663 |
+
|
664 |
+
You should also get your employer (if you work as a programmer) or school,
|
665 |
+
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
666 |
+
For more information on this, and how to apply and follow the GNU GPL, see
|
667 |
+
<https://www.gnu.org/licenses/>.
|
668 |
+
|
669 |
+
The GNU General Public License does not permit incorporating your program
|
670 |
+
into proprietary programs. If your program is a subroutine library, you
|
671 |
+
may consider it more useful to permit linking proprietary applications with
|
672 |
+
the library. If this is what you want to do, use the GNU Lesser General
|
673 |
+
Public License instead of this License. But first, please read
|
674 |
+
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
readme.txt
CHANGED
@@ -5,8 +5,8 @@ License: GPLv3
|
|
5 |
License URI: https://www.gnu.org/licenses/gpl.html
|
6 |
Tags: activity log, wordpress activity logs, security audit log, audit log, user tracking, security event log, audit trail, wordpress security monitor, wordpress admin, wordpress admin monitoring, user activity, admin, multisite, SMS alerts, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
|
7 |
Requires at least: 5.0
|
8 |
-
Tested up to: 5.9
|
9 |
-
Stable tag: 4.
|
10 |
Requires PHP: 7.0
|
11 |
|
12 |
The #1 user-rated activity log plugin. Keep a comprehensive log of the changes that happen on your site with this easy to use plugin.
|
@@ -162,7 +162,7 @@ WP Activity Log can keep also a detailed log of changes that happen on other plu
|
|
162 |
* [Why WP Activity Log](https://wpactivitylog.com/why-wp-activity-log/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+repos+description)
|
163 |
* [WordPress Multisite Features](https://wpactivitylog.com/support/kb/activity-log-multisite-network-features/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+repos+description)
|
164 |
* [The WP Activity Log plugin website](https://wpactivitylog.com/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+repos+description)
|
165 |
-
* [
|
166 |
|
167 |
#### WP Activity Log in your language!
|
168 |
We need help translating the plugin and the activity log events. Please visit the [WordPress Translate Project](https://translate.wordpress.org/projects/wp-plugins/wp-security-audit-log/) to translate the plugin. Drop us an email on support@wpwhitesecurity.com to get mentioned in the list of translators below.
|
@@ -208,11 +208,52 @@ Please refer to our [support pages](https://wpactivitylog.com/support/?utm_sourc
|
|
208 |
|
209 |
== Changelog ==
|
210 |
|
211 |
-
= 4.
|
212 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
|
214 |
* **Improvements**
|
215 |
-
*
|
216 |
-
* Improved
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
|
218 |
Refer to the [complete plugin changelog](https://wpactivitylog.com/support/kb/plugin-changelog/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+repos+description) for more detailed information about what was new, improved and fixed in previous versions of the WP Activity Log plugin.
|
5 |
License URI: https://www.gnu.org/licenses/gpl.html
|
6 |
Tags: activity log, wordpress activity logs, security audit log, audit log, user tracking, security event log, audit trail, wordpress security monitor, wordpress admin, wordpress admin monitoring, user activity, admin, multisite, SMS alerts, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
|
7 |
Requires at least: 5.0
|
8 |
+
Tested up to: 5.9.1
|
9 |
+
Stable tag: 4.4.0
|
10 |
Requires PHP: 7.0
|
11 |
|
12 |
The #1 user-rated activity log plugin. Keep a comprehensive log of the changes that happen on your site with this easy to use plugin.
|
162 |
* [Why WP Activity Log](https://wpactivitylog.com/why-wp-activity-log/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+repos+description)
|
163 |
* [WordPress Multisite Features](https://wpactivitylog.com/support/kb/activity-log-multisite-network-features/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+repos+description)
|
164 |
* [The WP Activity Log plugin website](https://wpactivitylog.com/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+repos+description)
|
165 |
+
* [The definitive WordPress security guide](hhttps://www.wpwhitesecurity.com/wordpress-security/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+repos+description)
|
166 |
|
167 |
#### WP Activity Log in your language!
|
168 |
We need help translating the plugin and the activity log events. Please visit the [WordPress Translate Project](https://translate.wordpress.org/projects/wp-plugins/wp-security-audit-log/) to translate the plugin. Drop us an email on support@wpwhitesecurity.com to get mentioned in the list of translators below.
|
208 |
|
209 |
== Changelog ==
|
210 |
|
211 |
+
= 4.4.0 (2022-02-08) =
|
212 |
+
|
213 |
+
Release notes: [New Reports engine with more criteria, reports management & more](https://wpactivitylog.com/wsal-4-4/)
|
214 |
+
|
215 |
+
* **New activity log event IDs**
|
216 |
+
* ID 6059: Changed the site's title.
|
217 |
+
* ID 4021: Changed the website URL in the user profile.
|
218 |
+
* ID 4013: User has been activated on a multisite network.
|
219 |
+
|
220 |
+
* **New features & functionality**
|
221 |
+
* Hooks to allow users to change the columns in reports or ad value from non-default columns. Refer to the [list of hooks in WP Activity Log](https://wpactivitylog.com/support/kb/list-hooks/) for more information.
|
222 |
+
* New UI for "Enable/Disable event IDs" with search and filtering functionality.
|
223 |
+
* New filter that allows user to add metadata to user information popup. Refer to the [List of hooks in WP Activity Log](https://wpactivitylog.com/support/kb/list-hooks/) for more information.
|
224 |
+
* The new [Activity Log for TablePress extension](https://wpactivitylog.com/extensions/tablepress-activity-log/).
|
225 |
|
226 |
* **Improvements**
|
227 |
+
* Changed the database schema for improved storing of data, and faster writing and reading. After the upgrade the plugin will launch the upgrade process which might take some time to complete, depending on the amount of data in the activity log.
|
228 |
+
* Improved the coverage of changes done to a website via REST API.
|
229 |
+
* Removed obsolete code used for advertorial events in the activity log viewer.
|
230 |
+
* All plugin settings now have the wsal_ prefix automatically added to them.
|
231 |
+
* Rewritten some of the settings help text in the plugin to better explain the settings.
|
232 |
+
* Removed obsolete settings & code of the old file integrity scanner (now part of [Website File Changes Monitor plugin](https://www.wpwhitesecurity.com/wordpress-plugins/website-file-changes-monitor/)).
|
233 |
+
* Removed obsolete reference to the old file changes scanner in the daily summary email.
|
234 |
+
* Made a number of JS strings available for translation.
|
235 |
+
* Removed a number of plugin settings from autoload for improved performance.
|
236 |
+
* Improved the plugin's metadata and added the licensing information.
|
237 |
+
* Long URL strings in activity log events are now automatically truncated. Full URL can be seen with just a click.
|
238 |
+
* Removed forced database table collation: plugin now uses the default WordPress table collation.
|
239 |
+
* Updated the "Help & Contact Us" page; improved text and added more relevant information.
|
240 |
+
* Improved several UI sections in the Third Party Connections module.
|
241 |
+
* Improved the check for writing activity log to external database; now it is less restrictive and faster.
|
242 |
+
|
243 |
+
* **Security fix**
|
244 |
+
* Upgraded the Freemius SDK to version 2.4.3.
|
245 |
+
|
246 |
+
* **Bug fixes**
|
247 |
+
* Fixed: Database error when trying to log in with a non-existing user and a login notification is enabled.
|
248 |
+
* Fixed: In some edge cases the plugin was creating an empty "external database" connection string.
|
249 |
+
* Fixed a number of typos in the text of activity log events.
|
250 |
+
* Fixed: Auto complete in the Delete activity log data section was not returning the correct list of objects.
|
251 |
+
* Fixed: Wrong object reported for event ID 5029.
|
252 |
+
* Fixed: Event ID 4000 not reported when front-end sensor is disabled.
|
253 |
+
* Fixed: "Unknown connection type" reported back setting up a third party connection on specific versions of WordPress.
|
254 |
+
* Fixed: Event ID 6320 (added / removed connection) reported instead of event ID 6321 (modified connection).
|
255 |
+
* Fixed: Function that was running on "add_filter" instead of "add_action" - [Support ticket](https://wordpress.org/support/topic/issue-with-hook-name-and-param-callback/).
|
256 |
+
* Fixed: PHP warning about OPCacheUtils.php in specific setups.
|
257 |
+
* Fixed: Edge case in which other plugins couldn't be installed or updated when WP Activity Log was activated.
|
258 |
|
259 |
Refer to the [complete plugin changelog](https://wpactivitylog.com/support/kb/plugin-changelog/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+repos+description) for more detailed information about what was new, improved and fixed in previous versions of the WP Activity Log plugin.
|
third-party/freemius/wordpress-sdk/includes/class-freemius.php
CHANGED
@@ -3550,6 +3550,8 @@
|
|
3550 |
* @since 1.1.7.3
|
3551 |
*/
|
3552 |
static function _toggle_debug_mode() {
|
|
|
|
|
3553 |
if ( ! is_super_admin() ) {
|
3554 |
return;
|
3555 |
}
|
@@ -3571,10 +3573,19 @@
|
|
3571 |
* @since 1.2.1.6
|
3572 |
*/
|
3573 |
static function _get_debug_log() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3574 |
$logs = FS_Logger::load_db_logs(
|
3575 |
fs_request_get( 'filters', false, 'post' ),
|
3576 |
-
|
3577 |
-
|
3578 |
);
|
3579 |
|
3580 |
self::shoot_ajax_success( $logs );
|
@@ -4447,6 +4458,12 @@
|
|
4447 |
* @since 1.0.9
|
4448 |
*/
|
4449 |
function _email_about_firewall_issue() {
|
|
|
|
|
|
|
|
|
|
|
|
|
4450 |
$this->_admin_notices->remove_sticky( 'failed_connect_api' );
|
4451 |
|
4452 |
$pong = $this->ping();
|
@@ -4521,6 +4538,12 @@
|
|
4521 |
* @since 1.1.7.4
|
4522 |
*/
|
4523 |
function _retry_connectivity_test() {
|
|
|
|
|
|
|
|
|
|
|
|
|
4524 |
$this->_admin_notices->remove_sticky( 'failed_connect_api_first' );
|
4525 |
|
4526 |
$pong = $this->ping();
|
3550 |
* @since 1.1.7.3
|
3551 |
*/
|
3552 |
static function _toggle_debug_mode() {
|
3553 |
+
check_admin_referer( 'fs_toggle_debug_mode' );
|
3554 |
+
|
3555 |
if ( ! is_super_admin() ) {
|
3556 |
return;
|
3557 |
}
|
3573 |
* @since 1.2.1.6
|
3574 |
*/
|
3575 |
static function _get_debug_log() {
|
3576 |
+
check_admin_referer( 'fs_get_debug_log' );
|
3577 |
+
|
3578 |
+
if ( ! is_super_admin() ) {
|
3579 |
+
return;
|
3580 |
+
}
|
3581 |
+
|
3582 |
+
$limit = min( ! empty( $_POST['limit'] ) ? absint( $_POST['limit'] ) : 200, 200 );
|
3583 |
+
$offset = min( ! empty( $_POST['offset'] ) ? absint( $_POST['offset'] ) : 200, 200 );
|
3584 |
+
|
3585 |
$logs = FS_Logger::load_db_logs(
|
3586 |
fs_request_get( 'filters', false, 'post' ),
|
3587 |
+
$limit,
|
3588 |
+
$offset
|
3589 |
);
|
3590 |
|
3591 |
self::shoot_ajax_success( $logs );
|
4458 |
* @since 1.0.9
|
4459 |
*/
|
4460 |
function _email_about_firewall_issue() {
|
4461 |
+
check_admin_referer( 'fs_resolve_firewall_issues' );
|
4462 |
+
|
4463 |
+
if ( ! current_user_can( is_multisite() ? 'manage_options' : 'activate_plugins' ) ) {
|
4464 |
+
return;
|
4465 |
+
}
|
4466 |
+
|
4467 |
$this->_admin_notices->remove_sticky( 'failed_connect_api' );
|
4468 |
|
4469 |
$pong = $this->ping();
|
4538 |
* @since 1.1.7.4
|
4539 |
*/
|
4540 |
function _retry_connectivity_test() {
|
4541 |
+
check_admin_referer( 'fs_retry_connectivity_test' );
|
4542 |
+
|
4543 |
+
if ( ! current_user_can( is_multisite() ? 'manage_options' : 'activate_plugins' ) ) {
|
4544 |
+
return;
|
4545 |
+
}
|
4546 |
+
|
4547 |
$this->_admin_notices->remove_sticky( 'failed_connect_api_first' );
|
4548 |
|
4549 |
$pong = $this->ping();
|
third-party/freemius/wordpress-sdk/includes/managers/class-fs-admin-notice-manager.php
CHANGED
@@ -175,7 +175,12 @@
|
|
175 |
*
|
176 |
*/
|
177 |
function dismiss_notice_ajax_callback() {
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
179 |
wp_die();
|
180 |
}
|
181 |
|
@@ -469,4 +474,4 @@
|
|
469 |
}
|
470 |
|
471 |
#endregion
|
472 |
-
}
|
175 |
*
|
176 |
*/
|
177 |
function dismiss_notice_ajax_callback() {
|
178 |
+
check_admin_referer( 'fs_dismiss_notice_action' );
|
179 |
+
|
180 |
+
if ( ! is_numeric( $_POST['message_id'] ) ) {
|
181 |
+
$this->_sticky_storage->remove( $_POST['message_id'] );
|
182 |
+
}
|
183 |
+
|
184 |
wp_die();
|
185 |
}
|
186 |
|
474 |
}
|
475 |
|
476 |
#endregion
|
477 |
+
}
|
third-party/freemius/wordpress-sdk/includes/sdk/Exceptions/ArgumentNotExistException.php
CHANGED
@@ -1,4 +1,8 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
2 |
if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
|
3 |
exit;
|
4 |
}
|
@@ -6,4 +10,4 @@
|
|
6 |
if ( ! class_exists( 'Freemius_ArgumentNotExistException' ) ) {
|
7 |
class Freemius_ArgumentNotExistException extends Freemius_InvalidArgumentException {
|
8 |
}
|
9 |
-
}
|
1 |
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
+
|
6 |
if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
|
7 |
exit;
|
8 |
}
|
10 |
if ( ! class_exists( 'Freemius_ArgumentNotExistException' ) ) {
|
11 |
class Freemius_ArgumentNotExistException extends Freemius_InvalidArgumentException {
|
12 |
}
|
13 |
+
}
|
third-party/freemius/wordpress-sdk/includes/sdk/Exceptions/EmptyArgumentException.php
CHANGED
@@ -1,4 +1,8 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
2 |
if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
|
3 |
exit;
|
4 |
}
|
@@ -6,4 +10,4 @@
|
|
6 |
if ( ! class_exists( 'Freemius_EmptyArgumentException' ) ) {
|
7 |
class Freemius_EmptyArgumentException extends Freemius_InvalidArgumentException {
|
8 |
}
|
9 |
-
}
|
1 |
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
+
|
6 |
if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
|
7 |
exit;
|
8 |
}
|
10 |
if ( ! class_exists( 'Freemius_EmptyArgumentException' ) ) {
|
11 |
class Freemius_EmptyArgumentException extends Freemius_InvalidArgumentException {
|
12 |
}
|
13 |
+
}
|
third-party/freemius/wordpress-sdk/includes/sdk/Exceptions/Exception.php
CHANGED
@@ -1,4 +1,8 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
2 |
if ( ! class_exists( 'Freemius_Exception' ) ) {
|
3 |
/**
|
4 |
* Thrown when an API call returns an exception.
|
@@ -71,4 +75,4 @@
|
|
71 |
return $str . $this->getMessage();
|
72 |
}
|
73 |
}
|
74 |
-
}
|
1 |
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
+
|
6 |
if ( ! class_exists( 'Freemius_Exception' ) ) {
|
7 |
/**
|
8 |
* Thrown when an API call returns an exception.
|
75 |
return $str . $this->getMessage();
|
76 |
}
|
77 |
}
|
78 |
+
}
|
third-party/freemius/wordpress-sdk/includes/sdk/Exceptions/InvalidArgumentException.php
CHANGED
@@ -1,8 +1,12 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
2 |
if ( ! class_exists( 'Freemius_Exception' ) ) {
|
3 |
exit;
|
4 |
}
|
5 |
|
6 |
if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
|
7 |
class Freemius_InvalidArgumentException extends Freemius_Exception { }
|
8 |
-
}
|
1 |
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
+
|
6 |
if ( ! class_exists( 'Freemius_Exception' ) ) {
|
7 |
exit;
|
8 |
}
|
9 |
|
10 |
if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
|
11 |
class Freemius_InvalidArgumentException extends Freemius_Exception { }
|
12 |
+
}
|
third-party/freemius/wordpress-sdk/includes/sdk/Exceptions/OAuthException.php
CHANGED
@@ -1,4 +1,8 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
2 |
if ( ! class_exists( 'Freemius_Exception' ) ) {
|
3 |
exit;
|
4 |
}
|
@@ -9,4 +13,4 @@
|
|
9 |
parent::__construct( $pResult );
|
10 |
}
|
11 |
}
|
12 |
-
}
|
1 |
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
+
|
6 |
if ( ! class_exists( 'Freemius_Exception' ) ) {
|
7 |
exit;
|
8 |
}
|
13 |
parent::__construct( $pResult );
|
14 |
}
|
15 |
}
|
16 |
+
}
|
third-party/freemius/wordpress-sdk/includes/sdk/FreemiusBase.php
CHANGED
@@ -15,6 +15,10 @@
|
|
15 |
* under the License.
|
16 |
*/
|
17 |
|
|
|
|
|
|
|
|
|
18 |
if ( ! defined( 'FS_API__VERSION' ) ) {
|
19 |
define( 'FS_API__VERSION', '1' );
|
20 |
}
|
15 |
* under the License.
|
16 |
*/
|
17 |
|
18 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
19 |
+
exit;
|
20 |
+
}
|
21 |
+
|
22 |
if ( ! defined( 'FS_API__VERSION' ) ) {
|
23 |
define( 'FS_API__VERSION', '1' );
|
24 |
}
|
third-party/freemius/wordpress-sdk/includes/sdk/FreemiusWordPress.php
CHANGED
@@ -14,6 +14,9 @@
|
|
14 |
* License for the specific language governing permissions and limitations
|
15 |
* under the License.
|
16 |
*/
|
|
|
|
|
|
|
17 |
|
18 |
require_once dirname( __FILE__ ) . '/FreemiusBase.php';
|
19 |
|
@@ -709,4 +712,4 @@
|
|
709 |
}
|
710 |
|
711 |
#endregion
|
712 |
-
}
|
14 |
* License for the specific language governing permissions and limitations
|
15 |
* under the License.
|
16 |
*/
|
17 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
18 |
+
exit;
|
19 |
+
}
|
20 |
|
21 |
require_once dirname( __FILE__ ) . '/FreemiusBase.php';
|
22 |
|
712 |
}
|
713 |
|
714 |
#endregion
|
715 |
+
}
|
third-party/freemius/wordpress-sdk/require.php
CHANGED
@@ -6,6 +6,10 @@
|
|
6 |
* @since 1.1.9
|
7 |
*/
|
8 |
|
|
|
|
|
|
|
|
|
9 |
// Configuration should be loaded first.
|
10 |
require_once dirname( __FILE__ ) . '/config.php';
|
11 |
require_once WP_FS__DIR_INCLUDES . '/fs-core-functions.php';
|
@@ -46,4 +50,4 @@
|
|
46 |
require_once WP_FS__DIR_INCLUDES . '/class-fs-admin-notices.php';
|
47 |
require_once WP_FS__DIR_INCLUDES . '/class-freemius-abstract.php';
|
48 |
require_once WP_FS__DIR_INCLUDES . '/sdk/Exceptions/Exception.php';
|
49 |
-
require_once WP_FS__DIR_INCLUDES . '/class-freemius.php';
|
6 |
* @since 1.1.9
|
7 |
*/
|
8 |
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
// Configuration should be loaded first.
|
14 |
require_once dirname( __FILE__ ) . '/config.php';
|
15 |
require_once WP_FS__DIR_INCLUDES . '/fs-core-functions.php';
|
50 |
require_once WP_FS__DIR_INCLUDES . '/class-fs-admin-notices.php';
|
51 |
require_once WP_FS__DIR_INCLUDES . '/class-freemius-abstract.php';
|
52 |
require_once WP_FS__DIR_INCLUDES . '/sdk/Exceptions/Exception.php';
|
53 |
+
require_once WP_FS__DIR_INCLUDES . '/class-freemius.php';
|
third-party/freemius/wordpress-sdk/start.php
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
*
|
16 |
* @var string
|
17 |
*/
|
18 |
-
$this_sdk_version = '2.4.
|
19 |
|
20 |
#region SDK Selection Logic --------------------------------------------------------------------
|
21 |
|
15 |
*
|
16 |
* @var string
|
17 |
*/
|
18 |
+
$this_sdk_version = '2.4.3';
|
19 |
|
20 |
#region SDK Selection Logic --------------------------------------------------------------------
|
21 |
|
third-party/freemius/wordpress-sdk/templates/account/partials/addon.php
CHANGED
@@ -1,4 +1,9 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
/**
|
3 |
* @var array $VARS
|
4 |
* @var Freemius $fs
|
@@ -443,4 +448,4 @@
|
|
443 |
</td>
|
444 |
<!--/ Optional Delete Action -->
|
445 |
<?php endif ?>
|
446 |
-
</tr>
|
1 |
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
4 |
+
exit;
|
5 |
+
}
|
6 |
+
|
7 |
/**
|
8 |
* @var array $VARS
|
9 |
* @var Freemius $fs
|
448 |
</td>
|
449 |
<!--/ Optional Delete Action -->
|
450 |
<?php endif ?>
|
451 |
+
</tr>
|
third-party/freemius/wordpress-sdk/templates/ajax-loader.php
CHANGED
@@ -1 +1,6 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
+
?>
|
6 |
+
<div class="fs-ajax-loader" style="display: none"><?php for ( $i = 1; $i <= 8; $i ++ ) : ?><div class="fs-ajax-loader-bar fs-ajax-loader-bar-<?php echo $i ?>"></div><?php endfor ?></div>
|
third-party/freemius/wordpress-sdk/templates/debug.php
CHANGED
@@ -37,6 +37,8 @@
|
|
37 |
|
38 |
$.post( ajaxurl, {
|
39 |
action: 'fs_toggle_debug_mode',
|
|
|
|
|
40 |
is_on : ($(this).hasClass( 'fs-on' ) ? 1 : 0)
|
41 |
}, function ( response ) {
|
42 |
if ( 1 == response ) {
|
@@ -111,7 +113,8 @@
|
|
111 |
if (optionName) {
|
112 |
$.post(ajaxurl, {
|
113 |
action : 'fs_get_db_option',
|
114 |
-
|
|
|
115 |
option_name: optionName
|
116 |
}, function (response) {
|
117 |
if (response.data.value)
|
@@ -131,7 +134,8 @@
|
|
131 |
if (optionValue) {
|
132 |
$.post(ajaxurl, {
|
133 |
action : 'fs_set_db_option',
|
134 |
-
|
|
|
135 |
option_name : optionName,
|
136 |
option_value: optionValue
|
137 |
}, function () {
|
@@ -724,6 +728,8 @@
|
|
724 |
|
725 |
$.post(ajaxurl, {
|
726 |
action : 'fs_get_debug_log',
|
|
|
|
|
727 |
filters: filters,
|
728 |
offset : offset,
|
729 |
limit : limit
|
37 |
|
38 |
$.post( ajaxurl, {
|
39 |
action: 'fs_toggle_debug_mode',
|
40 |
+
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
41 |
+
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_toggle_debug_mode' ) ); ?>,
|
42 |
is_on : ($(this).hasClass( 'fs-on' ) ? 1 : 0)
|
43 |
}, function ( response ) {
|
44 |
if ( 1 == response ) {
|
113 |
if (optionName) {
|
114 |
$.post(ajaxurl, {
|
115 |
action : 'fs_get_db_option',
|
116 |
+
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
117 |
+
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_get_db_option' ) ); ?>,
|
118 |
option_name: optionName
|
119 |
}, function (response) {
|
120 |
if (response.data.value)
|
134 |
if (optionValue) {
|
135 |
$.post(ajaxurl, {
|
136 |
action : 'fs_set_db_option',
|
137 |
+
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
138 |
+
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_set_db_option' ) ); ?>,
|
139 |
option_name : optionName,
|
140 |
option_value: optionValue
|
141 |
}, function () {
|
728 |
|
729 |
$.post(ajaxurl, {
|
730 |
action : 'fs_get_debug_log',
|
731 |
+
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
732 |
+
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_get_debug_log' ) ); ?>,
|
733 |
filters: filters,
|
734 |
offset : offset,
|
735 |
limit : limit
|
third-party/freemius/wordpress-sdk/templates/firewall-issues-js.php
CHANGED
@@ -22,10 +22,12 @@
|
|
22 |
notice = $( this ).parents( '.fs-notice' ),
|
23 |
ajaxActionSuffix = notice.attr( 'data-manager-id' ).replace( ':', '-' );
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
29 |
|
30 |
if ( 'squid' === error_type ) {
|
31 |
data.hosting_company = prompt( 'What is the name or URL of your hosting company?' );
|
@@ -39,7 +41,9 @@
|
|
39 |
}
|
40 |
|
41 |
if ( 'retry_ping' === error_type ) {
|
42 |
-
|
|
|
|
|
43 |
}
|
44 |
|
45 |
$( this ).css({'cursor': 'wait'});
|
@@ -56,4 +60,4 @@
|
|
56 |
});
|
57 |
});
|
58 |
});
|
59 |
-
</script>
|
22 |
notice = $( this ).parents( '.fs-notice' ),
|
23 |
ajaxActionSuffix = notice.attr( 'data-manager-id' ).replace( ':', '-' );
|
24 |
|
25 |
+
var data = {
|
26 |
+
action : 'fs_resolve_firewall_issues_' + ajaxActionSuffix,
|
27 |
+
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
28 |
+
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_resolve_firewall_issues' ) ); ?>,
|
29 |
+
error_type: error_type
|
30 |
+
};
|
31 |
|
32 |
if ( 'squid' === error_type ) {
|
33 |
data.hosting_company = prompt( 'What is the name or URL of your hosting company?' );
|
41 |
}
|
42 |
|
43 |
if ( 'retry_ping' === error_type ) {
|
44 |
+
data.action = 'fs_retry_connectivity_test_' + ajaxActionSuffix;
|
45 |
+
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
46 |
+
data._wpnonce = <?php echo wp_json_encode( wp_create_nonce( 'fs_retry_connectivity_test' ) ); ?>;
|
47 |
}
|
48 |
|
49 |
$( this ).css({'cursor': 'wait'});
|
60 |
});
|
61 |
});
|
62 |
});
|
63 |
+
</script>
|
third-party/freemius/wordpress-sdk/templates/partials/network-activation.php
CHANGED
@@ -1,4 +1,9 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
2 |
/**
|
3 |
* @var array $VARS
|
4 |
* @var Freemius $fs
|
@@ -86,4 +91,4 @@
|
|
86 |
</tbody>
|
87 |
</table>
|
88 |
</div>
|
89 |
-
</div>
|
1 |
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
4 |
+
exit;
|
5 |
+
}
|
6 |
+
|
7 |
/**
|
8 |
* @var array $VARS
|
9 |
* @var Freemius $fs
|
91 |
</tbody>
|
92 |
</table>
|
93 |
</div>
|
94 |
+
</div>
|
third-party/freemius/wordpress-sdk/templates/sticky-admin-notice-js.php
CHANGED
@@ -23,7 +23,9 @@
|
|
23 |
|
24 |
notice.fadeOut( 'fast', function() {
|
25 |
var data = {
|
26 |
-
action
|
|
|
|
|
27 |
message_id: id
|
28 |
};
|
29 |
|
@@ -36,4 +38,4 @@
|
|
36 |
});
|
37 |
});
|
38 |
});
|
39 |
-
</script>
|
23 |
|
24 |
notice.fadeOut( 'fast', function() {
|
25 |
var data = {
|
26 |
+
action : 'fs_dismiss_notice_action_' + ajaxActionSuffix,
|
27 |
+
// As such we don't need to use `wp_json_encode` method but using it to follow wp.org guideline.
|
28 |
+
_wpnonce : <?php echo wp_json_encode( wp_create_nonce( 'fs_dismiss_notice_action' ) ); ?>,
|
29 |
message_id: id
|
30 |
};
|
31 |
|
38 |
});
|
39 |
});
|
40 |
});
|
41 |
+
</script>
|
third-party/vendor/autoload.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload.php @generated by Composer
|
4 |
+
|
5 |
+
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
+
|
7 |
+
return ComposerAutoloaderInit23aaeb6864f7a0ba3de7e8f407e351c7::getLoader();
|
third-party/vendor/composer/ClassLoader.php
ADDED
@@ -0,0 +1,445 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Composer.
|
5 |
+
*
|
6 |
+
* (c) Nils Adermann <naderman@naderman.de>
|
7 |
+
* Jordi Boggiano <j.boggiano@seld.be>
|
8 |
+
*
|
9 |
+
* For the full copyright and license information, please view the LICENSE
|
10 |
+
* file that was distributed with this source code.
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace Composer\Autoload;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
17 |
+
*
|
18 |
+
* $loader = new \Composer\Autoload\ClassLoader();
|
19 |
+
*
|
20 |
+
* // register classes with namespaces
|
21 |
+
* $loader->add('Symfony\Component', __DIR__.'/component');
|
22 |
+
* $loader->add('Symfony', __DIR__.'/framework');
|
23 |
+
*
|
24 |
+
* // activate the autoloader
|
25 |
+
* $loader->register();
|
26 |
+
*
|
27 |
+
* // to enable searching the include path (eg. for PEAR packages)
|
28 |
+
* $loader->setUseIncludePath(true);
|
29 |
+
*
|
30 |
+
* In this example, if you try to use a class in the Symfony\Component
|
31 |
+
* namespace or one of its children (Symfony\Component\Console for instance),
|
32 |
+
* the autoloader will first look for the class under the component/
|
33 |
+
* directory, and it will then fallback to the framework/ directory if not
|
34 |
+
* found before giving up.
|
35 |
+
*
|
36 |
+
* This class is loosely based on the Symfony UniversalClassLoader.
|
37 |
+
*
|
38 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
39 |
+
* @author Jordi Boggiano <j.boggiano@seld.be>
|
40 |
+
* @see http://www.php-fig.org/psr/psr-0/
|
41 |
+
* @see http://www.php-fig.org/psr/psr-4/
|
42 |
+
*/
|
43 |
+
class ClassLoader
|
44 |
+
{
|
45 |
+
// PSR-4
|
46 |
+
private $prefixLengthsPsr4 = array();
|
47 |
+
private $prefixDirsPsr4 = array();
|
48 |
+
private $fallbackDirsPsr4 = array();
|
49 |
+
|
50 |
+
// PSR-0
|
51 |
+
private $prefixesPsr0 = array();
|
52 |
+
private $fallbackDirsPsr0 = array();
|
53 |
+
|
54 |
+
private $useIncludePath = false;
|
55 |
+
private $classMap = array();
|
56 |
+
private $classMapAuthoritative = false;
|
57 |
+
private $missingClasses = array();
|
58 |
+
private $apcuPrefix;
|
59 |
+
|
60 |
+
public function getPrefixes()
|
61 |
+
{
|
62 |
+
if (!empty($this->prefixesPsr0)) {
|
63 |
+
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
64 |
+
}
|
65 |
+
|
66 |
+
return array();
|
67 |
+
}
|
68 |
+
|
69 |
+
public function getPrefixesPsr4()
|
70 |
+
{
|
71 |
+
return $this->prefixDirsPsr4;
|
72 |
+
}
|
73 |
+
|
74 |
+
public function getFallbackDirs()
|
75 |
+
{
|
76 |
+
return $this->fallbackDirsPsr0;
|
77 |
+
}
|
78 |
+
|
79 |
+
public function getFallbackDirsPsr4()
|
80 |
+
{
|
81 |
+
return $this->fallbackDirsPsr4;
|
82 |
+
}
|
83 |
+
|
84 |
+
public function getClassMap()
|
85 |
+
{
|
86 |
+
return $this->classMap;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @param array $classMap Class to filename map
|
91 |
+
*/
|
92 |
+
public function addClassMap(array $classMap)
|
93 |
+
{
|
94 |
+
if ($this->classMap) {
|
95 |
+
$this->classMap = array_merge($this->classMap, $classMap);
|
96 |
+
} else {
|
97 |
+
$this->classMap = $classMap;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Registers a set of PSR-0 directories for a given prefix, either
|
103 |
+
* appending or prepending to the ones previously set for this prefix.
|
104 |
+
*
|
105 |
+
* @param string $prefix The prefix
|
106 |
+
* @param array|string $paths The PSR-0 root directories
|
107 |
+
* @param bool $prepend Whether to prepend the directories
|
108 |
+
*/
|
109 |
+
public function add($prefix, $paths, $prepend = false)
|
110 |
+
{
|
111 |
+
if (!$prefix) {
|
112 |
+
if ($prepend) {
|
113 |
+
$this->fallbackDirsPsr0 = array_merge(
|
114 |
+
(array) $paths,
|
115 |
+
$this->fallbackDirsPsr0
|
116 |
+
);
|
117 |
+
} else {
|
118 |
+
$this->fallbackDirsPsr0 = array_merge(
|
119 |
+
$this->fallbackDirsPsr0,
|
120 |
+
(array) $paths
|
121 |
+
);
|
122 |
+
}
|
123 |
+
|
124 |
+
return;
|
125 |
+
}
|
126 |
+
|
127 |
+
$first = $prefix[0];
|
128 |
+
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
129 |
+
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
130 |
+
|
131 |
+
return;
|
132 |
+
}
|
133 |
+
if ($prepend) {
|
134 |
+
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
135 |
+
(array) $paths,
|
136 |
+
$this->prefixesPsr0[$first][$prefix]
|
137 |
+
);
|
138 |
+
} else {
|
139 |
+
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
140 |
+
$this->prefixesPsr0[$first][$prefix],
|
141 |
+
(array) $paths
|
142 |
+
);
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Registers a set of PSR-4 directories for a given namespace, either
|
148 |
+
* appending or prepending to the ones previously set for this namespace.
|
149 |
+
*
|
150 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
151 |
+
* @param array|string $paths The PSR-4 base directories
|
152 |
+
* @param bool $prepend Whether to prepend the directories
|
153 |
+
*
|
154 |
+
* @throws \InvalidArgumentException
|
155 |
+
*/
|
156 |
+
public function addPsr4($prefix, $paths, $prepend = false)
|
157 |
+
{
|
158 |
+
if (!$prefix) {
|
159 |
+
// Register directories for the root namespace.
|
160 |
+
if ($prepend) {
|
161 |
+
$this->fallbackDirsPsr4 = array_merge(
|
162 |
+
(array) $paths,
|
163 |
+
$this->fallbackDirsPsr4
|
164 |
+
);
|
165 |
+
} else {
|
166 |
+
$this->fallbackDirsPsr4 = array_merge(
|
167 |
+
$this->fallbackDirsPsr4,
|
168 |
+
(array) $paths
|
169 |
+
);
|
170 |
+
}
|
171 |
+
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
172 |
+
// Register directories for a new namespace.
|
173 |
+
$length = strlen($prefix);
|
174 |
+
if ('\\' !== $prefix[$length - 1]) {
|
175 |
+
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
176 |
+
}
|
177 |
+
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
178 |
+
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
179 |
+
} elseif ($prepend) {
|
180 |
+
// Prepend directories for an already registered namespace.
|
181 |
+
$this->prefixDirsPsr4[$prefix] = array_merge(
|
182 |
+
(array) $paths,
|
183 |
+
$this->prefixDirsPsr4[$prefix]
|
184 |
+
);
|
185 |
+
} else {
|
186 |
+
// Append directories for an already registered namespace.
|
187 |
+
$this->prefixDirsPsr4[$prefix] = array_merge(
|
188 |
+
$this->prefixDirsPsr4[$prefix],
|
189 |
+
(array) $paths
|
190 |
+
);
|
191 |
+
}
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Registers a set of PSR-0 directories for a given prefix,
|
196 |
+
* replacing any others previously set for this prefix.
|
197 |
+
*
|
198 |
+
* @param string $prefix The prefix
|
199 |
+
* @param array|string $paths The PSR-0 base directories
|
200 |
+
*/
|
201 |
+
public function set($prefix, $paths)
|
202 |
+
{
|
203 |
+
if (!$prefix) {
|
204 |
+
$this->fallbackDirsPsr0 = (array) $paths;
|
205 |
+
} else {
|
206 |
+
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Registers a set of PSR-4 directories for a given namespace,
|
212 |
+
* replacing any others previously set for this namespace.
|
213 |
+
*
|
214 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
215 |
+
* @param array|string $paths The PSR-4 base directories
|
216 |
+
*
|
217 |
+
* @throws \InvalidArgumentException
|
218 |
+
*/
|
219 |
+
public function setPsr4($prefix, $paths)
|
220 |
+
{
|
221 |
+
if (!$prefix) {
|
222 |
+
$this->fallbackDirsPsr4 = (array) $paths;
|
223 |
+
} else {
|
224 |
+
$length = strlen($prefix);
|
225 |
+
if ('\\' !== $prefix[$length - 1]) {
|
226 |
+
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
227 |
+
}
|
228 |
+
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
229 |
+
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Turns on searching the include path for class files.
|
235 |
+
*
|
236 |
+
* @param bool $useIncludePath
|
237 |
+
*/
|
238 |
+
public function setUseIncludePath($useIncludePath)
|
239 |
+
{
|
240 |
+
$this->useIncludePath = $useIncludePath;
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Can be used to check if the autoloader uses the include path to check
|
245 |
+
* for classes.
|
246 |
+
*
|
247 |
+
* @return bool
|
248 |
+
*/
|
249 |
+
public function getUseIncludePath()
|
250 |
+
{
|
251 |
+
return $this->useIncludePath;
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Turns off searching the prefix and fallback directories for classes
|
256 |
+
* that have not been registered with the class map.
|
257 |
+
*
|
258 |
+
* @param bool $classMapAuthoritative
|
259 |
+
*/
|
260 |
+
public function setClassMapAuthoritative($classMapAuthoritative)
|
261 |
+
{
|
262 |
+
$this->classMapAuthoritative = $classMapAuthoritative;
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Should class lookup fail if not found in the current class map?
|
267 |
+
*
|
268 |
+
* @return bool
|
269 |
+
*/
|
270 |
+
public function isClassMapAuthoritative()
|
271 |
+
{
|
272 |
+
return $this->classMapAuthoritative;
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
277 |
+
*
|
278 |
+
* @param string|null $apcuPrefix
|
279 |
+
*/
|
280 |
+
public function setApcuPrefix($apcuPrefix)
|
281 |
+
{
|
282 |
+
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* The APCu prefix in use, or null if APCu caching is not enabled.
|
287 |
+
*
|
288 |
+
* @return string|null
|
289 |
+
*/
|
290 |
+
public function getApcuPrefix()
|
291 |
+
{
|
292 |
+
return $this->apcuPrefix;
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Registers this instance as an autoloader.
|
297 |
+
*
|
298 |
+
* @param bool $prepend Whether to prepend the autoloader or not
|
299 |
+
*/
|
300 |
+
public function register($prepend = false)
|
301 |
+
{
|
302 |
+
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Unregisters this instance as an autoloader.
|
307 |
+
*/
|
308 |
+
public function unregister()
|
309 |
+
{
|
310 |
+
spl_autoload_unregister(array($this, 'loadClass'));
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Loads the given class or interface.
|
315 |
+
*
|
316 |
+
* @param string $class The name of the class
|
317 |
+
* @return bool|null True if loaded, null otherwise
|
318 |
+
*/
|
319 |
+
public function loadClass($class)
|
320 |
+
{
|
321 |
+
if ($file = $this->findFile($class)) {
|
322 |
+
includeFile($file);
|
323 |
+
|
324 |
+
return true;
|
325 |
+
}
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Finds the path to the file where the class is defined.
|
330 |
+
*
|
331 |
+
* @param string $class The name of the class
|
332 |
+
*
|
333 |
+
* @return string|false The path if found, false otherwise
|
334 |
+
*/
|
335 |
+
public function findFile($class)
|
336 |
+
{
|
337 |
+
// class map lookup
|
338 |
+
if (isset($this->classMap[$class])) {
|
339 |
+
return $this->classMap[$class];
|
340 |
+
}
|
341 |
+
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
342 |
+
return false;
|
343 |
+
}
|
344 |
+
if (null !== $this->apcuPrefix) {
|
345 |
+
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
346 |
+
if ($hit) {
|
347 |
+
return $file;
|
348 |
+
}
|
349 |
+
}
|
350 |
+
|
351 |
+
$file = $this->findFileWithExtension($class, '.php');
|
352 |
+
|
353 |
+
// Search for Hack files if we are running on HHVM
|
354 |
+
if (false === $file && defined('HHVM_VERSION')) {
|
355 |
+
$file = $this->findFileWithExtension($class, '.hh');
|
356 |
+
}
|
357 |
+
|
358 |
+
if (null !== $this->apcuPrefix) {
|
359 |
+
apcu_add($this->apcuPrefix.$class, $file);
|
360 |
+
}
|
361 |
+
|
362 |
+
if (false === $file) {
|
363 |
+
// Remember that this class does not exist.
|
364 |
+
$this->missingClasses[$class] = true;
|
365 |
+
}
|
366 |
+
|
367 |
+
return $file;
|
368 |
+
}
|
369 |
+
|
370 |
+
private function findFileWithExtension($class, $ext)
|
371 |
+
{
|
372 |
+
// PSR-4 lookup
|
373 |
+
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
374 |
+
|
375 |
+
$first = $class[0];
|
376 |
+
if (isset($this->prefixLengthsPsr4[$first])) {
|
377 |
+
$subPath = $class;
|
378 |
+
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
379 |
+
$subPath = substr($subPath, 0, $lastPos);
|
380 |
+
$search = $subPath . '\\';
|
381 |
+
if (isset($this->prefixDirsPsr4[$search])) {
|
382 |
+
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
383 |
+
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
384 |
+
if (file_exists($file = $dir . $pathEnd)) {
|
385 |
+
return $file;
|
386 |
+
}
|
387 |
+
}
|
388 |
+
}
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
// PSR-4 fallback dirs
|
393 |
+
foreach ($this->fallbackDirsPsr4 as $dir) {
|
394 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
395 |
+
return $file;
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
+
// PSR-0 lookup
|
400 |
+
if (false !== $pos = strrpos($class, '\\')) {
|
401 |
+
// namespaced class name
|
402 |
+
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
403 |
+
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
404 |
+
} else {
|
405 |
+
// PEAR-like class name
|
406 |
+
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
407 |
+
}
|
408 |
+
|
409 |
+
if (isset($this->prefixesPsr0[$first])) {
|
410 |
+
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
411 |
+
if (0 === strpos($class, $prefix)) {
|
412 |
+
foreach ($dirs as $dir) {
|
413 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
414 |
+
return $file;
|
415 |
+
}
|
416 |
+
}
|
417 |
+
}
|
418 |
+
}
|
419 |
+
}
|
420 |
+
|
421 |
+
// PSR-0 fallback dirs
|
422 |
+
foreach ($this->fallbackDirsPsr0 as $dir) {
|
423 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
424 |
+
return $file;
|
425 |
+
}
|
426 |
+
}
|
427 |
+
|
428 |
+
// PSR-0 include paths.
|
429 |
+
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
430 |
+
return $file;
|
431 |
+
}
|
432 |
+
|
433 |
+
return false;
|
434 |
+
}
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Scope isolated include.
|
439 |
+
*
|
440 |
+
* Prevents access to $this/self from included files.
|
441 |
+
*/
|
442 |
+
function includeFile($file)
|
443 |
+
{
|
444 |
+
include $file;
|
445 |
+
}
|
third-party/vendor/composer/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
Copyright (c) Nils Adermann, Jordi Boggiano
|
3 |
+
|
4 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5 |
+
of this software and associated documentation files (the "Software"), to deal
|
6 |
+
in the Software without restriction, including without limitation the rights
|
7 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8 |
+
copies of the Software, and to permit persons to whom the Software is furnished
|
9 |
+
to do so, subject to the following conditions:
|
10 |
+
|
11 |
+
The above copyright notice and this permission notice shall be included in all
|
12 |
+
copies or substantial portions of the Software.
|
13 |
+
|
14 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20 |
+
THE SOFTWARE.
|
21 |
+
|
third-party/vendor/composer/autoload_classmap.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_classmap.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
'WSAL_Vendor\\MirazMac\\Requirements\\Checker' => $vendorDir . '/mirazmac/php-requirements-checker/src/Checker.php',
|
10 |
+
'WSAL_Vendor\\WP_Async_Request' => $vendorDir . '/deliciousbrains/wp-background-processing/classes/wp-async-request.php',
|
11 |
+
'WSAL_Vendor\\WP_Background_Process' => $vendorDir . '/deliciousbrains/wp-background-processing/classes/wp-background-process.php',
|
12 |
+
);
|
third-party/vendor/composer/autoload_namespaces.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_namespaces.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
);
|
third-party/vendor/composer/autoload_psr4.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_psr4.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
);
|
third-party/vendor/composer/autoload_real.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_real.php @generated by Composer
|
4 |
+
|
5 |
+
class ComposerAutoloaderInit23aaeb6864f7a0ba3de7e8f407e351c7
|
6 |
+
{
|
7 |
+
private static $loader;
|
8 |
+
|
9 |
+
public static function loadClassLoader($class)
|
10 |
+
{
|
11 |
+
if ('Composer\Autoload\ClassLoader' === $class) {
|
12 |
+
require __DIR__ . '/ClassLoader.php';
|
13 |
+
}
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return \Composer\Autoload\ClassLoader
|
18 |
+
*/
|
19 |
+
public static function getLoader()
|
20 |
+
{
|
21 |
+
if (null !== self::$loader) {
|
22 |
+
return self::$loader;
|
23 |
+
}
|
24 |
+
|
25 |
+
spl_autoload_register(array('ComposerAutoloaderInit23aaeb6864f7a0ba3de7e8f407e351c7', 'loadClassLoader'), true, true);
|
26 |
+
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit23aaeb6864f7a0ba3de7e8f407e351c7', 'loadClassLoader'));
|
28 |
+
|
29 |
+
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
+
if ($useStaticLoader) {
|
31 |
+
require_once __DIR__ . '/autoload_static.php';
|
32 |
+
|
33 |
+
call_user_func(\Composer\Autoload\ComposerStaticInit23aaeb6864f7a0ba3de7e8f407e351c7::getInitializer($loader));
|
34 |
+
} else {
|
35 |
+
$classMap = require __DIR__ . '/autoload_classmap.php';
|
36 |
+
if ($classMap) {
|
37 |
+
$loader->addClassMap($classMap);
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
$loader->setClassMapAuthoritative(true);
|
42 |
+
$loader->register(true);
|
43 |
+
|
44 |
+
return $loader;
|
45 |
+
}
|
46 |
+
}
|
third-party/vendor/composer/autoload_static.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_static.php @generated by Composer
|
4 |
+
|
5 |
+
namespace Composer\Autoload;
|
6 |
+
|
7 |
+
class ComposerStaticInit23aaeb6864f7a0ba3de7e8f407e351c7
|
8 |
+
{
|
9 |
+
public static $classMap = array (
|
10 |
+
'WSAL_Vendor\\MirazMac\\Requirements\\Checker' => __DIR__ . '/..' . '/mirazmac/php-requirements-checker/src/Checker.php',
|
11 |
+
'WSAL_Vendor\\WP_Async_Request' => __DIR__ . '/..' . '/deliciousbrains/wp-background-processing/classes/wp-async-request.php',
|
12 |
+
'WSAL_Vendor\\WP_Background_Process' => __DIR__ . '/..' . '/deliciousbrains/wp-background-processing/classes/wp-background-process.php',
|
13 |
+
);
|
14 |
+
|
15 |
+
public static function getInitializer(ClassLoader $loader)
|
16 |
+
{
|
17 |
+
return \Closure::bind(function () use ($loader) {
|
18 |
+
$loader->classMap = ComposerStaticInit23aaeb6864f7a0ba3de7e8f407e351c7::$classMap;
|
19 |
+
}, null, ClassLoader::class);
|
20 |
+
}
|
21 |
+
}
|
third-party/vendor/deliciousbrains/wp-background-processing/classes/wp-async-request.php
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WSAL_Vendor;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* WP Async Request
|
7 |
+
*
|
8 |
+
* @package WP-Background-Processing
|
9 |
+
*/
|
10 |
+
/**
|
11 |
+
* Abstract WP_Async_Request class.
|
12 |
+
*
|
13 |
+
* @abstract
|
14 |
+
*/
|
15 |
+
abstract class WP_Async_Request
|
16 |
+
{
|
17 |
+
/**
|
18 |
+
* Prefix
|
19 |
+
*
|
20 |
+
* (default value: 'wp')
|
21 |
+
*
|
22 |
+
* @var string
|
23 |
+
* @access protected
|
24 |
+
*/
|
25 |
+
protected $prefix = 'wp';
|
26 |
+
/**
|
27 |
+
* Action
|
28 |
+
*
|
29 |
+
* (default value: 'async_request')
|
30 |
+
*
|
31 |
+
* @var string
|
32 |
+
* @access protected
|
33 |
+
*/
|
34 |
+
protected $action = 'async_request';
|
35 |
+
/**
|
36 |
+
* Identifier
|
37 |
+
*
|
38 |
+
* @var mixed
|
39 |
+
* @access protected
|
40 |
+
*/
|
41 |
+
protected $identifier;
|
42 |
+
/**
|
43 |
+
* Data
|
44 |
+
*
|
45 |
+
* (default value: array())
|
46 |
+
*
|
47 |
+
* @var array
|
48 |
+
* @access protected
|
49 |
+
*/
|
50 |
+
protected $data = array();
|
51 |
+
/**
|
52 |
+
* Initiate new async request
|
53 |
+
*/
|
54 |
+
public function __construct()
|
55 |
+
{
|
56 |
+
$this->identifier = $this->prefix . '_' . $this->action;
|
57 |
+
add_action('wp_ajax_' . $this->identifier, array($this, 'maybe_handle'));
|
58 |
+
add_action('wp_ajax_nopriv_' . $this->identifier, array($this, 'maybe_handle'));
|
59 |
+
}
|
60 |
+
/**
|
61 |
+
* Set data used during the request
|
62 |
+
*
|
63 |
+
* @param array $data Data.
|
64 |
+
*
|
65 |
+
* @return $this
|
66 |
+
*/
|
67 |
+
public function data($data)
|
68 |
+
{
|
69 |
+
$this->data = $data;
|
70 |
+
return $this;
|
71 |
+
}
|
72 |
+
/**
|
73 |
+
* Dispatch the async request
|
74 |
+
*
|
75 |
+
* @return array|WP_Error
|
76 |
+
*/
|
77 |
+
public function dispatch()
|
78 |
+
{
|
79 |
+
$url = add_query_arg($this->get_query_args(), $this->get_query_url());
|
80 |
+
$args = $this->get_post_args();
|
81 |
+
return wp_remote_post(esc_url_raw($url), $args);
|
82 |
+
}
|
83 |
+
/**
|
84 |
+
* Get query args
|
85 |
+
*
|
86 |
+
* @return array
|
87 |
+
*/
|
88 |
+
protected function get_query_args()
|
89 |
+
{
|
90 |
+
if (\property_exists($this, 'query_args')) {
|
91 |
+
return $this->query_args;
|
92 |
+
}
|
93 |
+
$args = array('action' => $this->identifier, 'nonce' => wp_create_nonce($this->identifier));
|
94 |
+
/**
|
95 |
+
* Filters the post arguments used during an async request.
|
96 |
+
*
|
97 |
+
* @param array $url
|
98 |
+
*/
|
99 |
+
return apply_filters($this->identifier . '_query_args', $args);
|
100 |
+
}
|
101 |
+
/**
|
102 |
+
* Get query URL
|
103 |
+
*
|
104 |
+
* @return string
|
105 |
+
*/
|
106 |
+
protected function get_query_url()
|
107 |
+
{
|
108 |
+
if (\property_exists($this, 'query_url')) {
|
109 |
+
return $this->query_url;
|
110 |
+
}
|
111 |
+
$url = admin_url('admin-ajax.php');
|
112 |
+
/**
|
113 |
+
* Filters the post arguments used during an async request.
|
114 |
+
*
|
115 |
+
* @param string $url
|
116 |
+
*/
|
117 |
+
return apply_filters($this->identifier . '_query_url', $url);
|
118 |
+
}
|
119 |
+
/**
|
120 |
+
* Get post args
|
121 |
+
*
|
122 |
+
* @return array
|
123 |
+
*/
|
124 |
+
protected function get_post_args()
|
125 |
+
{
|
126 |
+
if (\property_exists($this, 'post_args')) {
|
127 |
+
return $this->post_args;
|
128 |
+
}
|
129 |
+
$args = array('timeout' => 0.01, 'blocking' => \false, 'body' => $this->data, 'cookies' => $_COOKIE, 'sslverify' => apply_filters('https_local_ssl_verify', \false));
|
130 |
+
/**
|
131 |
+
* Filters the post arguments used during an async request.
|
132 |
+
*
|
133 |
+
* @param array $args
|
134 |
+
*/
|
135 |
+
return apply_filters($this->identifier . '_post_args', $args);
|
136 |
+
}
|
137 |
+
/**
|
138 |
+
* Maybe handle
|
139 |
+
*
|
140 |
+
* Check for correct nonce and pass to handler.
|
141 |
+
*/
|
142 |
+
public function maybe_handle()
|
143 |
+
{
|
144 |
+
// Don't lock up other requests while processing
|
145 |
+
\session_write_close();
|
146 |
+
check_ajax_referer($this->identifier, 'nonce');
|
147 |
+
$this->handle();
|
148 |
+
wp_die();
|
149 |
+
}
|
150 |
+
/**
|
151 |
+
* Handle
|
152 |
+
*
|
153 |
+
* Override this method to perform any actions required
|
154 |
+
* during the async request.
|
155 |
+
*/
|
156 |
+
protected abstract function handle();
|
157 |
+
}
|
third-party/vendor/deliciousbrains/wp-background-processing/classes/wp-background-process.php
ADDED
@@ -0,0 +1,440 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WSAL_Vendor;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* WP Background Process
|
7 |
+
*
|
8 |
+
* @package WP-Background-Processing
|
9 |
+
*/
|
10 |
+
/**
|
11 |
+
* Abstract WP_Background_Process class.
|
12 |
+
*
|
13 |
+
* @abstract
|
14 |
+
* @extends WP_Async_Request
|
15 |
+
*/
|
16 |
+
abstract class WP_Background_Process extends WP_Async_Request
|
17 |
+
{
|
18 |
+
/**
|
19 |
+
* Action
|
20 |
+
*
|
21 |
+
* (default value: 'background_process')
|
22 |
+
*
|
23 |
+
* @var string
|
24 |
+
* @access protected
|
25 |
+
*/
|
26 |
+
protected $action = 'background_process';
|
27 |
+
/**
|
28 |
+
* Start time of current process.
|
29 |
+
*
|
30 |
+
* (default value: 0)
|
31 |
+
*
|
32 |
+
* @var int
|
33 |
+
* @access protected
|
34 |
+
*/
|
35 |
+
protected $start_time = 0;
|
36 |
+
/**
|
37 |
+
* Cron_hook_identifier
|
38 |
+
*
|
39 |
+
* @var mixed
|
40 |
+
* @access protected
|
41 |
+
*/
|
42 |
+
protected $cron_hook_identifier;
|
43 |
+
/**
|
44 |
+
* Cron_interval_identifier
|
45 |
+
*
|
46 |
+
* @var mixed
|
47 |
+
* @access protected
|
48 |
+
*/
|
49 |
+
protected $cron_interval_identifier;
|
50 |
+
/**
|
51 |
+
* Initiate new background process
|
52 |
+
*/
|
53 |
+
public function __construct()
|
54 |
+
{
|
55 |
+
parent::__construct();
|
56 |
+
$this->cron_hook_identifier = $this->identifier . '_cron';
|
57 |
+
$this->cron_interval_identifier = $this->identifier . '_cron_interval';
|
58 |
+
add_action($this->cron_hook_identifier, array($this, 'handle_cron_healthcheck'));
|
59 |
+
add_filter('cron_schedules', array($this, 'schedule_cron_healthcheck'));
|
60 |
+
}
|
61 |
+
/**
|
62 |
+
* Dispatch
|
63 |
+
*
|
64 |
+
* @access public
|
65 |
+
* @return void
|
66 |
+
*/
|
67 |
+
public function dispatch()
|
68 |
+
{
|
69 |
+
// Schedule the cron healthcheck.
|
70 |
+
$this->schedule_event();
|
71 |
+
// Perform remote post.
|
72 |
+
return parent::dispatch();
|
73 |
+
}
|
74 |
+
/**
|
75 |
+
* Push to queue
|
76 |
+
*
|
77 |
+
* @param mixed $data Data.
|
78 |
+
*
|
79 |
+
* @return $this
|
80 |
+
*/
|
81 |
+
public function push_to_queue($data)
|
82 |
+
{
|
83 |
+
$this->data[] = $data;
|
84 |
+
return $this;
|
85 |
+
}
|
86 |
+
/**
|
87 |
+
* Save queue
|
88 |
+
*
|
89 |
+
* @return $this
|
90 |
+
*/
|
91 |
+
public function save()
|
92 |
+
{
|
93 |
+
$key = $this->generate_key();
|
94 |
+
if (!empty($this->data)) {
|
95 |
+
update_site_option($key, $this->data);
|
96 |
+
}
|
97 |
+
return $this;
|
98 |
+
}
|
99 |
+
/**
|
100 |
+
* Update queue
|
101 |
+
*
|
102 |
+
* @param string $key Key.
|
103 |
+
* @param array $data Data.
|
104 |
+
*
|
105 |
+
* @return $this
|
106 |
+
*/
|
107 |
+
public function update($key, $data)
|
108 |
+
{
|
109 |
+
if (!empty($data)) {
|
110 |
+
update_site_option($key, $data);
|
111 |
+
}
|
112 |
+
return $this;
|
113 |
+
}
|
114 |
+
/**
|
115 |
+
* Delete queue
|
116 |
+
*
|
117 |
+
* @param string $key Key.
|
118 |
+
*
|
119 |
+
* @return $this
|
120 |
+
*/
|
121 |
+
public function delete($key)
|
122 |
+
{
|
123 |
+
delete_site_option($key);
|
124 |
+
return $this;
|
125 |
+
}
|
126 |
+
/**
|
127 |
+
* Generate key
|
128 |
+
*
|
129 |
+
* Generates a unique key based on microtime. Queue items are
|
130 |
+
* given a unique key so that they can be merged upon save.
|
131 |
+
*
|
132 |
+
* @param int $length Length.
|
133 |
+
*
|
134 |
+
* @return string
|
135 |
+
*/
|
136 |
+
protected function generate_key($length = 64)
|
137 |
+
{
|
138 |
+
$unique = \md5(\microtime() . \rand());
|
139 |
+
$prepend = $this->identifier . '_batch_';
|
140 |
+
return \substr($prepend . $unique, 0, $length);
|
141 |
+
}
|
142 |
+
/**
|
143 |
+
* Maybe process queue
|
144 |
+
*
|
145 |
+
* Checks whether data exists within the queue and that
|
146 |
+
* the process is not already running.
|
147 |
+
*/
|
148 |
+
public function maybe_handle()
|
149 |
+
{
|
150 |
+
// Don't lock up other requests while processing
|
151 |
+
\session_write_close();
|
152 |
+
if ($this->is_process_running()) {
|
153 |
+
// Background process already running.
|
154 |
+
wp_die();
|
155 |
+
}
|
156 |
+
if ($this->is_queue_empty()) {
|
157 |
+
// No data to process.
|
158 |
+
wp_die();
|
159 |
+
}
|
160 |
+
check_ajax_referer($this->identifier, 'nonce');
|
161 |
+
$this->handle();
|
162 |
+
wp_die();
|
163 |
+
}
|
164 |
+
/**
|
165 |
+
* Is queue empty
|
166 |
+
*
|
167 |
+
* @return bool
|
168 |
+
*/
|
169 |
+
protected function is_queue_empty()
|
170 |
+
{
|
171 |
+
global $wpdb;
|
172 |
+
$table = $wpdb->options;
|
173 |
+
$column = 'option_name';
|
174 |
+
if (is_multisite()) {
|
175 |
+
$table = $wpdb->sitemeta;
|
176 |
+
$column = 'meta_key';
|
177 |
+
}
|
178 |
+
$key = $wpdb->esc_like($this->identifier . '_batch_') . '%';
|
179 |
+
$count = $wpdb->get_var($wpdb->prepare("\n\t\t\tSELECT COUNT(*)\n\t\t\tFROM {$table}\n\t\t\tWHERE {$column} LIKE %s\n\t\t", $key));
|
180 |
+
return $count > 0 ? \false : \true;
|
181 |
+
}
|
182 |
+
/**
|
183 |
+
* Is process running
|
184 |
+
*
|
185 |
+
* Check whether the current process is already running
|
186 |
+
* in a background process.
|
187 |
+
*/
|
188 |
+
protected function is_process_running()
|
189 |
+
{
|
190 |
+
if (get_site_transient($this->identifier . '_process_lock')) {
|
191 |
+
// Process already running.
|
192 |
+
return \true;
|
193 |
+
}
|
194 |
+
return \false;
|
195 |
+
}
|
196 |
+
/**
|
197 |
+
* Lock process
|
198 |
+
*
|
199 |
+
* Lock the process so that multiple instances can't run simultaneously.
|
200 |
+
* Override if applicable, but the duration should be greater than that
|
201 |
+
* defined in the time_exceeded() method.
|
202 |
+
*/
|
203 |
+
protected function lock_process()
|
204 |
+
{
|
205 |
+
$this->start_time = \time();
|
206 |
+
// Set start time of current process.
|
207 |
+
$lock_duration = \property_exists($this, 'queue_lock_time') ? $this->queue_lock_time : 60;
|
208 |
+
// 1 minute
|
209 |
+
$lock_duration = apply_filters($this->identifier . '_queue_lock_time', $lock_duration);
|
210 |
+
set_site_transient($this->identifier . '_process_lock', \microtime(), $lock_duration);
|
211 |
+
}
|
212 |
+
/**
|
213 |
+
* Unlock process
|
214 |
+
*
|
215 |
+
* Unlock the process so that other instances can spawn.
|
216 |
+
*
|
217 |
+
* @return $this
|
218 |
+
*/
|
219 |
+
protected function unlock_process()
|
220 |
+
{
|
221 |
+
delete_site_transient($this->identifier . '_process_lock');
|
222 |
+
return $this;
|
223 |
+
}
|
224 |
+
/**
|
225 |
+
* Get batch
|
226 |
+
*
|
227 |
+
* @return stdClass Return the first batch from the queue
|
228 |
+
*/
|
229 |
+
protected function get_batch()
|
230 |
+
{
|
231 |
+
global $wpdb;
|
232 |
+
$table = $wpdb->options;
|
233 |
+
$column = 'option_name';
|
234 |
+
$key_column = 'option_id';
|
235 |
+
$value_column = 'option_value';
|
236 |
+
if (is_multisite()) {
|
237 |
+
$table = $wpdb->sitemeta;
|
238 |
+
$column = 'meta_key';
|
239 |
+
$key_column = 'meta_id';
|
240 |
+
$value_column = 'meta_value';
|
241 |
+
}
|
242 |
+
$key = $wpdb->esc_like($this->identifier . '_batch_') . '%';
|
243 |
+
$query = $wpdb->get_row($wpdb->prepare("\n\t\t\tSELECT *\n\t\t\tFROM {$table}\n\t\t\tWHERE {$column} LIKE %s\n\t\t\tORDER BY {$key_column} ASC\n\t\t\tLIMIT 1\n\t\t", $key));
|
244 |
+
$batch = new \stdClass();
|
245 |
+
$batch->key = $query->{$column};
|
246 |
+
$batch->data = maybe_unserialize($query->{$value_column});
|
247 |
+
return $batch;
|
248 |
+
}
|
249 |
+
/**
|
250 |
+
* Handle
|
251 |
+
*
|
252 |
+
* Pass each queue item to the task handler, while remaining
|
253 |
+
* within server memory and time limit constraints.
|
254 |
+
*/
|
255 |
+
protected function handle()
|
256 |
+
{
|
257 |
+
$this->lock_process();
|
258 |
+
do {
|
259 |
+
$batch = $this->get_batch();
|
260 |
+
foreach ($batch->data as $key => $value) {
|
261 |
+
$task = $this->task($value);
|
262 |
+
if (\false !== $task) {
|
263 |
+
$batch->data[$key] = $task;
|
264 |
+
} else {
|
265 |
+
unset($batch->data[$key]);
|
266 |
+
}
|
267 |
+
if ($this->time_exceeded() || $this->memory_exceeded()) {
|
268 |
+
// Batch limits reached.
|
269 |
+
break;
|
270 |
+
}
|
271 |
+
}
|
272 |
+
// Update or delete current batch.
|
273 |
+
if (!empty($batch->data)) {
|
274 |
+
$this->update($batch->key, $batch->data);
|
275 |
+
} else {
|
276 |
+
$this->delete($batch->key);
|
277 |
+
}
|
278 |
+
} while (!$this->time_exceeded() && !$this->memory_exceeded() && !$this->is_queue_empty());
|
279 |
+
$this->unlock_process();
|
280 |
+
// Start next batch or complete process.
|
281 |
+
if (!$this->is_queue_empty()) {
|
282 |
+
$this->dispatch();
|
283 |
+
} else {
|
284 |
+
$this->complete();
|
285 |
+
}
|
286 |
+
wp_die();
|
287 |
+
}
|
288 |
+
/**
|
289 |
+
* Memory exceeded
|
290 |
+
*
|
291 |
+
* Ensures the batch process never exceeds 90%
|
292 |
+
* of the maximum WordPress memory.
|
293 |
+
*
|
294 |
+
* @return bool
|
295 |
+
*/
|
296 |
+
protected function memory_exceeded()
|
297 |
+
{
|
298 |
+
$memory_limit = $this->get_memory_limit() * 0.9;
|
299 |
+
// 90% of max memory
|
300 |
+
$current_memory = \memory_get_usage(\true);
|
301 |
+
$return = \false;
|
302 |
+
if ($current_memory >= $memory_limit) {
|
303 |
+
$return = \true;
|
304 |
+
}
|
305 |
+
return apply_filters($this->identifier . '_memory_exceeded', $return);
|
306 |
+
}
|
307 |
+
/**
|
308 |
+
* Get memory limit
|
309 |
+
*
|
310 |
+
* @return int
|
311 |
+
*/
|
312 |
+
protected function get_memory_limit()
|
313 |
+
{
|
314 |
+
if (\function_exists('ini_get')) {
|
315 |
+
$memory_limit = \ini_get('memory_limit');
|
316 |
+
} else {
|
317 |
+
// Sensible default.
|
318 |
+
$memory_limit = '128M';
|
319 |
+
}
|
320 |
+
if (!$memory_limit || -1 === \intval($memory_limit)) {
|
321 |
+
// Unlimited, set to 32GB.
|
322 |
+
$memory_limit = '32000M';
|
323 |
+
}
|
324 |
+
return wp_convert_hr_to_bytes($memory_limit);
|
325 |
+
}
|
326 |
+
/**
|
327 |
+
* Time exceeded.
|
328 |
+
*
|
329 |
+
* Ensures the batch never exceeds a sensible time limit.
|
330 |
+
* A timeout limit of 30s is common on shared hosting.
|
331 |
+
*
|
332 |
+
* @return bool
|
333 |
+
*/
|
334 |
+
protected function time_exceeded()
|
335 |
+
{
|
336 |
+
$finish = $this->start_time + apply_filters($this->identifier . '_default_time_limit', 20);
|
337 |
+
// 20 seconds
|
338 |
+
$return = \false;
|
339 |
+
if (\time() >= $finish) {
|
340 |
+
$return = \true;
|
341 |
+
}
|
342 |
+
return apply_filters($this->identifier . '_time_exceeded', $return);
|
343 |
+
}
|
344 |
+
/**
|
345 |
+
* Complete.
|
346 |
+
*
|
347 |
+
* Override if applicable, but ensure that the below actions are
|
348 |
+
* performed, or, call parent::complete().
|
349 |
+
*/
|
350 |
+
protected function complete()
|
351 |
+
{
|
352 |
+
// Unschedule the cron healthcheck.
|
353 |
+
$this->clear_scheduled_event();
|
354 |
+
}
|
355 |
+
/**
|
356 |
+
* Schedule cron healthcheck
|
357 |
+
*
|
358 |
+
* @access public
|
359 |
+
*
|
360 |
+
* @param mixed $schedules Schedules.
|
361 |
+
*
|
362 |
+
* @return mixed
|
363 |
+
*/
|
364 |
+
public function schedule_cron_healthcheck($schedules)
|
365 |
+
{
|
366 |
+
$interval = apply_filters($this->identifier . '_cron_interval', 5);
|
367 |
+
if (\property_exists($this, 'cron_interval')) {
|
368 |
+
$interval = apply_filters($this->identifier . '_cron_interval', $this->cron_interval);
|
369 |
+
}
|
370 |
+
// Adds every 5 minutes to the existing schedules.
|
371 |
+
$schedules[$this->identifier . '_cron_interval'] = array('interval' => \MINUTE_IN_SECONDS * $interval, 'display' => \sprintf(__('Every %d Minutes'), $interval));
|
372 |
+
return $schedules;
|
373 |
+
}
|
374 |
+
/**
|
375 |
+
* Handle cron healthcheck
|
376 |
+
*
|
377 |
+
* Restart the background process if not already running
|
378 |
+
* and data exists in the queue.
|
379 |
+
*/
|
380 |
+
public function handle_cron_healthcheck()
|
381 |
+
{
|
382 |
+
if ($this->is_process_running()) {
|
383 |
+
// Background process already running.
|
384 |
+
exit;
|
385 |
+
}
|
386 |
+
if ($this->is_queue_empty()) {
|
387 |
+
// No data to process.
|
388 |
+
$this->clear_scheduled_event();
|
389 |
+
exit;
|
390 |
+
}
|
391 |
+
$this->handle();
|
392 |
+
exit;
|
393 |
+
}
|
394 |
+
/**
|
395 |
+
* Schedule event
|
396 |
+
*/
|
397 |
+
protected function schedule_event()
|
398 |
+
{
|
399 |
+
if (!wp_next_scheduled($this->cron_hook_identifier)) {
|
400 |
+
wp_schedule_event(\time(), $this->cron_interval_identifier, $this->cron_hook_identifier);
|
401 |
+
}
|
402 |
+
}
|
403 |
+
/**
|
404 |
+
* Clear scheduled event
|
405 |
+
*/
|
406 |
+
protected function clear_scheduled_event()
|
407 |
+
{
|
408 |
+
$timestamp = wp_next_scheduled($this->cron_hook_identifier);
|
409 |
+
if ($timestamp) {
|
410 |
+
wp_unschedule_event($timestamp, $this->cron_hook_identifier);
|
411 |
+
}
|
412 |
+
}
|
413 |
+
/**
|
414 |
+
* Cancel Process
|
415 |
+
*
|
416 |
+
* Stop processing queue items, clear cronjob and delete batch.
|
417 |
+
*
|
418 |
+
*/
|
419 |
+
public function cancel_process()
|
420 |
+
{
|
421 |
+
if (!$this->is_queue_empty()) {
|
422 |
+
$batch = $this->get_batch();
|
423 |
+
$this->delete($batch->key);
|
424 |
+
wp_clear_scheduled_hook($this->cron_hook_identifier);
|
425 |
+
}
|
426 |
+
}
|
427 |
+
/**
|
428 |
+
* Task
|
429 |
+
*
|
430 |
+
* Override this method to perform any actions required on each
|
431 |
+
* queue item. Return the modified item for further processing
|
432 |
+
* in the next pass through. Or, return false to remove the
|
433 |
+
* item from the queue.
|
434 |
+
*
|
435 |
+
* @param mixed $item Queue item to iterate over.
|
436 |
+
*
|
437 |
+
* @return mixed
|
438 |
+
*/
|
439 |
+
protected abstract function task($item);
|
440 |
+
}
|
third-party/vendor/deliciousbrains/wp-background-processing/wp-background-processing.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WSAL_Vendor;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* WP-Background Processing
|
7 |
+
*
|
8 |
+
* @package WP-Background-Processing
|
9 |
+
*/
|
10 |
+
/*
|
11 |
+
Plugin Name: WP Background Processing
|
12 |
+
Plugin URI: https://github.com/A5hleyRich/wp-background-processing
|
13 |
+
Description: Asynchronous requests and background processing in WordPress.
|
14 |
+
Author: Delicious Brains Inc.
|
15 |
+
Version: 1.0
|
16 |
+
Author URI: https://deliciousbrains.com/
|
17 |
+
GitHub Plugin URI: https://github.com/A5hleyRich/wp-background-processing
|
18 |
+
GitHub Branch: master
|
19 |
+
*/
|
20 |
+
if (!\class_exists('WSAL_Vendor\\WP_Async_Request')) {
|
21 |
+
require_once plugin_dir_path(__FILE__) . 'classes/wp-async-request.php';
|
22 |
+
}
|
23 |
+
if (!\class_exists('WSAL_Vendor\\WP_Background_Process')) {
|
24 |
+
require_once plugin_dir_path(__FILE__) . 'classes/wp-background-process.php';
|
25 |
+
}
|
third-party/vendor/mirazmac/php-requirements-checker/src/Checker.php
ADDED
@@ -0,0 +1,780 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WSAL_Vendor\MirazMac\Requirements;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* PHP Requirements Checker
|
7 |
+
*
|
8 |
+
* A quick library to check the current environment against a set of defined requirements.
|
9 |
+
* Currently it supports checking for PHP version, OS, Extensions, PHP INI values,
|
10 |
+
* Functions, Classes, Apache Modules and local Files and Folders.
|
11 |
+
*
|
12 |
+
* @author Miraz Mac <mirazmac@gmail.com>
|
13 |
+
* @link https://mirazmac.com Author Homepage
|
14 |
+
* @version 0.1
|
15 |
+
* @license LICENSE The MIT License
|
16 |
+
* @package MirazMac\Requirements
|
17 |
+
*/
|
18 |
+
class Checker
|
19 |
+
{
|
20 |
+
/**
|
21 |
+
* Identifier for is_file() check
|
22 |
+
*/
|
23 |
+
const CHECK_IS_FILE = 'is_file';
|
24 |
+
/**
|
25 |
+
* Identifier for is_dir() check
|
26 |
+
*/
|
27 |
+
const CHECK_IS_DIR = 'is_dir';
|
28 |
+
/**
|
29 |
+
* Identifier for is_readable() check
|
30 |
+
*/
|
31 |
+
const CHECK_IS_READABLE = 'is_readable';
|
32 |
+
/**
|
33 |
+
* Identifier for is_writable() check
|
34 |
+
*/
|
35 |
+
const CHECK_IS_WRITABLE = 'is_writable';
|
36 |
+
/**
|
37 |
+
* Identifier for file_exists() check
|
38 |
+
*/
|
39 |
+
const CHECK_FILE_EXISTS = 'file_exists';
|
40 |
+
/**
|
41 |
+
* Identifier for Unix
|
42 |
+
*/
|
43 |
+
const OS_UNIX = 'UNIX';
|
44 |
+
/**
|
45 |
+
* Identifier for Windows
|
46 |
+
*/
|
47 |
+
const OS_DOS = 'DOS';
|
48 |
+
/**
|
49 |
+
* Requirements as an array
|
50 |
+
*
|
51 |
+
* @var array
|
52 |
+
*/
|
53 |
+
protected $requirements;
|
54 |
+
/**
|
55 |
+
* Parsed state of the requirements
|
56 |
+
*
|
57 |
+
* @var array
|
58 |
+
*/
|
59 |
+
protected $parsedRequirements;
|
60 |
+
/**
|
61 |
+
* Stores if current requirements criteria is satisfied or not
|
62 |
+
*
|
63 |
+
* @var boolean
|
64 |
+
*/
|
65 |
+
protected $satisfied = \true;
|
66 |
+
/**
|
67 |
+
* Basic locales for comparison operators
|
68 |
+
*
|
69 |
+
* @var array
|
70 |
+
*/
|
71 |
+
protected $locale = ['>' => 'greater than', '=' => 'equal to', '<' => 'lower than', '>=' => 'greater than or equal to', '=<' => 'lower than or equal to'];
|
72 |
+
/**
|
73 |
+
* Array of the total errors
|
74 |
+
*
|
75 |
+
* @var array
|
76 |
+
*/
|
77 |
+
protected $errors = [];
|
78 |
+
/**
|
79 |
+
* Constructor
|
80 |
+
*/
|
81 |
+
public function __construct()
|
82 |
+
{
|
83 |
+
$this->resetRequirements();
|
84 |
+
}
|
85 |
+
/**
|
86 |
+
* Perform checks on the passed requirements
|
87 |
+
*
|
88 |
+
* @return array The parsed requirements
|
89 |
+
*/
|
90 |
+
public function check()
|
91 |
+
{
|
92 |
+
$this->parsedRequirements['system'] = $this->validateSystemRequirement();
|
93 |
+
$this->parsedRequirements['extensions'] = $this->validateExtensionRequirement();
|
94 |
+
$this->parsedRequirements['apache_modules'] = $this->validateApacheModuleRequirement();
|
95 |
+
$this->parsedRequirements['functions'] = $this->validateFunctionRequirement();
|
96 |
+
$this->parsedRequirements['classes'] = $this->validateClassRequirement();
|
97 |
+
$this->parsedRequirements['ini_values'] = $this->validateIniRequirement();
|
98 |
+
$this->parsedRequirements['files'] = $this->validateFileRequirement();
|
99 |
+
return $this->parsedRequirements;
|
100 |
+
}
|
101 |
+
/**
|
102 |
+
* Resets the requirements to default
|
103 |
+
*
|
104 |
+
* @return Checker
|
105 |
+
*/
|
106 |
+
public function resetRequirements()
|
107 |
+
{
|
108 |
+
$default = ['system' => ['php_version' => null, 'os' => null], 'ini_values' => [], 'files' => [], 'extensions' => [], 'classes' => [], 'functions' => [], 'apache_modules' => []];
|
109 |
+
$this->requirements = $default;
|
110 |
+
$this->parsedRequirements = $default;
|
111 |
+
return $this;
|
112 |
+
}
|
113 |
+
/**
|
114 |
+
* Return the requirements added currently
|
115 |
+
*
|
116 |
+
* @return array
|
117 |
+
*/
|
118 |
+
public function getRequirements()
|
119 |
+
{
|
120 |
+
return $this->requirements;
|
121 |
+
}
|
122 |
+
/**
|
123 |
+
* Returns if the last requirement check was satisfying or not
|
124 |
+
*
|
125 |
+
* @return boolean
|
126 |
+
*/
|
127 |
+
public function isSatisfied()
|
128 |
+
{
|
129 |
+
return $this->satisfied;
|
130 |
+
}
|
131 |
+
/**
|
132 |
+
* Returns all the errors as array
|
133 |
+
*
|
134 |
+
* @return array
|
135 |
+
*/
|
136 |
+
public function getErrors()
|
137 |
+
{
|
138 |
+
return $this->errors;
|
139 |
+
}
|
140 |
+
/**
|
141 |
+
* Validates only the PHP INI requirements
|
142 |
+
*
|
143 |
+
* @return array
|
144 |
+
*/
|
145 |
+
public function validateIniRequirement()
|
146 |
+
{
|
147 |
+
$values = [];
|
148 |
+
foreach ($this->requirements['ini_values'] as $key => $value) {
|
149 |
+
$setting = \ini_get($key);
|
150 |
+
if ($setting == 'On' || $setting == '1') {
|
151 |
+
$setting = \true;
|
152 |
+
} elseif ($setting == 'Off' || $setting == '' || $setting == '0') {
|
153 |
+
$setting = \false;
|
154 |
+
}
|
155 |
+
$data = $this->getParsedStructure();
|
156 |
+
$data['preferred'] = $value;
|
157 |
+
$data['current'] = $setting;
|
158 |
+
// So you only want to show the value?
|
159 |
+
// No validation? Fine.
|
160 |
+
if (\is_null($value)) {
|
161 |
+
$data['satisfied'] = \true;
|
162 |
+
$values[$key] = $data;
|
163 |
+
continue;
|
164 |
+
}
|
165 |
+
if (\is_bool($value)) {
|
166 |
+
$data['preferred'] = $value ? 'On' : 'Off';
|
167 |
+
$data['current'] = $setting ? 'On' : 'Off';
|
168 |
+
if ($value) {
|
169 |
+
$data['satisfied'] = $setting;
|
170 |
+
} else {
|
171 |
+
$data['satisfied'] = !$setting;
|
172 |
+
}
|
173 |
+
if (!$data['satisfied']) {
|
174 |
+
$this->satisfied = \false;
|
175 |
+
$data['message'] = "The php.ini setting `{$key}` should be {$data['preferred']}, currently it's set to {$data['current']}";
|
176 |
+
$this->errors[] = $data['message'];
|
177 |
+
}
|
178 |
+
$values[$key] = $data;
|
179 |
+
continue;
|
180 |
+
}
|
181 |
+
$parsed = $this->parseComparisonString($value, '=');
|
182 |
+
$value = $parsed['plain'];
|
183 |
+
$operator = $parsed['operator'];
|
184 |
+
$newcfg = $this->returnBytes($setting);
|
185 |
+
$newval = $this->returnBytes($value);
|
186 |
+
// Acknowledge '-1'(unlimited) values
|
187 |
+
// @see https://github.com/MirazMac/php-requirements-checker/issues/2
|
188 |
+
$data['satisfied'] = $setting == '-1' ? \true : $this->looseComparison($newcfg, $operator, $newval);
|
189 |
+
if (!$data['satisfied']) {
|
190 |
+
$this->satisfied = \false;
|
191 |
+
$data['message'] = "The php.ini setting `{$key}` should be {$this->locale[$operator]} {$value}. Currently it's set to {$setting}";
|
192 |
+
$this->errors[] = $data['message'];
|
193 |
+
}
|
194 |
+
$values[$key] = $data;
|
195 |
+
}
|
196 |
+
return $values;
|
197 |
+
}
|
198 |
+
/**
|
199 |
+
* Validates only the classes requirement
|
200 |
+
*
|
201 |
+
* @return array
|
202 |
+
*/
|
203 |
+
public function validateClassRequirement()
|
204 |
+
{
|
205 |
+
$values = [];
|
206 |
+
foreach ($this->requirements['classes'] as $key => $class) {
|
207 |
+
$data = $this->getParsedStructure();
|
208 |
+
$data['preferred'] = $class;
|
209 |
+
$data['current'] = \false;
|
210 |
+
$satisfied = \false;
|
211 |
+
foreach (\explode('|', $class) as $className) {
|
212 |
+
if (\class_exists($this->ensureNamespace($className))) {
|
213 |
+
$satisfied = \true;
|
214 |
+
break;
|
215 |
+
}
|
216 |
+
}
|
217 |
+
if ($satisfied) {
|
218 |
+
$data['satisfied'] = \true;
|
219 |
+
$data['current'] = \true;
|
220 |
+
} else {
|
221 |
+
$this->satisfied = \false;
|
222 |
+
$data['message'] = "Class `{$class}` is not defined";
|
223 |
+
$this->errors[] = $data['message'];
|
224 |
+
}
|
225 |
+
$values[$class] = $data;
|
226 |
+
}
|
227 |
+
return $values;
|
228 |
+
}
|
229 |
+
/**
|
230 |
+
* Validates apache module requirements
|
231 |
+
*
|
232 |
+
* @return array
|
233 |
+
*/
|
234 |
+
public function validateApacheModuleRequirement()
|
235 |
+
{
|
236 |
+
$values = [];
|
237 |
+
// Run Only in apache servers
|
238 |
+
if (!\function_exists('apache_get_modules')) {
|
239 |
+
return $values;
|
240 |
+
}
|
241 |
+
$modules = \apache_get_modules();
|
242 |
+
foreach ($this->requirements['apache_modules'] as $key => $module) {
|
243 |
+
$structure = $this->getParsedStructure();
|
244 |
+
$structure['preferred'] = $module;
|
245 |
+
$structure['current'] = \true;
|
246 |
+
$structure['satisfied'] = \true;
|
247 |
+
$satisfied = \false;
|
248 |
+
foreach (\explode('|', $module) as $moduleName) {
|
249 |
+
if (\in_array($moduleName, $modules)) {
|
250 |
+
$satisfied = \true;
|
251 |
+
break;
|
252 |
+
}
|
253 |
+
}
|
254 |
+
if (!$satisfied) {
|
255 |
+
$structure['satisfied'] = \false;
|
256 |
+
$structure['current'] = \false;
|
257 |
+
$this->satisfied = \false;
|
258 |
+
$structure['message'] = "Apache module `{$module}` is not loaded";
|
259 |
+
$this->errors[] = $structure['message'];
|
260 |
+
}
|
261 |
+
$values[$module] = $structure;
|
262 |
+
}
|
263 |
+
return $values;
|
264 |
+
}
|
265 |
+
/**
|
266 |
+
* Validates only the functions requirement
|
267 |
+
*
|
268 |
+
* @return array
|
269 |
+
*/
|
270 |
+
public function validateFunctionRequirement()
|
271 |
+
{
|
272 |
+
$values = [];
|
273 |
+
foreach ($this->requirements['functions'] as $key => $func) {
|
274 |
+
$data = $this->getParsedStructure();
|
275 |
+
$data['preferred'] = $func;
|
276 |
+
$data['current'] = \false;
|
277 |
+
$satisfied = \false;
|
278 |
+
foreach (\explode('|', $func) as $function) {
|
279 |
+
if (\function_exists($function)) {
|
280 |
+
$satisfied = \true;
|
281 |
+
break;
|
282 |
+
}
|
283 |
+
}
|
284 |
+
if ($satisfied) {
|
285 |
+
$data['satisfied'] = \true;
|
286 |
+
$data['current'] = \true;
|
287 |
+
} else {
|
288 |
+
$this->satisfied = \false;
|
289 |
+
$data['message'] = "PHP function `{$func}()` is not defined";
|
290 |
+
$this->errors[] = $data['message'];
|
291 |
+
}
|
292 |
+
$values[$func] = $data;
|
293 |
+
}
|
294 |
+
return $values;
|
295 |
+
}
|
296 |
+
/**
|
297 |
+
* Validates only the extensions requirement
|
298 |
+
*
|
299 |
+
* @return array
|
300 |
+
*/
|
301 |
+
public function validateExtensionRequirement()
|
302 |
+
{
|
303 |
+
$values = [];
|
304 |
+
foreach ($this->requirements['extensions'] as $key => $ext) {
|
305 |
+
$data = $this->getParsedStructure();
|
306 |
+
$data['preferred'] = $ext;
|
307 |
+
$data['current'] = \false;
|
308 |
+
$satisfied = \false;
|
309 |
+
foreach (\explode('|', $ext) as $extension) {
|
310 |
+
if (\extension_loaded($extension)) {
|
311 |
+
$satisfied = \true;
|
312 |
+
break;
|
313 |
+
}
|
314 |
+
}
|
315 |
+
if ($satisfied) {
|
316 |
+
$data['satisfied'] = \true;
|
317 |
+
$data['current'] = \true;
|
318 |
+
} else {
|
319 |
+
$this->satisfied = \false;
|
320 |
+
$data['message'] = "PHP extension {$ext} is not loaded";
|
321 |
+
$this->errors[] = $data['message'];
|
322 |
+
}
|
323 |
+
$values[$ext] = $data;
|
324 |
+
}
|
325 |
+
return $values;
|
326 |
+
}
|
327 |
+
/**
|
328 |
+
* Validate only the system requirements, includes the php version, OS and apache version
|
329 |
+
*
|
330 |
+
* @return array
|
331 |
+
*/
|
332 |
+
public function validateSystemRequirement()
|
333 |
+
{
|
334 |
+
$values = [];
|
335 |
+
if ($this->requirements['system']['php_version']) {
|
336 |
+
$structure = $this->getParsedStructure();
|
337 |
+
$structure['current'] = \PHP_VERSION;
|
338 |
+
$structure['preferred'] = $this->requirements['system']['php_version'];
|
339 |
+
$parsed = $this->parseComparisonString($this->requirements['system']['php_version'], '>=');
|
340 |
+
$result = \version_compare(\PHP_VERSION, $parsed['plain'], $parsed['operator']);
|
341 |
+
$structure['satisfied'] = $result;
|
342 |
+
if (!$result) {
|
343 |
+
$this->satisfied = \false;
|
344 |
+
$structure['message'] = \sprintf('PHP version must be %1$s %2$s', $this->locale[$parsed['operator']], $structure['preferred']);
|
345 |
+
$this->errors[] = $structure['message'];
|
346 |
+
}
|
347 |
+
$values['php_version'] = $structure;
|
348 |
+
}
|
349 |
+
// Now the OS
|
350 |
+
if ($this->requirements['system']['os']) {
|
351 |
+
$structureOS = $this->getParsedStructure();
|
352 |
+
$os = \DIRECTORY_SEPARATOR === '\\' ? static::OS_DOS : static::OS_UNIX;
|
353 |
+
$structureOS['satisfied'] = \true;
|
354 |
+
$structureOS['preferred'] = $this->requirements['system']['os'];
|
355 |
+
$structureOS['current'] = $os;
|
356 |
+
if ($os !== $structureOS['preferred']) {
|
357 |
+
$structureOS['satisfied'] = \false;
|
358 |
+
$this->satisfied = \false;
|
359 |
+
$structureOS['message'] = "The operating system must be {$structureOS['preferred']}, currently we are on a {$os} system";
|
360 |
+
$this->errors[] = $structureOS['message'];
|
361 |
+
}
|
362 |
+
$values['os'] = $structureOS;
|
363 |
+
}
|
364 |
+
return $values;
|
365 |
+
}
|
366 |
+
/**
|
367 |
+
* Validates only the file requirements
|
368 |
+
*
|
369 |
+
* @return array
|
370 |
+
*/
|
371 |
+
public function validateFileRequirement()
|
372 |
+
{
|
373 |
+
$values = [];
|
374 |
+
foreach ($this->requirements['files'] as $file => $checks) {
|
375 |
+
$structure = $this->getParsedStructure();
|
376 |
+
$file = $this->unixPath($file);
|
377 |
+
$structure['path'] = $file;
|
378 |
+
$type = 'path';
|
379 |
+
$exists = \file_exists($file);
|
380 |
+
if (\is_file($file)) {
|
381 |
+
$type = 'file';
|
382 |
+
} elseif (\is_dir($file)) {
|
383 |
+
$type = 'directory';
|
384 |
+
}
|
385 |
+
foreach ($checks as $check) {
|
386 |
+
$data = $structure;
|
387 |
+
$data['preferred'] = $check;
|
388 |
+
$data['satisfied'] = (bool) $check($file);
|
389 |
+
$data['current'] = $data['satisfied'];
|
390 |
+
if (!$data['satisfied']) {
|
391 |
+
$this->satisfied = \false;
|
392 |
+
switch ($check) {
|
393 |
+
case static::CHECK_IS_DIR:
|
394 |
+
$data['message'] = "The path `{$file}` must be a directory";
|
395 |
+
if (!$exists) {
|
396 |
+
$data['message'] .= ", but the path doesn't even exist";
|
397 |
+
} elseif ($type === 'file') {
|
398 |
+
$data['message'] .= ', but the path is a file';
|
399 |
+
}
|
400 |
+
$data['current'] = "No directory";
|
401 |
+
break;
|
402 |
+
case static::CHECK_IS_FILE:
|
403 |
+
$data['message'] = "The path `{$file}` must be a file";
|
404 |
+
$data['current'] = "No file";
|
405 |
+
if (!$exists) {
|
406 |
+
$data['message'] .= ", but the path doesn't even exist";
|
407 |
+
} elseif ($type === 'directory') {
|
408 |
+
$data['message'] .= ', but the path is a directory';
|
409 |
+
}
|
410 |
+
break;
|
411 |
+
case static::CHECK_FILE_EXISTS:
|
412 |
+
$data['message'] = "The path `{$file}` doesn't exist";
|
413 |
+
$data['current'] = "Doesn't exist";
|
414 |
+
break;
|
415 |
+
case static::CHECK_IS_READABLE:
|
416 |
+
case static::CHECK_IS_WRITABLE:
|
417 |
+
$humanFriendly = \str_replace('is_', '', $check);
|
418 |
+
$data['current'] = "Not {$humanFriendly}";
|
419 |
+
$data['message'] = "The path `{$file}` must be {$humanFriendly}";
|
420 |
+
if (!$exists) {
|
421 |
+
$data['message'] .= ", but the path doesn't even exist";
|
422 |
+
}
|
423 |
+
break;
|
424 |
+
}
|
425 |
+
$this->errors[] = $data['message'];
|
426 |
+
}
|
427 |
+
$values[] = $data;
|
428 |
+
}
|
429 |
+
}
|
430 |
+
return $values;
|
431 |
+
}
|
432 |
+
/**
|
433 |
+
* Require a certain OS
|
434 |
+
*
|
435 |
+
* @param string $os The OS would pass the test
|
436 |
+
* Possible values: DOS, WIN
|
437 |
+
* @return Checker
|
438 |
+
*/
|
439 |
+
public function requireOS($os)
|
440 |
+
{
|
441 |
+
$this->requirements['system']['os'] = $os;
|
442 |
+
return $this;
|
443 |
+
}
|
444 |
+
/**
|
445 |
+
* Require php.ini config values
|
446 |
+
*
|
447 |
+
* @param array $values As key => value format
|
448 |
+
* @return Checker
|
449 |
+
*/
|
450 |
+
public function requireIniValues(array $values)
|
451 |
+
{
|
452 |
+
foreach ($values as $key => $value) {
|
453 |
+
$this->requirements['ini_values'][$key] = $value;
|
454 |
+
}
|
455 |
+
return $this;
|
456 |
+
}
|
457 |
+
/**
|
458 |
+
* Set required PHP version
|
459 |
+
*
|
460 |
+
* @param string $version The required PHP version
|
461 |
+
* @return Checker
|
462 |
+
*/
|
463 |
+
public function requirePhpVersion($version)
|
464 |
+
{
|
465 |
+
$this->requirements['system']['php_version'] = $version;
|
466 |
+
return $this;
|
467 |
+
}
|
468 |
+
/**
|
469 |
+
* Add required extensions
|
470 |
+
*
|
471 |
+
* @param array|string $extensions The exact name(s) of the extension as they appear of the phpinfo() page
|
472 |
+
* @return Checker
|
473 |
+
*/
|
474 |
+
public function requirePhpExtensions(array $extensions)
|
475 |
+
{
|
476 |
+
foreach ($extensions as $ext) {
|
477 |
+
$this->requirements['extensions'][$ext] = $ext;
|
478 |
+
}
|
479 |
+
return $this;
|
480 |
+
}
|
481 |
+
/**
|
482 |
+
* Add required functions(s)
|
483 |
+
*
|
484 |
+
* @param array $functions Required function(s) name
|
485 |
+
* @return Checker
|
486 |
+
*/
|
487 |
+
public function requireFunctions(array $functions)
|
488 |
+
{
|
489 |
+
foreach ($functions as $func) {
|
490 |
+
$this->requirements['functions'][$func] = $func;
|
491 |
+
}
|
492 |
+
return $this;
|
493 |
+
}
|
494 |
+
/**
|
495 |
+
* Add required classe(es)
|
496 |
+
*
|
497 |
+
* @param array $classes Required class(es) name
|
498 |
+
* @return Checker
|
499 |
+
*/
|
500 |
+
public function requireClasses(array $classes)
|
501 |
+
{
|
502 |
+
foreach ($classes as $class) {
|
503 |
+
$this->requirements['classes'][$class] = $class;
|
504 |
+
}
|
505 |
+
return $this;
|
506 |
+
}
|
507 |
+
/**
|
508 |
+
* Require list of apache modules (check will be performed only if server is apache)
|
509 |
+
*
|
510 |
+
* @param array $modules
|
511 |
+
* @return Checker
|
512 |
+
*/
|
513 |
+
public function requireApacheModules(array $modules)
|
514 |
+
{
|
515 |
+
foreach ($modules as $module) {
|
516 |
+
$this->requirements['apache_modules'][$module] = $module;
|
517 |
+
}
|
518 |
+
return $this;
|
519 |
+
}
|
520 |
+
/**
|
521 |
+
* Require a file or folder with appropriate check
|
522 |
+
*
|
523 |
+
* @param string $path Path to the file/directory
|
524 |
+
* @param string $check Any of the supported checks, defaults to file_exists
|
525 |
+
* @return Checker
|
526 |
+
*/
|
527 |
+
public function requireFile($path, $check = self::CHECK_FILE_EXISTS)
|
528 |
+
{
|
529 |
+
$supportedChecks = ['is_file', 'is_dir', 'is_readable', 'is_writable', 'file_exists'];
|
530 |
+
if (!\in_array($check, $supportedChecks)) {
|
531 |
+
throw new \InvalidArgumentException("No such check is supported!");
|
532 |
+
}
|
533 |
+
$this->requirements['files'][$path][] = $check;
|
534 |
+
return $this;
|
535 |
+
}
|
536 |
+
/**
|
537 |
+
* Alias of $this->requireFile() for people who are extra concerned about verbosity
|
538 |
+
*
|
539 |
+
* @param string $path Path to the file/directory
|
540 |
+
* @param string $check Any of the supported checks, defaults to file_exists
|
541 |
+
* @return Checker
|
542 |
+
*/
|
543 |
+
public function requireDirectory($path, $check = self::CHECK_FILE_EXISTS)
|
544 |
+
{
|
545 |
+
return $this->requireFile($path, $check);
|
546 |
+
}
|
547 |
+
/**
|
548 |
+
* Remove extensions requirements
|
549 |
+
*
|
550 |
+
* @param array $keys extensions to remove as an array
|
551 |
+
* @return Checker
|
552 |
+
*/
|
553 |
+
public function removeExtensionsRequirement(array $keys)
|
554 |
+
{
|
555 |
+
foreach ($keys as $key) {
|
556 |
+
unset($this->requirements['extensions'][$key]);
|
557 |
+
}
|
558 |
+
return $this;
|
559 |
+
}
|
560 |
+
/**
|
561 |
+
* Remove apache modules requirements
|
562 |
+
*
|
563 |
+
* @param array $keys apache modules to remove as an array
|
564 |
+
* @return Checker
|
565 |
+
*/
|
566 |
+
public function removeApacheModulesRequirement(array $keys)
|
567 |
+
{
|
568 |
+
foreach ($keys as $key) {
|
569 |
+
unset($this->requirements['apache_modules'][$key]);
|
570 |
+
}
|
571 |
+
return $this;
|
572 |
+
}
|
573 |
+
/**
|
574 |
+
* Remove classes requirements
|
575 |
+
*
|
576 |
+
* @param array $keys classes to remove as an array
|
577 |
+
* @return Checker
|
578 |
+
*/
|
579 |
+
public function removeClassesRequirement(array $keys)
|
580 |
+
{
|
581 |
+
foreach ($keys as $key) {
|
582 |
+
unset($this->requirements['classes'][$key]);
|
583 |
+
}
|
584 |
+
return $this;
|
585 |
+
}
|
586 |
+
/**
|
587 |
+
* Remove functions requirements
|
588 |
+
*
|
589 |
+
* @param array $keys functions to remove as an array
|
590 |
+
* @return Checker
|
591 |
+
*/
|
592 |
+
public function removeFunctionsRequirement(array $keys)
|
593 |
+
{
|
594 |
+
foreach ($keys as $key) {
|
595 |
+
unset($this->requirements['functions'][$key]);
|
596 |
+
}
|
597 |
+
return $this;
|
598 |
+
}
|
599 |
+
/**
|
600 |
+
* Remove INI requirements
|
601 |
+
*
|
602 |
+
* @param array $keys Keys as an array
|
603 |
+
* @return Checker
|
604 |
+
*/
|
605 |
+
public function removeIniValuesRequirement(array $keys)
|
606 |
+
{
|
607 |
+
foreach ($keys as $key) {
|
608 |
+
unset($this->requirements['ini_values'][$key]);
|
609 |
+
}
|
610 |
+
return $this;
|
611 |
+
}
|
612 |
+
/**
|
613 |
+
* Remove a file/directory requirement
|
614 |
+
*
|
615 |
+
* @param string $path The file path that you added earlier using self::requireFile()
|
616 |
+
* @param string|null The check name to remove, set this to null/empty and
|
617 |
+
* the entire path will be removed with all the checks.
|
618 |
+
* @return Checker
|
619 |
+
*/
|
620 |
+
public function removeFilesRequirement($path, $check = null)
|
621 |
+
{
|
622 |
+
// Make sure the path is added
|
623 |
+
if (!isset($this->requirements['files'][$path])) {
|
624 |
+
return $this;
|
625 |
+
}
|
626 |
+
// No check passed so just remove the file entirely
|
627 |
+
if (!$check) {
|
628 |
+
unset($this->requirements['files'][$path]);
|
629 |
+
return $this;
|
630 |
+
}
|
631 |
+
$newVals = $this->arrayRemoveValue($this->requirements['files'][$path], [$check]);
|
632 |
+
$this->requirements['files'][$path] = $newVals;
|
633 |
+
return $this;
|
634 |
+
}
|
635 |
+
/**
|
636 |
+
* Remove currently set OS requirements
|
637 |
+
*
|
638 |
+
* @return Checker
|
639 |
+
*/
|
640 |
+
public function removeOsRequirement()
|
641 |
+
{
|
642 |
+
$this->requirements['system']['os'] = null;
|
643 |
+
return $this;
|
644 |
+
}
|
645 |
+
/**
|
646 |
+
* Remove PHP version requirement
|
647 |
+
*
|
648 |
+
* @return Checker
|
649 |
+
*/
|
650 |
+
public function removePhpVersionRequirement()
|
651 |
+
{
|
652 |
+
$this->requirements['system']['php_version'] = null;
|
653 |
+
return $this;
|
654 |
+
}
|
655 |
+
/**
|
656 |
+
* Remove specific value from one-dimensional array
|
657 |
+
*
|
658 |
+
* @param array $array The array to remove values from
|
659 |
+
* @param array $removals List of values to remove
|
660 |
+
*
|
661 |
+
* @return array
|
662 |
+
*/
|
663 |
+
public function arrayRemoveValue(array $array, array $removals)
|
664 |
+
{
|
665 |
+
return \array_diff($array, $removals);
|
666 |
+
}
|
667 |
+
/**
|
668 |
+
* Transform any file path to unix style path
|
669 |
+
*
|
670 |
+
* @param string $string
|
671 |
+
* @return string
|
672 |
+
*/
|
673 |
+
public function unixPath($string)
|
674 |
+
{
|
675 |
+
return \str_replace('\\', '/', $string);
|
676 |
+
}
|
677 |
+
/**
|
678 |
+
* Checks if a string is PHP style namespaced using backslash or not
|
679 |
+
*
|
680 |
+
* @param string $string
|
681 |
+
* @return boolean
|
682 |
+
*/
|
683 |
+
public function ensureNamespace($string)
|
684 |
+
{
|
685 |
+
// Already namespaced
|
686 |
+
if (\strpos($string, '\\') !== \false) {
|
687 |
+
return $string;
|
688 |
+
}
|
689 |
+
// Append a global namespace
|
690 |
+
return '\\' . $string;
|
691 |
+
}
|
692 |
+
/**
|
693 |
+
* Parse a string that has comparison operator prepended to it
|
694 |
+
*
|
695 |
+
* @param string $string
|
696 |
+
* @param string $default
|
697 |
+
* @return array As operator => the comparison operator if exists
|
698 |
+
* plain => the string without the operator
|
699 |
+
**/
|
700 |
+
public function parseComparisonString($string, $default)
|
701 |
+
{
|
702 |
+
$comparison = \substr($string, 0, 1);
|
703 |
+
$comparison2 = \substr($string, 0, 2);
|
704 |
+
$operator = $default;
|
705 |
+
$withoutVersion = $string;
|
706 |
+
if ($comparison2 == '>=' || $comparison2 == '<=') {
|
707 |
+
$operator = $comparison2;
|
708 |
+
$withoutVersion = \substr($string, 2);
|
709 |
+
} elseif ($comparison == '>' || $comparison == '<' || $comparison == '=') {
|
710 |
+
$operator = $comparison;
|
711 |
+
$withoutVersion = \substr($string, 1);
|
712 |
+
}
|
713 |
+
return ['operator' => $operator, 'plain' => $withoutVersion];
|
714 |
+
}
|
715 |
+
/**
|
716 |
+
* Loosely compare two variables with the comparison operator provided
|
717 |
+
*
|
718 |
+
* @param mixed $var1
|
719 |
+
* @param string $op
|
720 |
+
* @param mixed $var2
|
721 |
+
* @return boolean
|
722 |
+
*/
|
723 |
+
public function looseComparison($var1, $op, $var2)
|
724 |
+
{
|
725 |
+
switch ($op) {
|
726 |
+
case "=":
|
727 |
+
return $var1 == $var2;
|
728 |
+
case "!=":
|
729 |
+
return $var1 != $var2;
|
730 |
+
case ">=":
|
731 |
+
return $var1 >= $var2;
|
732 |
+
case "<=":
|
733 |
+
return $var1 <= $var2;
|
734 |
+
case ">":
|
735 |
+
return $var1 > $var2;
|
736 |
+
case "<":
|
737 |
+
return $var1 < $var2;
|
738 |
+
default:
|
739 |
+
return \true;
|
740 |
+
}
|
741 |
+
}
|
742 |
+
/**
|
743 |
+
* Returns bytes from php.ini string values
|
744 |
+
*
|
745 |
+
* @param string $val
|
746 |
+
* @return integer
|
747 |
+
*/
|
748 |
+
public function returnBytes($val)
|
749 |
+
{
|
750 |
+
$val = \strtolower(\trim($val));
|
751 |
+
if (\substr($val, -1) == 'b') {
|
752 |
+
$val = \substr($val, 0, -1);
|
753 |
+
}
|
754 |
+
$last = \substr($val, -1);
|
755 |
+
$val = \intval($val);
|
756 |
+
switch ($last) {
|
757 |
+
case 'g':
|
758 |
+
case 'gb':
|
759 |
+
$val *= 1024;
|
760 |
+
// no break
|
761 |
+
case 'm':
|
762 |
+
case 'mb':
|
763 |
+
$val *= 1024;
|
764 |
+
// no break
|
765 |
+
case 'k':
|
766 |
+
case 'kb':
|
767 |
+
$val *= 1024;
|
768 |
+
}
|
769 |
+
return $val;
|
770 |
+
}
|
771 |
+
/**
|
772 |
+
* Returns base structure for the values
|
773 |
+
*
|
774 |
+
* @return array
|
775 |
+
*/
|
776 |
+
protected function getParsedStructure()
|
777 |
+
{
|
778 |
+
return ['satisfied' => \false, 'preferred' => null, 'current' => null, 'message' => null];
|
779 |
+
}
|
780 |
+
}
|
third-party/vendor/mirazmac/php-requirements-checker/usage/usage.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WSAL_Vendor;
|
4 |
+
|
5 |
+
require '../vendor/autoload.php';
|
6 |
+
use WSAL_Vendor\MirazMac\Requirements\Checker;
|
7 |
+
$checker = new Checker();
|
8 |
+
// Define requirements
|
9 |
+
// Make sure the PHP version is equal to or greater than 5.6
|
10 |
+
// Pass preferred php.ini values as an array
|
11 |
+
// Note the usage of boolean instead of On/1/Off/0
|
12 |
+
// Ensures allow_url_fopen is On
|
13 |
+
$checker->requirePhpVersion('>=5.6')->requirePhpExtensions(['pdo', 'mbstring'])->requireFunctions(['random_bytes'])->requireFile('../composer.json', Checker::CHECK_FILE_EXISTS)->requireDirectory('../src', Checker::CHECK_IS_READABLE)->requireIniValues(['allow_url_fopen' => \true, 'short_open_tag' => \true, 'memory_limit' => '>=64M']);
|
14 |
+
// Runs the check and returns parsed requirements as an array
|
15 |
+
// Contains parsed requirements with state of the current values and their comparison result
|
16 |
+
$output = $checker->check();
|
17 |
+
// Should be called after running check() to see if requirements has met or not
|
18 |
+
$satisfied = $checker->isSatisfied();
|
19 |
+
if ($satisfied) {
|
20 |
+
echo "Requirements are met.";
|
21 |
+
} else {
|
22 |
+
echo \join(', ', $checker->getErrors());
|
23 |
+
}
|
third-party/vendor/scoper-autoload.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// scoper-autoload.php @generated by PhpScoper
|
4 |
+
|
5 |
+
$loader = require_once __DIR__.'/autoload.php';
|
6 |
+
|
7 |
+
return $loader;
|
wp-security-audit-log.php
CHANGED
@@ -1,38 +1,42 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
* Plugin Name: WP Activity Log
|
4 |
-
*
|
5 |
-
*
|
6 |
-
*
|
7 |
-
*
|
|
|
8 |
* Text Domain: wp-security-audit-log
|
9 |
-
*
|
10 |
-
* License:
|
|
|
|
|
11 |
* Network: true
|
12 |
*
|
13 |
* @package wsal
|
14 |
*
|
15 |
-
* @fs_premium_only /extensions/, /
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
*/
|
17 |
|
18 |
-
/*
|
19 |
-
WP Activity Log
|
20 |
-
Copyright(c) 2021 WP White Security (email : info@wpwhitesecurity.com)
|
21 |
-
|
22 |
-
This program is free software; you can redistribute it and/or modify
|
23 |
-
it under the terms of the GNU General Public License, version 2, as
|
24 |
-
published by the Free Software Foundation.
|
25 |
-
|
26 |
-
This program is distributed in the hope that it will be useful,
|
27 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
28 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
29 |
-
GNU General Public License for more details.
|
30 |
-
|
31 |
-
You should have received a copy of the GNU General Public License
|
32 |
-
along with this program; if not, write to the Free Software
|
33 |
-
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
34 |
-
*/
|
35 |
-
|
36 |
if ( ! function_exists( 'wsal_freemius' ) ) {
|
37 |
|
38 |
if ( ! class_exists( 'WpSecurityAuditLog' ) ) {
|
@@ -49,9 +53,9 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
49 |
*
|
50 |
* @var string
|
51 |
*/
|
52 |
-
public $version = '4.
|
53 |
|
54 |
-
|
55 |
* Plugin constants.
|
56 |
*
|
57 |
* @var string
|
@@ -467,6 +471,7 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
467 |
require_once 'classes/ThirdPartyExtensions/WooCommerceExtension.php';
|
468 |
require_once 'classes/ThirdPartyExtensions/GravityFormsExtension.php';
|
469 |
require_once 'classes/ThirdPartyExtensions/TablePressExtension.php';
|
|
|
470 |
}
|
471 |
|
472 |
// Connectors.
|
@@ -540,7 +545,7 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
540 |
wp_schedule_event( time(), 'daily', 'wsal_delete_logins' );
|
541 |
}
|
542 |
|
543 |
-
|
544 |
|
545 |
add_action( 'admin_init', array( $this, 'maybe_sync_premium_freemius' ) );
|
546 |
|
@@ -557,9 +562,8 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
557 |
$bbpress_addon = new WSAL_BBPressExtension();
|
558 |
$wpforms_addon = new WSAL_WPFormsExtension();
|
559 |
$gravityforms_addon = new WSAL_GravityFormsExtension();
|
560 |
-
|
561 |
-
|
562 |
-
//$tablepress_addon = new WSAL_TablePressExtension();
|
563 |
}
|
564 |
|
565 |
// Extensions which are both admin and frontend based.
|
@@ -751,133 +755,6 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
751 |
return ! in_array( $alert, $alerts );
|
752 |
}
|
753 |
|
754 |
-
/**
|
755 |
-
* MainWP Dashboard Handler.
|
756 |
-
*
|
757 |
-
* @since 3.2.5
|
758 |
-
*
|
759 |
-
* @param array $info – Information to return.
|
760 |
-
* @param array $post_data – Post data array from MainWP.
|
761 |
-
* @return mixed
|
762 |
-
*/
|
763 |
-
public function mainwp_dashboard_callback( $info, $post_data ) {
|
764 |
-
if ( isset( $post_data['action'] ) ) {
|
765 |
-
switch ( $post_data['action'] ) {
|
766 |
-
case 'check_wsal':
|
767 |
-
$info = new stdClass();
|
768 |
-
$info->wsal_installed = true;
|
769 |
-
$info->is_premium = false;
|
770 |
-
break;
|
771 |
-
|
772 |
-
case 'get_events':
|
773 |
-
$limit = isset( $post_data['events_count'] ) ? $post_data['events_count'] : false;
|
774 |
-
$offset = isset( $post_data['events_offset'] ) ? $post_data['events_offset'] : false;
|
775 |
-
$query_args = isset( $post_data['query_args'] ) ? $post_data['query_args'] : false;
|
776 |
-
$info = $this->alerts->get_mainwp_extension_events( $limit, $offset, $query_args );
|
777 |
-
break;
|
778 |
-
|
779 |
-
case 'get_report':
|
780 |
-
$filters = isset( $post_data['filters'] ) ? $post_data['filters'] : array();
|
781 |
-
$report_type = isset( $post_data['report_type'] ) ? $post_data['report_type'] : false;
|
782 |
-
$info = $this->alerts->get_mainwp_extension_report( $filters, $report_type );
|
783 |
-
break;
|
784 |
-
|
785 |
-
case 'latest_event':
|
786 |
-
// run the query and return it.
|
787 |
-
$event = $this->query_for_latest_event();
|
788 |
-
$event = $event->getAdapter()->Execute( $event );
|
789 |
-
|
790 |
-
// Set the return object.
|
791 |
-
if ( isset( $event[0] ) ) {
|
792 |
-
$info = new stdClass();
|
793 |
-
$info->alert_id = $event[0]->alert_id;
|
794 |
-
$info->created_on = $event[0]->created_on;
|
795 |
-
} else {
|
796 |
-
$info = false;
|
797 |
-
}
|
798 |
-
break;
|
799 |
-
case 'enforce_settings':
|
800 |
-
// check subaction
|
801 |
-
if ( ! array_key_exists( 'subaction', $post_data) || empty( $post_data['subaction'] ) ) {
|
802 |
-
$info = array(
|
803 |
-
'success' => 'no',
|
804 |
-
'message' => 'Missing subaction parameter.'
|
805 |
-
);
|
806 |
-
break;
|
807 |
-
}
|
808 |
-
|
809 |
-
$subaction = filter_var( $post_data['subaction'], FILTER_SANITIZE_STRING);
|
810 |
-
if ( ! in_array( $subaction, [ 'update', 'remove' ] ) ) {
|
811 |
-
$info = array(
|
812 |
-
'success' => 'no',
|
813 |
-
'message' => 'Unsupported subaction parameter value.'
|
814 |
-
);
|
815 |
-
break;
|
816 |
-
}
|
817 |
-
|
818 |
-
if ( 'update' === $subaction ) {
|
819 |
-
// store the enforced settings in local database (used for example to disable related parts
|
820 |
-
// of the settings UI
|
821 |
-
$settings_to_enforce = $post_data[ 'settings'];
|
822 |
-
$this->settings()->set_mainwp_enforced_settings( $settings_to_enforce );
|
823 |
-
|
824 |
-
// change the existing settings
|
825 |
-
if ( array_key_exists( 'pruning_enabled', $settings_to_enforce ) ) {
|
826 |
-
$this->settings()->SetPruningDateEnabled( $settings_to_enforce['pruning_enabled'] );
|
827 |
-
if ( array_key_exists( 'pruning_date', $settings_to_enforce ) && array_key_exists( 'pruning_unit', $settings_to_enforce) ) {
|
828 |
-
$this->settings()->SetPruningDate($settings_to_enforce[ 'pruning_date' ] . ' ' . $settings_to_enforce[ 'pruning_unit' ]);
|
829 |
-
$this->settings()->set_pruning_unit( $settings_to_enforce[ 'pruning_unit' ] );
|
830 |
-
}
|
831 |
-
}
|
832 |
-
|
833 |
-
if ( array_key_exists( 'disabled_events', $settings_to_enforce ) ) {
|
834 |
-
$disabled_event_ids = array_key_exists( 'disabled_events', $settings_to_enforce ) ? array_map( 'intval', explode( ',', $settings_to_enforce['disabled_events'] ) ) : [];
|
835 |
-
$this->alerts->SetDisabledAlerts( $disabled_event_ids );
|
836 |
-
}
|
837 |
-
|
838 |
-
if (array_key_exists('incognito_mode_enabled', $settings_to_enforce)) {
|
839 |
-
$this->settings()->SetIncognito($settings_to_enforce['incognito_mode_enabled']);
|
840 |
-
}
|
841 |
-
|
842 |
-
if (array_key_exists('login_notification_enabled', $settings_to_enforce)) {
|
843 |
-
$login_page_notification_enabled = $settings_to_enforce['login_notification_enabled'];
|
844 |
-
$this->settings()->set_login_page_notification($login_page_notification_enabled);
|
845 |
-
if ('yes' === $login_page_notification_enabled) {
|
846 |
-
$this->settings()->set_login_page_notification_text($settings_to_enforce['login_notification_text']);
|
847 |
-
}
|
848 |
-
}
|
849 |
-
|
850 |
-
} else if ( 'remove' === $subaction ) {
|
851 |
-
$this->settings()->delete_mainwp_enforced_settings();
|
852 |
-
}
|
853 |
-
|
854 |
-
$info = array(
|
855 |
-
'success' => 'yes'
|
856 |
-
);
|
857 |
-
$this->alerts->Trigger( 6043 );
|
858 |
-
default:
|
859 |
-
break;
|
860 |
-
}
|
861 |
-
}
|
862 |
-
return $info;
|
863 |
-
}
|
864 |
-
|
865 |
-
/**
|
866 |
-
* Performs a query to retrieve the latest event in the logs.
|
867 |
-
*
|
868 |
-
* @method query_for_latest_event
|
869 |
-
* @since 4.0.3
|
870 |
-
* @return array
|
871 |
-
*/
|
872 |
-
public function query_for_latest_event() {
|
873 |
-
$event_query = new WSAL_Models_OccurrenceQuery();
|
874 |
-
// order by creation.
|
875 |
-
$event_query->addOrderBy( 'created_on', true );
|
876 |
-
// only request 1 item.
|
877 |
-
$event_query->setLimit( 1 );
|
878 |
-
return $event_query;
|
879 |
-
}
|
880 |
-
|
881 |
/**
|
882 |
* Method: WSAL plugin redirect.
|
883 |
*/
|
@@ -1073,27 +950,33 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
1073 |
);
|
1074 |
}
|
1075 |
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1097 |
|
1098 |
/**
|
1099 |
* Start to trigger the events after installation.
|
@@ -1148,6 +1031,9 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
1148 |
*/
|
1149 |
do_action( 'wsal_init', $this );
|
1150 |
|
|
|
|
|
|
|
1151 |
// allow registration of custom alert formatters (must be called after wsal_init action )
|
1152 |
WSAL_AlertFormatterFactory::bootstrap();
|
1153 |
}
|
@@ -1304,11 +1190,12 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
1304 |
$script_data = array(
|
1305 |
'ajaxURL' => admin_url( 'admin-ajax.php' ),
|
1306 |
'liveEvents' => $live_events_enabled,
|
1307 |
-
'installing' =>
|
1308 |
-
'already_installed' =>
|
1309 |
-
'installed' =>
|
1310 |
-
'activated' =>
|
1311 |
-
'failed' =>
|
|
|
1312 |
);
|
1313 |
|
1314 |
wp_localize_script( 'wsal-common', 'wsalCommonData', $script_data );
|
@@ -1331,7 +1218,6 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
1331 |
require_once 'classes/ConstantManager.php';
|
1332 |
require_once 'classes/Loggers/Database.php';
|
1333 |
require_once 'classes/SensorManager.php';
|
1334 |
-
require_once 'classes/Sensors/Public.php';
|
1335 |
require_once 'classes/Settings.php';
|
1336 |
|
1337 |
if ( is_admin() ) {
|
@@ -1436,7 +1322,7 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
1436 |
*/
|
1437 |
public function Update( $old_version, $new_version ) {
|
1438 |
// Update version in db.
|
1439 |
-
$this->SetGlobalSetting( 'version', $new_version );
|
1440 |
|
1441 |
if ( '0.0.0' === $old_version ) {
|
1442 |
// set some initial plugins settings (only the ones that bypass the regular settings retrieval at some
|
@@ -1536,6 +1422,34 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
1536 |
$this->DeleteGlobalSetting( 'excluded-custom' );
|
1537 |
}
|
1538 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1539 |
}
|
1540 |
}
|
1541 |
|
@@ -1646,25 +1560,25 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
1646 |
$this->SetGlobalSetting( $option, $value );
|
1647 |
}
|
1648 |
|
1649 |
-
|
1650 |
-
|
1651 |
-
|
1652 |
-
|
1653 |
-
|
1654 |
-
|
1655 |
-
|
1656 |
-
|
1657 |
-
|
1658 |
-
|
1659 |
-
|
1660 |
-
|
|
|
|
|
1661 |
|
1662 |
/**
|
1663 |
* Deletes a global setting.
|
1664 |
*
|
1665 |
-
*
|
1666 |
-
*
|
1667 |
-
* @param string $option - Option name.
|
1668 |
*
|
1669 |
* @return bool
|
1670 |
* @since 4.2.1
|
@@ -1687,17 +1601,20 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
1687 |
$result = $this->GetGlobalSetting( $option, \WSAL\Helpers\Options::string_to_bool( $default ) );
|
1688 |
return \WSAL\Helpers\Options::string_to_bool( $result );
|
1689 |
}
|
1690 |
-
|
1691 |
-
|
1692 |
-
|
1693 |
-
|
1694 |
-
|
1695 |
-
|
1696 |
-
|
1697 |
-
|
1698 |
-
|
1699 |
-
|
1700 |
-
|
|
|
|
|
|
|
1701 |
|
1702 |
/**
|
1703 |
* Run cleanup routines.
|
@@ -1951,7 +1868,7 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
1951 |
$old_value = get_option( $option_name );
|
1952 |
|
1953 |
// determine new value via Freemius SDK
|
1954 |
-
$new_value = wsal_freemius()->
|
1955 |
|
1956 |
// update the db option only if the value changed
|
1957 |
if ($new_value != $old_value) {
|
@@ -2197,6 +2114,17 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
|
|
2197 |
}
|
2198 |
}
|
2199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2200 |
// Begin load sequence.
|
2201 |
WpSecurityAuditLog::GetInstance();
|
2202 |
|
1 |
<?php
|
2 |
/**
|
3 |
+
* WP Activity Log.
|
4 |
+
*
|
5 |
+
* @copyright Copyright (C) 2013-@current_year, WP White Security - support@wpwhitesecurity.com
|
6 |
+
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 or higher
|
7 |
+
*
|
8 |
+
* @wordpress-plugin
|
9 |
* Plugin Name: WP Activity Log
|
10 |
+
* Version: 4.4.0
|
11 |
+
* Plugin URI: https://wpactivitylog.com/
|
12 |
+
* Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress, including users activity. Similar to Linux Syslog, WP Activity Log generates an activity log with a record of everything that happens on your WordPress websites.
|
13 |
+
* Author: WP White Security
|
14 |
+
* Author URI: https://www.wpwhitesecurity.com/
|
15 |
* Text Domain: wp-security-audit-log
|
16 |
+
* Domain Path: /languages/
|
17 |
+
* License: GPL v3
|
18 |
+
* Requires at least: 5.0
|
19 |
+
* Requires PHP: 7.0
|
20 |
* Network: true
|
21 |
*
|
22 |
* @package wsal
|
23 |
*
|
24 |
+
* @fs_premium_only /extensions/, /third-party/woocommerce/
|
25 |
+
*
|
26 |
+
* This program is free software: you can redistribute it and/or modify
|
27 |
+
* it under the terms of the GNU General Public License as published by
|
28 |
+
* the Free Software Foundation, either version 3 of the License, or
|
29 |
+
* (at your option) any later version.
|
30 |
+
*
|
31 |
+
* This program is distributed in the hope that it will be useful,
|
32 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
33 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
34 |
+
* GNU General Public License for more details.
|
35 |
+
*
|
36 |
+
* You should have received a copy of the GNU General Public License
|
37 |
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
38 |
*/
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
if ( ! function_exists( 'wsal_freemius' ) ) {
|
41 |
|
42 |
if ( ! class_exists( 'WpSecurityAuditLog' ) ) {
|
53 |
*
|
54 |
* @var string
|
55 |
*/
|
56 |
+
public $version = '4.4.0';
|
57 |
|
58 |
+
/**
|
59 |
* Plugin constants.
|
60 |
*
|
61 |
* @var string
|
471 |
require_once 'classes/ThirdPartyExtensions/WooCommerceExtension.php';
|
472 |
require_once 'classes/ThirdPartyExtensions/GravityFormsExtension.php';
|
473 |
require_once 'classes/ThirdPartyExtensions/TablePressExtension.php';
|
474 |
+
require_once 'classes/ThirdPartyExtensions/WFCMExtension.php';
|
475 |
}
|
476 |
|
477 |
// Connectors.
|
545 |
wp_schedule_event( time(), 'daily', 'wsal_delete_logins' );
|
546 |
}
|
547 |
|
548 |
+
add_filter( 'mainwp_child_extra_execution', array( new WSAL_MainWpApi( $this ), 'handle_callback' ), 10, 2 );
|
549 |
|
550 |
add_action( 'admin_init', array( $this, 'maybe_sync_premium_freemius' ) );
|
551 |
|
562 |
$bbpress_addon = new WSAL_BBPressExtension();
|
563 |
$wpforms_addon = new WSAL_WPFormsExtension();
|
564 |
$gravityforms_addon = new WSAL_GravityFormsExtension();
|
565 |
+
$tablepress_addon = new WSAL_TablePressExtension();
|
566 |
+
$wfcm_addon = new WSAL_WFCMExtension();
|
|
|
567 |
}
|
568 |
|
569 |
// Extensions which are both admin and frontend based.
|
755 |
return ! in_array( $alert, $alerts );
|
756 |
}
|
757 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
758 |
/**
|
759 |
* Method: WSAL plugin redirect.
|
760 |
*/
|
950 |
);
|
951 |
}
|
952 |
|
953 |
+
/**
|
954 |
+
* Limited License Activation Error.
|
955 |
+
*
|
956 |
+
* @param string $error - Error Message.
|
957 |
+
*
|
958 |
+
* @return string
|
959 |
+
*/
|
960 |
+
public function limited_license_activation_error( $error ) {
|
961 |
+
// We only process error if it's some sort of string message.
|
962 |
+
if ( ! is_string( $error ) ) {
|
963 |
+
return $error;
|
964 |
+
}
|
965 |
+
|
966 |
+
$site_count = null;
|
967 |
+
preg_match( '!\d+!', $error, $site_count );
|
968 |
+
|
969 |
+
// Check if this is an expired error.
|
970 |
+
if ( strpos( $error, 'expired' ) !== false ) {
|
971 |
+
/* Translators: Expired message and time */
|
972 |
+
$error = sprintf( esc_html__( '%s You need to renew your license to continue using premium features.', 'wp-security-audit-log' ), preg_replace( '/\([^)]+\)/', '', $error ) );
|
973 |
+
} elseif ( ! empty( $site_count[0] ) ) {
|
974 |
+
/* Translators: Number of sites */
|
975 |
+
$error = sprintf( esc_html__( 'The license is limited to %s sub-sites. You need to upgrade your license to cover all the sub-sites on this network.', 'wp-security-audit-log' ), $site_count[0] );
|
976 |
+
}
|
977 |
+
|
978 |
+
return $error;
|
979 |
+
}
|
980 |
|
981 |
/**
|
982 |
* Start to trigger the events after installation.
|
1031 |
*/
|
1032 |
do_action( 'wsal_init', $this );
|
1033 |
|
1034 |
+
// background job for metadata migration
|
1035 |
+
new WSAL_Upgrade_MetadataMigration();
|
1036 |
+
|
1037 |
// allow registration of custom alert formatters (must be called after wsal_init action )
|
1038 |
WSAL_AlertFormatterFactory::bootstrap();
|
1039 |
}
|
1190 |
$script_data = array(
|
1191 |
'ajaxURL' => admin_url( 'admin-ajax.php' ),
|
1192 |
'liveEvents' => $live_events_enabled,
|
1193 |
+
'installing' => esc_html__( 'Installing, please wait', 'wp-security-audit-log' ),
|
1194 |
+
'already_installed' => esc_html__( 'Already installed', 'wp-security-audit-log' ),
|
1195 |
+
'installed' => esc_html__( 'Extension installed', 'wp-security-audit-log' ),
|
1196 |
+
'activated' => esc_html__( 'Extension activated', 'wp-security-audit-log' ),
|
1197 |
+
'failed' => esc_html__( 'Install failed', 'wp-security-audit-log' ),
|
1198 |
+
'reloading_page' => esc_html__( 'Reloading page', 'wp-security-audit-log' )
|
1199 |
);
|
1200 |
|
1201 |
wp_localize_script( 'wsal-common', 'wsalCommonData', $script_data );
|
1218 |
require_once 'classes/ConstantManager.php';
|
1219 |
require_once 'classes/Loggers/Database.php';
|
1220 |
require_once 'classes/SensorManager.php';
|
|
|
1221 |
require_once 'classes/Settings.php';
|
1222 |
|
1223 |
if ( is_admin() ) {
|
1322 |
*/
|
1323 |
public function Update( $old_version, $new_version ) {
|
1324 |
// Update version in db.
|
1325 |
+
$this->SetGlobalSetting( 'version', $new_version, true );
|
1326 |
|
1327 |
if ( '0.0.0' === $old_version ) {
|
1328 |
// set some initial plugins settings (only the ones that bypass the regular settings retrieval at some
|
1422 |
$this->DeleteGlobalSetting( 'excluded-custom' );
|
1423 |
}
|
1424 |
}
|
1425 |
+
|
1426 |
+
if ( version_compare( $new_version, '4.4.0', '>=' ) ) {
|
1427 |
+
// Delete unwanted usermeta.
|
1428 |
+
global $wpdb;
|
1429 |
+
$all_user_meta = $wpdb->get_results(
|
1430 |
+
$wpdb->prepare(
|
1431 |
+
"DELETE FROM {$wpdb->usermeta} WHERE meta_key = '%s';",
|
1432 |
+
'wsal-notice-update-44-notice'
|
1433 |
+
)
|
1434 |
+
);
|
1435 |
+
|
1436 |
+
$this->settings()->set_database_version( 44400 );
|
1437 |
+
|
1438 |
+
if ( class_exists( 'WSAL_Extension_Manager' ) ) {
|
1439 |
+
WSAL_Extension_Manager::include_extension( 'external-db' );
|
1440 |
+
}
|
1441 |
+
|
1442 |
+
if ( ! did_action( 'wsal_init' ) ) {
|
1443 |
+
// we need to call wsal init manually because it does not run as before the upgrade procedure is triggered
|
1444 |
+
do_action( 'wsal_init', $this );
|
1445 |
+
}
|
1446 |
+
|
1447 |
+
require_once 'classes/Upgrade/Upgrade_43000_to_44400.php';
|
1448 |
+
$upgrader = new WSAL_Upgrade_43000_to_44400( $this );
|
1449 |
+
$upgrader->run();
|
1450 |
+
|
1451 |
+
// @todo remove legacy periodic reports for unique_ip and number_logins
|
1452 |
+
}
|
1453 |
}
|
1454 |
}
|
1455 |
|
1560 |
$this->SetGlobalSetting( $option, $value );
|
1561 |
}
|
1562 |
|
1563 |
+
/**
|
1564 |
+
* Set a global setting.
|
1565 |
+
*
|
1566 |
+
* @param string $option - Option name.
|
1567 |
+
* @param mixed $value - New value for option.
|
1568 |
+
* @param bool $autoload Whether or not to autoload this option.
|
1569 |
+
*
|
1570 |
+
* @return bool
|
1571 |
+
*/
|
1572 |
+
public function SetGlobalSetting( $option, $value, $autoload = false ) {
|
1573 |
+
$this->include_options_helper();
|
1574 |
+
|
1575 |
+
return $this->options_helper->set_option_value( $option, $value, $autoload );
|
1576 |
+
}
|
1577 |
|
1578 |
/**
|
1579 |
* Deletes a global setting.
|
1580 |
*
|
1581 |
+
* @param string $option - Option name without the prefix.
|
|
|
|
|
1582 |
*
|
1583 |
* @return bool
|
1584 |
* @since 4.2.1
|
1601 |
$result = $this->GetGlobalSetting( $option, \WSAL\Helpers\Options::string_to_bool( $default ) );
|
1602 |
return \WSAL\Helpers\Options::string_to_bool( $result );
|
1603 |
}
|
1604 |
+
|
1605 |
+
/**
|
1606 |
+
* Sets a global boolean setting. It takes care of the conversion between string and boolean.
|
1607 |
+
*
|
1608 |
+
* @param string $option - Option name.
|
1609 |
+
* @param mixed $value - New value for option.
|
1610 |
+
* @param bool $autoload Whether or not to autoload this option.
|
1611 |
+
*
|
1612 |
+
* @since 4.1.3
|
1613 |
+
*/
|
1614 |
+
public function SetGlobalBooleanSetting( $option, $value, $autoload = false ) {
|
1615 |
+
$boolean_value = \WSAL\Helpers\Options::string_to_bool( $value );
|
1616 |
+
$this->SetGlobalSetting( $option, \WSAL\Helpers\Options::bool_to_string( $boolean_value ), $autoload );
|
1617 |
+
}
|
1618 |
|
1619 |
/**
|
1620 |
* Run cleanup routines.
|
1868 |
$old_value = get_option( $option_name );
|
1869 |
|
1870 |
// determine new value via Freemius SDK
|
1871 |
+
$new_value = wsal_freemius()->has_active_valid_license() ? 'yes' : 'no';
|
1872 |
|
1873 |
// update the db option only if the value changed
|
1874 |
if ($new_value != $old_value) {
|
2114 |
}
|
2115 |
}
|
2116 |
|
2117 |
+
$prefixed_autoloader_file_path = plugin_dir_path( __FILE__ ) . implode( DIRECTORY_SEPARATOR, [
|
2118 |
+
'third-party',
|
2119 |
+
'vendor',
|
2120 |
+
'autoload.php'
|
2121 |
+
]
|
2122 |
+
);
|
2123 |
+
|
2124 |
+
if ( file_exists( $prefixed_autoloader_file_path ) ) {
|
2125 |
+
require_once $prefixed_autoloader_file_path;
|
2126 |
+
}
|
2127 |
+
|
2128 |
// Begin load sequence.
|
2129 |
WpSecurityAuditLog::GetInstance();
|
2130 |
|